fixed logging

This commit is contained in:
Bojan Kucera 2025-06-05 09:05:40 -04:00
parent d0e8fd9e3f
commit 7c2e055dd4
8 changed files with 19 additions and 45 deletions

View file

@ -121,7 +121,6 @@ LOKI_USERNAME=
LOKI_PASSWORD= LOKI_PASSWORD=
LOKI_TENANT_ID= LOKI_TENANT_ID=
LOKI_PUSH_TIMEOUT=10000 LOKI_PUSH_TIMEOUT=10000
LOKI_FLUSH_INTERVAL_MS=5000
LOKI_BATCH_SIZE=1024 LOKI_BATCH_SIZE=1024
LOKI_BATCH_WAIT=1000 LOKI_BATCH_WAIT=1000
LOKI_RETENTION_PERIOD=30d LOKI_RETENTION_PERIOD=30d

View file

@ -37,7 +37,6 @@ LOKI_PASSWORD=
LOKI_RETENTION_DAYS=30 LOKI_RETENTION_DAYS=30
LOKI_LABELS=environment=development,service=stock-bot LOKI_LABELS=environment=development,service=stock-bot
LOKI_BATCH_SIZE=100 LOKI_BATCH_SIZE=100
LOKI_FLUSH_INTERVAL_MS=5000
# Feature Flags # Feature Flags
ENABLE_ML_SIGNALS=false ENABLE_ML_SIGNALS=false

View file

@ -116,7 +116,6 @@ LOKI_USERNAME=${LOKI_USERNAME}
LOKI_PASSWORD=${LOKI_PASSWORD} LOKI_PASSWORD=${LOKI_PASSWORD}
LOKI_TENANT_ID=${LOKI_TENANT_ID} LOKI_TENANT_ID=${LOKI_TENANT_ID}
LOKI_PUSH_TIMEOUT=30000 LOKI_PUSH_TIMEOUT=30000
LOKI_FLUSH_INTERVAL_MS=5000
LOKI_BATCH_SIZE=2048 LOKI_BATCH_SIZE=2048
LOKI_BATCH_WAIT=5000 LOKI_BATCH_WAIT=5000
LOKI_RETENTION_PERIOD=90d LOKI_RETENTION_PERIOD=90d

View file

