feat(logging): add professional logging with pino and headless E2E tests - Add ILogger port interface in application layer - Implement PinoLogAdapter with Electron-compatible structured logging - Add NoOpLogAdapter for testing - Wire logging into DI container and all adapters - Create 32 E2E tests for automation workflow (headless-only) - Add vitest.e2e.config.ts for E2E test configuration - All tests enforce HEADLESS mode (no headed browser allowed)
This commit is contained in:
82
packages/infrastructure/config/LoggingConfig.ts
Normal file
82
packages/infrastructure/config/LoggingConfig.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { LogLevel } from '../../application/ports/ILogger';
|
||||
|
||||
export type LogEnvironment = 'development' | 'production' | 'test';
|
||||
|
||||
export interface LoggingEnvironmentConfig {
|
||||
level: LogLevel;
|
||||
prettyPrint: boolean;
|
||||
fileOutput: boolean;
|
||||
filePath?: string;
|
||||
maxFiles?: number;
|
||||
maxFileSize?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load logging configuration from environment variables.
|
||||
*
|
||||
* Environment variables:
|
||||
* - NODE_ENV: 'development' | 'production' | 'test' (default: 'development')
|
||||
* - LOG_LEVEL: Override log level (optional)
|
||||
* - LOG_FILE_PATH: Path for log files in production (default: './logs/gridpilot')
|
||||
* - LOG_MAX_FILES: Max rotated files to keep (default: 7)
|
||||
* - LOG_MAX_SIZE: Max file size before rotation (default: '10m')
|
||||
*
|
||||
* @returns LoggingEnvironmentConfig with parsed environment values
|
||||
*/
|
||||
export function loadLoggingConfig(): LoggingEnvironmentConfig {
|
||||
const envValue = process.env.NODE_ENV;
|
||||
const environment = isValidLogEnvironment(envValue) ? envValue : 'development';
|
||||
|
||||
const defaults = getDefaultsForEnvironment(environment);
|
||||
|
||||
const levelOverride = process.env.LOG_LEVEL;
|
||||
const level = isValidLogLevel(levelOverride) ? levelOverride : defaults.level;
|
||||
|
||||
return {
|
||||
level,
|
||||
prettyPrint: defaults.prettyPrint,
|
||||
fileOutput: defaults.fileOutput,
|
||||
filePath: process.env.LOG_FILE_PATH || './logs/gridpilot',
|
||||
maxFiles: parseIntSafe(process.env.LOG_MAX_FILES, 7),
|
||||
maxFileSize: process.env.LOG_MAX_SIZE || '10m',
|
||||
};
|
||||
}
|
||||
|
||||
function getDefaultsForEnvironment(env: LogEnvironment): LoggingEnvironmentConfig {
|
||||
switch (env) {
|
||||
case 'development':
|
||||
return {
|
||||
level: 'debug',
|
||||
prettyPrint: true,
|
||||
fileOutput: false,
|
||||
};
|
||||
case 'production':
|
||||
return {
|
||||
level: 'info',
|
||||
prettyPrint: false,
|
||||
fileOutput: true,
|
||||
};
|
||||
case 'test':
|
||||
return {
|
||||
level: 'warn',
|
||||
prettyPrint: false,
|
||||
fileOutput: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function isValidLogEnvironment(value: string | undefined): value is LogEnvironment {
|
||||
return value === 'development' || value === 'production' || value === 'test';
|
||||
}
|
||||
|
||||
function isValidLogLevel(value: string | undefined): value is LogLevel {
|
||||
return value === 'debug' || value === 'info' || value === 'warn' || value === 'error' || value === 'fatal';
|
||||
}
|
||||
|
||||
function parseIntSafe(value: string | undefined, defaultValue: number): number {
|
||||
if (value === undefined || value === '') {
|
||||
return defaultValue;
|
||||
}
|
||||
const parsed = parseInt(value, 10);
|
||||
return isNaN(parsed) ? defaultValue : parsed;
|
||||
}
|
||||
Reference in New Issue
Block a user