Improve logger

This commit is contained in:
julian merlo 2024-02-14 11:14:25 -03:00
parent aae76c3617
commit ff39767e76
7 changed files with 42 additions and 35 deletions

View File

@ -9,13 +9,13 @@ import { ethers } from "ethers";
export class HandleEvmLogs<T> { export class HandleEvmLogs<T> {
cfg: HandleEvmConfig; cfg: HandleEvmConfig;
mapper: (log: EvmLog, parsedArgs: ReadonlyArray<any>) => T; mapper: (log: EvmLog, parsedArgs: ReadonlyArray<any>) => T;
target: (parsed: T[]) => Promise<void>; target: (parsed: T[], chain: string) => Promise<void>;
statsRepo: StatRepository; statsRepo: StatRepository;
constructor( constructor(
cfg: HandleEvmConfig, cfg: HandleEvmConfig,
mapper: (log: EvmLog, args: ReadonlyArray<any>) => T, mapper: (log: EvmLog, args: ReadonlyArray<any>) => T,
target: (parsed: T[]) => Promise<void>, target: (parsed: T[], chain: string) => Promise<void>,
statsRepo: StatRepository statsRepo: StatRepository
) { ) {
this.cfg = this.normalizeCfg(cfg); this.cfg = this.normalizeCfg(cfg);
@ -39,7 +39,7 @@ export class HandleEvmLogs<T> {
return logMap; return logMap;
}); });
await this.target(mappedItems); await this.target(mappedItems, this.cfg.chain);
// TODO: return a result specifying failures if any // TODO: return a result specifying failures if any
return mappedItems; return mappedItems;
} }

View File

@ -9,13 +9,13 @@ import { StatRepository } from "../../repositories";
export class HandleEvmTransactions<T> { export class HandleEvmTransactions<T> {
cfg: HandleEvmConfig; cfg: HandleEvmConfig;
mapper: (log: EvmTransaction) => T; mapper: (log: EvmTransaction) => T;
target: (parsed: T[]) => Promise<void>; target: (parsed: T[], chain: string) => Promise<void>;
statsRepo: StatRepository; statsRepo: StatRepository;
constructor( constructor(
cfg: HandleEvmConfig, cfg: HandleEvmConfig,
mapper: (log: EvmTransaction) => T, mapper: (log: EvmTransaction) => T,
target: (parsed: T[]) => Promise<void>, target: (parsed: T[], chain: string) => Promise<void>,
statsRepo: StatRepository statsRepo: StatRepository
) { ) {
this.cfg = this.normalizeCfg(cfg); this.cfg = this.normalizeCfg(cfg);
@ -36,7 +36,7 @@ export class HandleEvmTransactions<T> {
} }
}) as T[]; }) as T[];
await this.target(filterItems); await this.target(filterItems, this.cfg.chain);
return filterItems; return filterItems;
} }

View File

@ -8,14 +8,14 @@ import winston from "winston";
export class HandleSolanaTransactions<T> { export class HandleSolanaTransactions<T> {
cfg: HandleSolanaTxConfig; cfg: HandleSolanaTxConfig;
mapper: (txs: solana.Transaction, args: { programId: string }) => Promise<T[]>; mapper: (txs: solana.Transaction, args: { programId: string }) => Promise<T[]>;
target?: (parsed: T[]) => Promise<void>; target?: (parsed: T[], chain: string) => Promise<void>;
logger: winston.Logger = winston.child({ module: "HandleSolanaTransaction" }); logger: winston.Logger = winston.child({ module: "HandleSolanaTransaction" });
statsRepo?: StatRepository; statsRepo?: StatRepository;
constructor( constructor(
cfg: HandleSolanaTxConfig, cfg: HandleSolanaTxConfig,
mapper: (tx: solana.Transaction) => Promise<T[]>, mapper: (tx: solana.Transaction) => Promise<T[]>,
target?: (parsed: T[]) => Promise<void>, target?: (parsed: T[], chain: string) => Promise<void>,
statsRepo?: StatRepository statsRepo?: StatRepository
) { ) {
this.cfg = cfg; this.cfg = cfg;
@ -46,7 +46,7 @@ export class HandleSolanaTransactions<T> {
} }
if (this.target) { if (this.target) {
await this.target(mappedItems); await this.target(mappedItems, this.cfg.chain);
} else { } else {
this.logger.warn(`No target for ${this.cfg.programId} txs`); this.logger.warn(`No target for ${this.cfg.programId} txs`);
} }

View File

@ -2,11 +2,14 @@ import { TransactionFoundEvent } from "../../entities";
import { SuiTransactionBlockReceipt } from "../../entities/sui"; import { SuiTransactionBlockReceipt } from "../../entities/sui";
import { StatRepository } from "../../repositories"; import { StatRepository } from "../../repositories";
const COMMITMENT = "immediate";
const SUI_CHAIN = "sui";
export class HandleSuiTransactions { export class HandleSuiTransactions {
constructor( constructor(
private readonly cfg: HandleSuiTransactionsOptions, private readonly cfg: HandleSuiTransactionsOptions,
private readonly mapper: (tx: SuiTransactionBlockReceipt) => TransactionFoundEvent, private readonly mapper: (tx: SuiTransactionBlockReceipt) => TransactionFoundEvent,
private readonly target: (parsed: TransactionFoundEvent[]) => Promise<void>, private readonly target: (parsed: TransactionFoundEvent[], chain: string) => Promise<void>,
private readonly statsRepo: StatRepository private readonly statsRepo: StatRepository
) {} ) {}
@ -21,7 +24,7 @@ export class HandleSuiTransactions {
} }
} }
await this.target(items); await this.target(items, SUI_CHAIN);
return items; return items;
} }
@ -37,8 +40,8 @@ export class HandleSuiTransactions {
const labels = { const labels = {
job: this.cfg.id, job: this.cfg.id,
chain: "sui", chain: SUI_CHAIN,
commitment: "immediate", commitment: COMMITMENT,
}; };
this.statsRepo.count(this.cfg.metricName, labels); this.statsRepo.count(this.cfg.metricName, labels);
} }

