From 596f7bb9f197c370cde6099651a6613f04a3db93 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Thu, 1 Jun 2023 19:51:52 +0100 Subject: [PATCH] feat: added optional logging configuration --- vea-sdk/.env.dist | 13 ++++----- vea-sdk/examples/index.ts | 24 ++++++++++++---- vea-sdk/src/client.ts | 14 ++++++---- vea-sdk/src/message.ts | 4 +-- vea-sdk/src/sdk.ts | 30 ++++++++++++++++---- vea-sdk/src/utils/env.ts | 24 ++++++++++++++++ vea-sdk/src/utils/envVar.ts | 13 --------- vea-sdk/src/utils/logger.ts | 56 +++++++++++++++++++++---------------- 8 files changed, 115 insertions(+), 63 deletions(-) create mode 100644 vea-sdk/src/utils/env.ts delete mode 100644 vea-sdk/src/utils/envVar.ts diff --git a/vea-sdk/.env.dist b/vea-sdk/.env.dist index b009fa7d..8a775f29 100644 --- a/vea-sdk/.env.dist +++ b/vea-sdk/.env.dist @@ -1,13 +1,10 @@ -PRIVATE_KEY= +PRIVATE_KEY=0x.... RPC_CHIADO=https://rpc.chiadochain.net RPC_ARB_GOERLI=https://goerli-rollup.arbitrum.io/rpc RPC_GOERLI= -VEAINBOX_ARBGOERLI_TO_GOERLI_ADDRESS=0x906dE43dBef27639b1688Ac46532a16dc07Ce410 -VEAINBOX_ARBGOERLI_TO_CHIADO_ADDRESS=0xAb53e341121448Ae259Da8fa17f216Cb0e21199C -VEAOUTBOX_ARBGOERLI_TO_GOERLI_ADDRESS=0x906dE43dBef27639b1688Ac46532a16dc07Ce410 -VEAOUTBOX_ARBGOERLI_TO_CHIADO_ADDRESS=0xAb53e341121448Ae259Da8fa17f216Cb0e21199C - -TRANSACTION_BATCHER_CONTRACT_ADDRESS_GOERLI=0xe7953da7751063d0a41ba727c32c762d3523ade8 -TRANSACTION_BATCHER_CONTRACT_ADDRESS_CHIADO=0xcC0a08D4BCC5f91ee9a1587608f7a2975EA75d73 \ No newline at end of file +# Optional +HEARTBEAT_URL=https://MY_STATUS.com +LOGTAIL_TOKEN= +LOG_LEVEL= \ No newline at end of file diff --git a/vea-sdk/examples/index.ts b/vea-sdk/examples/index.ts index 1850cf57..581df141 100644 --- a/vea-sdk/examples/index.ts +++ b/vea-sdk/examples/index.ts @@ -1,25 +1,39 @@ import { Wallet } from "@ethersproject/wallet"; import VeaSdk from "../src/index"; -import envVar from "../src/utils/envVar"; +import env from "../src/utils/env"; async function main() { + // Optional logger configuration + const loggerOptions = { + transportTargetOptions: { + target: "@logtail/pino", + options: { sourceToken: env.require("LOGTAIL_TOKEN") }, + level: env.optional("LOG_LEVEL", "info"), + }, + }; + // Create the Vea client - const vea = VeaSdk.ClientFactory.arbitrumGoerliToChiadoDevnet(envVar("RPC_ARB_GOERLI"), envVar("RPC_CHIADO")); + const vea = VeaSdk.ClientFactory.arbitrumGoerliToChiadoDevnet( + env.require("RPC_ARB_GOERLI"), + env.require("RPC_CHIADO"), + loggerOptions + ); // Get the current state root - console.log(`stateRoot=${await vea.outbox.stateRoot()}`); + const logger = vea.logger; + logger.info(`stateRoot=${await vea.outbox.stateRoot()}`); // Get a message info const messageId = 1; const messageInfo = await vea.getMessageInfo(messageId); // Relay the message - const privateKey = envVar("PRIVATE_KEY"); + const privateKey = env.require("PRIVATE_KEY"); const wallet = new Wallet(privateKey, vea.outboxProvider); await vea.relay(messageInfo, wallet); } main().catch((e) => { - console.error(e); + VeaSdk.ClientFactory.logger.error(e); process.exit(1); }); diff --git a/vea-sdk/src/client.ts b/vea-sdk/src/client.ts index 2242c1ef..cf99cb69 100644 --- a/vea-sdk/src/client.ts +++ b/vea-sdk/src/client.ts @@ -1,6 +1,7 @@ import { JsonRpcProvider } from "@ethersproject/providers"; import { ContractTransaction } from "@ethersproject/contracts"; import { Signer } from "@ethersproject/abstract-signer"; +import { Logger } from "pino"; import { VeaInboxArbToEth, VeaOutboxArbToGnosisDevnet, @@ -20,23 +21,26 @@ export type VeaOutbox = VeaOutboxArbToEthDevnet | VeaOutboxArbToGnosisDevnet; export class VeaClient { readonly config: VeaClientConfig; - inboxProvider: JsonRpcProvider; - outboxProvider: JsonRpcProvider; - inbox: VeaInbox; - outbox: VeaOutbox; + readonly inboxProvider: JsonRpcProvider; + readonly outboxProvider: JsonRpcProvider; + readonly inbox: VeaInbox; + readonly outbox: VeaOutbox; + readonly logger: Logger; constructor( config: VeaClientConfig, inboxProvider: JsonRpcProvider, outboxProvider: JsonRpcProvider, inbox: VeaInboxArbToEth, - outbox: VeaOutboxArbToEthDevnet | VeaOutboxArbToGnosisDevnet + outbox: VeaOutboxArbToEthDevnet | VeaOutboxArbToGnosisDevnet, + logger: Logger ) { this.config = config; this.inboxProvider = inboxProvider; this.outboxProvider = outboxProvider; this.inbox = inbox; this.outbox = outbox; + this.logger = logger; } public getMessageInfo = async (messageId: number): Promise => { diff --git a/vea-sdk/src/message.ts b/vea-sdk/src/message.ts index a9f2a98e..9c184457 100644 --- a/vea-sdk/src/message.ts +++ b/vea-sdk/src/message.ts @@ -64,7 +64,7 @@ const getProofAtCount = async (client: VeaClient, messageId: number, count: numb proof.push(result[`layer${i}`][0].hash); } } catch (e) { - console.log(e); + client.logger.error(e, "Error getting proof from subgraph"); } return proof; }; @@ -103,7 +103,7 @@ const getMessageDataToRelay = async (client: VeaClient, messageId: number): Prom const result: any = await request(subgraph, query); dataAndTo = [result[`messageSents`][0].to.id, result[`messageSents`][0].data]; } catch (e) { - console.log(e); + client.logger.error(e, "Error getting message data from subgraph"); } return dataAndTo; }; diff --git a/vea-sdk/src/sdk.ts b/vea-sdk/src/sdk.ts index c5593b10..24b4f9d7 100644 --- a/vea-sdk/src/sdk.ts +++ b/vea-sdk/src/sdk.ts @@ -1,9 +1,19 @@ import { JsonRpcProvider } from "@ethersproject/providers"; +import loggerFactory from "./utils/logger"; import * as Bridges from "./bridges"; import { VeaClient, VeaClientConfig } from "./client"; export class ClientFactory { - private static configure(bridge: Bridges.Bridge, inboxRpc: string, outboxRpc: string): VeaClient { + static logger = loggerFactory.createLogger(); + + private static configure( + bridge: Bridges.Bridge, + inboxRpc: string, + outboxRpc: string, + loggerOptions?: loggerFactory.LoggerOptions + ): VeaClient { + this.logger = loggerFactory.createLogger(loggerOptions); + const config: VeaClientConfig = { bridge, inboxRpc: inboxRpc, @@ -22,14 +32,22 @@ export class ClientFactory { outboxProvider.getNetwork().then((network) => { if (network.chainId !== bridge.outboxChainId) throw new Error("Incorrect Outbox RPC"); }); - return new VeaClient(config, inboxProvider, outboxProvider, veaInbox, veaOutbox); + return new VeaClient(config, inboxProvider, outboxProvider, veaInbox, veaOutbox, this.logger); } - static arbitrumGoerliToChiadoDevnet(inboxRpc: string, outboxRpc: string): VeaClient { - return this.configure(Bridges.arbitrumGoerliToChiadoDevnet, inboxRpc, outboxRpc); + static arbitrumGoerliToChiadoDevnet( + inboxRpc: string, + outboxRpc: string, + loggerOptions?: loggerFactory.LoggerOptions + ): VeaClient { + return this.configure(Bridges.arbitrumGoerliToChiadoDevnet, inboxRpc, outboxRpc, loggerOptions); } - static arbitrumGoerliToGoerliDevnet(inboxRpc: string, outboxRpc: string): VeaClient { - return this.configure(Bridges.arbitrumGoerliToGoerliDevnet, inboxRpc, outboxRpc); + static arbitrumGoerliToGoerliDevnet( + inboxRpc: string, + outboxRpc: string, + loggerOptions?: loggerFactory.LoggerOptions + ): VeaClient { + return this.configure(Bridges.arbitrumGoerliToGoerliDevnet, inboxRpc, outboxRpc, loggerOptions); } } diff --git a/vea-sdk/src/utils/env.ts b/vea-sdk/src/utils/env.ts new file mode 100644 index 00000000..ef815ef8 --- /dev/null +++ b/vea-sdk/src/utils/env.ts @@ -0,0 +1,24 @@ +import dotenv from "dotenv"; + +dotenv.config(); + +namespace env { + export const require = (key: string): string => { + const value = process.env[key]; + if (value === undefined) { + throw new Error(`Environment variable ${key} is undefined`); + } + return value; + }; + + export const optional = (key: string, defaultValue: string): string => { + const value = process.env[key]; + return value === undefined ? defaultValue : value; + }; + + export const optionalNoDefault = (key: string): string | undefined => { + return process.env[key]; + }; +} + +export default env; diff --git a/vea-sdk/src/utils/envVar.ts b/vea-sdk/src/utils/envVar.ts deleted file mode 100644 index ff66b5da..00000000 --- a/vea-sdk/src/utils/envVar.ts +++ /dev/null @@ -1,13 +0,0 @@ -import dotenv from "dotenv"; - -dotenv.config(); - -function envVar(key: string): string { - const value = process.env[key]; - if (value === undefined) { - throw new Error(`Environment variable ${key} is undefined`); - } - return value; -} - -export default envVar; diff --git a/vea-sdk/src/utils/logger.ts b/vea-sdk/src/utils/logger.ts index a3e9a648..d00dc523 100644 --- a/vea-sdk/src/utils/logger.ts +++ b/vea-sdk/src/utils/logger.ts @@ -1,28 +1,36 @@ import pino from "pino"; -import envVar from "./envVar"; +import { TransportTargetOptions } from "pino"; +import dotenv from "dotenv"; -// TODO: make this env var optional, skip fetch if undefined -const logtailToken = envVar("LOGTAIL_TOKEN"); -const transport = pino.transport({ - targets: [ - { - target: "@logtail/pino", - options: { sourceToken: logtailToken }, - level: "debug", - }, - { - target: "pino-pretty", - options: {}, - level: "debug", - }, - ], -}); -const logger = pino( - { - level: envVar("LOG_LEVEL"), // TODO: set it to info if not defined - timestamp: pino.stdTimeFunctions.isoTime, - }, - transport -); +dotenv.config(); + +namespace logger { + export type LoggerOptions = { + level?: string; + transportTargetOptions?: TransportTargetOptions; + }; + + export const createLogger = (options?: LoggerOptions): pino.Logger => { + const targets: TransportTargetOptions[] = [ + { + target: "pino-pretty", + options: {}, + level: options?.level ?? "info", + }, + ]; + + if (options?.transportTargetOptions) { + targets.push(options.transportTargetOptions); + } + + return pino( + { + level: options?.level ?? "info", + timestamp: pino.stdTimeFunctions.isoTime, + }, + pino.transport({ targets: targets }) + ); + }; +} export default logger;