@ -12,7 +12,6 @@ loadEnvVariables();
const app = new Hono(); const app = new Hono();
const logger = createLogger('data-service'); const logger = createLogger('data-service');
const PORT = parseInt(process.env.DATA_SERVICE_PORT || '3002'); const PORT = parseInt(process.env.DATA_SERVICE_PORT || '3002');
logger.info(`Data Service starting on port ${PORT}`);
// Health check endpoint // Health check endpoint
app.get('/health', (c) => { app.get('/health', (c) => {
return c.json({ return c.json({

View file

@ -78,7 +78,7 @@ LOKI_PORT=3100 # Loki server port
LOKI_RETENTION_DAYS=30 # Days to retain logs LOKI_RETENTION_DAYS=30 # Days to retain logs
LOKI_LABELS=environment=development,service=stock-bot # Default labels LOKI_LABELS=environment=development,service=stock-bot # Default labels
LOKI_BATCH_SIZE=100 # Number of logs to batch before sending LOKI_BATCH_SIZE=100 # Number of logs to batch before sending
LOKI_FLUSH_INTERVAL_MS=5000 # Max time to wait before sending logs LOKI_BATCH_WAIT=5 # Max time to wait before sending logs
``` ```
## Useful Loki Queries ## Useful Loki Queries

View file

@ -21,7 +21,7 @@ export const lokiConfig = cleanEnv(process.env, {
// Push Configuration // Push Configuration
LOKI_PUSH_TIMEOUT: num({ default: 10000, desc: 'Push timeout in ms' }), LOKI_PUSH_TIMEOUT: num({ default: 10000, desc: 'Push timeout in ms' }),
LOKI_BATCH_SIZE: num({ default: 1024, desc: 'Batch size for log entries' }), LOKI_BATCH_SIZE: num({ default: 1024, desc: 'Batch size for log entries' }),
LOKI_BATCH_WAIT: num({ default: 1000, desc: 'Batch wait time in ms' }), LOKI_BATCH_WAIT: num({ default: 5, desc: 'Batch wait time in ms' }),
// Retention Settings // Retention Settings
LOKI_RETENTION_PERIOD: str({ default: '30d', desc: 'Log retention period' }), LOKI_RETENTION_PERIOD: str({ default: '30d', desc: 'Log retention period' }),
@ -35,8 +35,6 @@ export const lokiConfig = cleanEnv(process.env, {
LOKI_DEFAULT_LABELS: str({ default: '', desc: 'Default labels for all log entries (JSON format)' }), LOKI_DEFAULT_LABELS: str({ default: '', desc: 'Default labels for all log entries (JSON format)' }),
LOKI_SERVICE_LABEL: str({ default: 'stock-bot', desc: 'Service label for log entries' }), LOKI_SERVICE_LABEL: str({ default: 'stock-bot', desc: 'Service label for log entries' }),
LOKI_ENVIRONMENT_LABEL: str({ default: 'development', desc: 'Environment label for log entries' }), LOKI_ENVIRONMENT_LABEL: str({ default: 'development', desc: 'Environment label for log entries' }),
LOKI_FLUSH_INTERVAL_MS: num({ default: 5000, desc: 'Flush interval ms' }),
}); });
// Export typed configuration object // Export typed configuration object
@ -60,5 +58,4 @@ export const {
LOKI_DEFAULT_LABELS, LOKI_DEFAULT_LABELS,
LOKI_SERVICE_LABEL, LOKI_SERVICE_LABEL,
LOKI_ENVIRONMENT_LABEL, LOKI_ENVIRONMENT_LABEL,
LOKI_FLUSH_INTERVAL_MS,
} = lokiConfig; } = lokiConfig;

View file

@ -163,7 +163,6 @@ LOG_FILE_PATH=./logs
LOKI_HOST=localhost LOKI_HOST=localhost
LOKI_PORT=3100 LOKI_PORT=3100
LOKI_BATCH_SIZE=1024 LOKI_BATCH_SIZE=1024
LOKI_FLUSH_INTERVAL_MS=5000
``` ```
## Advanced Usage ## Advanced Usage
@ -332,7 +331,6 @@ To use in your service:
### High memory usage ### High memory usage
- Reduce `LOKI_BATCH_SIZE` if batching too many logs - Reduce `LOKI_BATCH_SIZE` if batching too many logs
- Decrease `LOKI_FLUSH_INTERVAL_MS` to flush more frequently
- Disable file logging if not needed - Disable file logging if not needed
### Missing logs ### Missing logs

View file

@ -19,17 +19,6 @@ import type { LogLevel, LogContext, LogMetadata } from './types';
// Global logger instances cache // Global logger instances cache
const loggerInstances = new Map<string, pino.Logger>(); const loggerInstances = new Map<string, pino.Logger>();
// Pino log level mapping from string to number
const PINO_LEVELS: Record<LogLevel, number> = {
silly: 10,
debug: 20,
verbose: 25,
http: 30,
info: 30,
warn: 40,
error: 50
};
/** /**
* Create transport configuration for Pino based on options * Create transport configuration for Pino based on options
*/ */
@ -50,16 +39,11 @@ function createTransports(serviceName: string, options?: {
if (enableConsole) { if (enableConsole) {
targets.push({ targets.push({
target: 'pino-pretty', target: 'pino-pretty',
level: loggingConfig.LOG_LEVEL, level: loggingConfig.LOG_LEVEL, options: {
options: {
colorize: true, colorize: true,
translateTime: 'yyyy-mm-dd HH:MM:ss.l', translateTime: 'yyyy-mm-dd HH:MM:ss.l',
ignore: 'pid,hostname', ignore: 'pid,hostname',
messageFormat: '[{service}] {msg}', messageFormat: '[{service}] {msg}'
customPrettifiers: {
service: (service: string) => `${service}`,
level: (level: string) => `[${level.toUpperCase()}]`
}
} }
}); });
} }
@ -95,7 +79,7 @@ function createTransports(serviceName: string, options?: {
level: loggingConfig.LOG_LEVEL, level: loggingConfig.LOG_LEVEL,
options: { options: {
batching: true, batching: true,
interval: lokiConfig.LOKI_FLUSH_INTERVAL_MS, interval: lokiConfig.LOKI_BATCH_WAIT,
host: lokiConfig.LOKI_URL || `http://${lokiConfig.LOKI_HOST}:${lokiConfig.LOKI_PORT}`, host: lokiConfig.LOKI_URL || `http://${lokiConfig.LOKI_HOST}:${lokiConfig.LOKI_PORT}`,
basicAuth: lokiConfig.LOKI_USERNAME && lokiConfig.LOKI_PASSWORD basicAuth: lokiConfig.LOKI_USERNAME && lokiConfig.LOKI_PASSWORD
? { ? {
@ -109,7 +93,9 @@ function createTransports(serviceName: string, options?: {
...(lokiConfig.LOKI_DEFAULT_LABELS ? JSON.parse(lokiConfig.LOKI_DEFAULT_LABELS) : {}) ...(lokiConfig.LOKI_DEFAULT_LABELS ? JSON.parse(lokiConfig.LOKI_DEFAULT_LABELS) : {})
}, },
timeout: lokiConfig.LOKI_PUSH_TIMEOUT || 10000, timeout: lokiConfig.LOKI_PUSH_TIMEOUT || 10000,
silenceErrors: false silenceErrors: false,
// Better JSON handling
replaceTimestamp: false,
} }
}); });
} }
@ -161,27 +147,25 @@ function buildLogger(serviceName: string, options?: {
enableFile, enableFile,
enableLoki enableLoki
}); });
const loggerConfig: pino.LoggerOptions = { const loggerConfig: pino.LoggerOptions = {
// level: PINO_LEVELS[level] ? level : 'info', level: level,
// customLevels: PINO_LEVELS,
useOnlyCustomLevels: false,
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`, timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
// formatters: {
// level: (label: string) => ({ level: label }),
// bindings: () => ({})
// },
base: { base: {
service: serviceName, service: serviceName,
environment: loggingConfig.LOG_ENVIRONMENT, environment: loggingConfig.LOG_ENVIRONMENT,
version: loggingConfig.LOG_SERVICE_VERSION version: loggingConfig.LOG_SERVICE_VERSION
}, }
transport
}; };
// Only add transport if targets exist to avoid worker thread issues
if (transport && transport.targets && transport.targets.length > 0) {
loggerConfig.transport = transport;
}
return pino(loggerConfig); return pino(loggerConfig);
} }
/** /**
* Enhanced Logger class with convenience methods and flexible message handling * Enhanced Logger class with convenience methods and flexible message handling
*/ */
@ -199,8 +183,7 @@ export class Logger {
this.serviceName = serviceName; this.serviceName = serviceName;
this.context = context; this.context = context;
this.pino = createLogger(serviceName, options); this.pino = createLogger(serviceName, options);
} } /**
/**
* Flexible log method that accepts string or object messages * Flexible log method that accepts string or object messages
*/ */
log(level: LogLevel, message: string | object, metadata?: LogMetadata): void { log(level: LogLevel, message: string | object, metadata?: LogMetadata): void {
@ -221,7 +204,7 @@ export class Logger {
} }
/** /**
* Map custom log levels to Pino levels * Map custom log levels to standard Pino levels
*/ */
private mapToPinoLevel(level: LogLevel): string { private mapToPinoLevel(level: LogLevel): string {
switch (level) { switch (level) {