All files / src/Infrastructure/Monitoring Logger.ts

82.35% Statements 14/17
23.07% Branches 3/13
85.71% Functions 6/7
81.25% Lines 13/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87            3x 3x           3x 1x                 1x 1x                 11x                     55x 55x                                         4x 4x                   59x   59x              
import { LoggerInterface } from "@Application/Shared/Monitoring/LoggerInterface";
import { TracingStore } from "@Infrastructure/Http/Middlewares/TracingMiddleware";
import { AsyncLocalStorage } from "async_hooks";
 
export type LoggerLevels = 'debug' | 'info' | 'warn' | 'error';
 
export const isLoggerLevel = (level: string): level is LoggerLevels => {
    return ['debug', 'info', 'warn', 'error'].includes(level);
}
 
/**
 * Implementation of the LoggerInterface
 */
export class Logger implements LoggerInterface {
    private readonly levelsMap: Record<LoggerLevels, number> = {
        debug: 1,
        info: 2,
        warn: 3,
        error: 4,
    };
 
 
    constructor(
        private readonly level: LoggerLevels = 'info',
        private readonly asyncLocalStorage: AsyncLocalStorage<TracingStore>
    ) { }
 
    /**
     * Logs a debug message
     * @param message The message to log
     * @param context Optional context data
     */
    debug(message: string, context: Record<string, unknown> = {}) {
        Iif (this.levelsMap[this.level] <= this.levelsMap.debug) {
            console.debug(`[DEBUG] ${message}`, this.addTracingContext(context));
        }
    }
 
    /**
     * Logs an informational message
     * @param message The message to log
     * @param context Optional context data
     */
    info(message: string, context: Record<string, unknown> = {}) {
        Eif (this.levelsMap[this.level] <= this.levelsMap.info) {
            console.log(`[INFO] ${message}`, this.addTracingContext(context));
        }
    }
 
    /**
     * Logs a warning message
     * @param message The message to log
     * @param context Optional context data
     */
    warn(message: string, context: Record<string, unknown> = {}) {
        if (this.levelsMap[this.level] <= this.levelsMap.warn) {
            console.warn(`[WARN] ${message}`, this.addTracingContext(context));
        }
    }
 
    /**
     * Logs an error message
     * @param message The message to log
     * @param context Optional context data
     */
    error(message: string, context: Record<string, unknown> = {}) {
        Eif (this.levelsMap[this.level] <= this.levelsMap.error) {
            console.error(`[ERROR] ${message}`, this.addTracingContext(context));
        }
    }
 
    /**
     * Adds tracing context to the log entry
     * @param context The existing context
     * @returns The context with tracing information added
     */
    private addTracingContext(context: Record<string, unknown>) {
        const tracingStore = this.asyncLocalStorage.getStore();
 
        return {
            ...context,
            correlationId: tracingStore?.correlationId,
            transactionId: tracingStore?.transactionId,
        };
    }
}