@robertprp/intents-sdk
Version:
Shogun Network Intent-based cross-chain swaps SDK
129 lines (104 loc) • 3.48 kB
text/typescript
import { BaseError } from '../errors/index.js';
export enum LogLevel {
DEBUG = 'DEBUG',
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
NONE = 'NONE',
}
export type LoggerConfig = {
level: LogLevel;
customLogger?: CustomLogger;
};
export interface CustomLogger {
debug(message: string, ...args: unknown[]): void;
info(message: string, ...args: unknown[]): void;
warn(message: string, ...args: unknown[]): void;
error(message: string, ...args: unknown[]): void;
}
class DefaultLogger implements CustomLogger {
debug(message: string, ...args: unknown[]): void {
console.debug(`[${new Date().toISOString()} DEBUG] ${message}`, ...args);
}
info(message: string, ...args: unknown[]): void {
console.info(`[${new Date().toISOString()} INFO] ${message}`, ...args);
}
warn(message: string, ...args: unknown[]): void {
console.warn(`[${new Date().toISOString()} WARN] ${message}`, ...args);
}
error(message: string, ...args: unknown[]): void {
console.error(`[${new Date().toISOString()} ERROR] ${message}`, ...args);
}
}
class Logger {
private static instance: Logger;
private loggerImpl: CustomLogger = new DefaultLogger();
private logLevel: LogLevel = LogLevel.INFO;
private constructor() {}
public static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
public configure(config: LoggerConfig): void {
this.logLevel = config.level;
if (config.customLogger) {
this.loggerImpl = config.customLogger;
}
}
public debug(message: string, ...args: unknown[]): void {
if (this.shouldLog(LogLevel.DEBUG)) {
this.loggerImpl.debug(message, ...args);
}
}
public info(message: string, ...args: unknown[]): void {
if (this.shouldLog(LogLevel.INFO)) {
this.loggerImpl.info(message, ...args);
}
}
public warn(message: string, ...args: unknown[]): void {
if (this.shouldLog(LogLevel.WARN)) {
this.loggerImpl.warn(message, ...args);
}
}
public error(message: string, error?: unknown): void {
if (this.shouldLog(LogLevel.ERROR)) {
const formattedError = this.formatError(error);
this.loggerImpl.error(message, formattedError);
}
}
public logError(error: unknown): void {
if (this.shouldLog(LogLevel.ERROR)) {
const formattedError = this.formatError(error);
if (error instanceof BaseError) {
this.loggerImpl.error(`${error.name}: ${error.message}`, formattedError);
} else if (error instanceof Error) {
this.loggerImpl.error(`${error.name}: ${error.message}`, formattedError);
} else {
this.loggerImpl.error('Unknown error', formattedError);
}
}
}
private shouldLog(level: LogLevel): boolean {
const levels = [LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR];
const currentLevelIndex = levels.indexOf(this.logLevel);
const targetLevelIndex = levels.indexOf(level);
return currentLevelIndex <= targetLevelIndex && this.logLevel !== LogLevel.NONE;
}
private formatError(error?: unknown): unknown {
if (!error) return 'No error details provided';
if (error instanceof BaseError) {
return error.toJSON();
}
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack,
};
}
return error;
}
}
export const logger = Logger.getInstance();