From 42b96d58a05e9ebec15f14b366c8aa0116014772 Mon Sep 17 00:00:00 2001 From: ajdj100 Date: Wed, 31 Dec 2025 09:51:40 -0500 Subject: [PATCH] added new logging system --- api/.env.example | 3 ++ api/src/services/logging/logger.ts | 67 ++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 api/src/services/logging/logger.ts diff --git a/api/.env.example b/api/.env.example index 9a1e8da..515a080 100644 --- a/api/.env.example +++ b/api/.env.example @@ -23,6 +23,9 @@ APPLICATION_VERSION= # Should match release tag APPLICATION_ENVIRONMENT= # dev / prod CONFIG_ID= # configures +# Logger +LOG_DEPTH= # normal: 0, verbose: 1 + # Glitchtip GLITCHTIP_DSN= DISABLE_GLITCHTIP= # true/false diff --git a/api/src/services/logging/logger.ts b/api/src/services/logging/logger.ts new file mode 100644 index 0000000..3c59bde --- /dev/null +++ b/api/src/services/logging/logger.ts @@ -0,0 +1,67 @@ +export type LogLevel = 'debug' | 'info' | 'warn' | 'error'; +export type LogDepth = 'normal' | 'verbose'; +export type LogType = 'http' | 'app'; + +export interface LogHeader { + timestamp: string; + level: LogLevel; + depth: LogDepth; + type: LogType; // 'http', 'app', 'db', etc. + user_id?: number; +} + +export interface LogPayload { + message?: string; // short human-friendly description + data?: Record; // type-specific rich data +} + +// Environment defaults +const CURRENT_DEPTH: LogDepth = (process.env.LOG_DEPTH as LogDepth) || 'normal'; + +const DEPTH_ORDER: Record = { normal: 0, verbose: 1 }; + +function shouldLog(level: LogLevel, depth: LogDepth) { + return DEPTH_ORDER[depth] >= DEPTH_ORDER[CURRENT_DEPTH]; +} + +function emitLog(header: LogHeader, payload: LogPayload = {}) { + if (!shouldLog(header.level, header.depth)) return; + + const logLine = { ...header, ...payload }; + console.log(JSON.stringify(logLine)); +} + +export const logger = { + log(level: LogLevel, type: LogType, message: string, data?: Record, depth: LogDepth = 'normal', context?: Partial) { + const header: LogHeader = { + timestamp: new Date().toISOString(), + level, + depth, + type, + ...context, + }; + + const payload: LogPayload = { + message, + data, + }; + + emitLog(header, payload); + }, + + info(type: string, message: string, data?: Record, depth: LogDepth = 'normal', context?: Partial) { + this.log('info', type, message, data, depth, context); + }, + + debug(type: string, message: string, data?: Record, depth: LogDepth = 'normal', context?: Partial) { + this.log('debug', type, message, data, depth, context); + }, + + warn(type: string, message: string, data?: Record, depth: LogDepth = 'normal', context?: Partial) { + this.log('warn', type, message, data, depth, context); + }, + + error(type: string, message: string, data?: Record, depth: LogDepth = 'normal', context?: Partial) { + this.log('error', type, message, data, depth, context); + }, +} \ No newline at end of file