View File

@ -22,9 +22,9 @@ export class SnsEventRepository {
this.logger.info(`Created for topic ${cfg.topicArn}`); this.logger.info(`Created for topic ${cfg.topicArn}`);
} }
async publish(events: LogFoundEvent<any>[]): Promise<SnsPublishResult> { async publish(events: LogFoundEvent<any>[], chain: string): Promise<SnsPublishResult> {
if (!events.length) { if (!events.length) {
this.logger.debug("[publish] No events to publish, continuing..."); this.logger.debug(`[publish][${chain}] No events to publish, continuing...`);
return { return {
status: "success", status: "success",
}; };
@ -63,7 +63,7 @@ export class SnsEventRepository {
for (const result of results) { for (const result of results) {
if (result.status !== "fulfilled") { if (result.status !== "fulfilled") {
this.logger.error(`[publish] ${result.reason}`); this.logger.error(`[publish][${chain}] ${result.reason}`);
errors.push(result.reason); errors.push(result.reason);
} }
} }
@ -82,18 +82,18 @@ export class SnsEventRepository {
}; };
} }
this.logger.info(`[publish] Published ${events.length} events to SNS`); this.logger.info(`[publish][${chain}] Published ${events.length} events to SNS`);
return { return {
status: "success", status: "success",
}; };
} }
async asTarget(): Promise<(events: LogFoundEvent<any>[]) => Promise<void>> { async asTarget(): Promise<(events: LogFoundEvent<any>[], chain: string) => Promise<void>> {
return async (events: LogFoundEvent<any>[]) => { return async (events: LogFoundEvent<any>[], chain: string) => {
const result = await this.publish(events); const result = await this.publish(events, chain);
if (result.status === "error") { if (result.status === "error") {
this.logger.error( this.logger.error(
`[asTarget] Error publishing events to SNS: ${result.reason ?? result.reasons}` `[asTarget][${chain}] Error publishing events to SNS: ${result.reason ?? result.reasons}`
); );
throw new Error(`Error publishing events to SNS: ${result.reason}`); throw new Error(`Error publishing events to SNS: ${result.reason}`);
} }

View File

@ -41,7 +41,8 @@ export class StaticJobRepository implements JobRepository {
private handlers: Map<string, (cfg: any, target: string, mapper: any) => Promise<Handler>> = private handlers: Map<string, (cfg: any, target: string, mapper: any) => Promise<Handler>> =
new Map(); new Map();
private mappers: Map<string, any> = new Map(); private mappers: Map<string, any> = new Map();
private targets: Map<string, () => Promise<(items: any[]) => Promise<void>>> = new Map(); private targets: Map<string, () => Promise<(items: any[], chain: string) => Promise<void>>> =
new Map();
private blockRepoProvider: (chain: string) => EvmBlockRepository; private blockRepoProvider: (chain: string) => EvmBlockRepository;
private metadataRepo: MetadataRepository<any>; private metadataRepo: MetadataRepository<any>;
private statsRepo: StatRepository; private statsRepo: StatRepository;
@ -209,7 +210,7 @@ export class StaticJobRepository implements JobRepository {
this.handlers.set("HandleSuiTransactions", handleSuiTx); this.handlers.set("HandleSuiTransactions", handleSuiTx);
} }
private async getTarget(target: string): Promise<(items: any[]) => Promise<void>> { private async getTarget(target: string): Promise<(items: any[], chain: string) => Promise<void>> {
const maybeTarget = this.targets.get(this.dryRun ? "dummy" : target); const maybeTarget = this.targets.get(this.dryRun ? "dummy" : target);
if (!maybeTarget) { if (!maybeTarget) {
throw new Error(`Target ${target} not found`); throw new Error(`Target ${target} not found`);

View File

@ -10,7 +10,7 @@ describe("SnsEventRepository", () => {
it("should not call sns client when no events given", async () => { it("should not call sns client when no events given", async () => {
givenSnsEventRepository(); givenSnsEventRepository();
const result = await snsEventRepository.publish([]); const result = await snsEventRepository.publish([], "sui");
expect(result).toEqual({ status: "success" }); expect(result).toEqual({ status: "success" });
expect(snsClient.send).not.toHaveBeenCalled(); expect(snsClient.send).not.toHaveBeenCalled();
@ -19,17 +19,20 @@ describe("SnsEventRepository", () => {
it("should publish", async () => { it("should publish", async () => {
givenSnsEventRepository(); givenSnsEventRepository();
const result = await snsEventRepository.publish([ const result = await snsEventRepository.publish(
{ [
chainId: 1, {
address: "0x123456", chainId: 1,
txHash: "0x123", address: "0x123456",
blockHeight: 123n, txHash: "0x123",
blockTime: 0, blockHeight: 123n,
name: "LogMessagePublished", blockTime: 0,
attributes: {}, name: "LogMessagePublished",
}, attributes: {},
]); },
],
"sui"
);
expect(result).toEqual({ status: "success" }); expect(result).toEqual({ status: "success" });
expect(snsClient.send).toHaveBeenCalledTimes(1); expect(snsClient.send).toHaveBeenCalledTimes(1);