Skip to content

Logging Overview

The AI-Enhanced TypeScript Template includes a comprehensive logging system built on Winston, providing structured, configurable, and professional logging for your TypeScript applications.

What is Winston Logging?

Winston is a versatile logging library for Node.js that provides:

  • Multiple transport options (console, file, database, etc.)
  • Configurable log levels (error, warn, info, debug)
  • Structured logging with metadata support
  • Custom formatting for different environments
  • Performance optimized for production use

Key Features

🎯 Professional Logging

  • Structured log messages with consistent formatting
  • Multiple output targets (console with colors, JSON files)
  • Configurable log levels for different environments
  • Timestamp and metadata support for debugging

🔧 Easy Configuration

  • Environment-aware setup with sensible defaults
  • File and console outputs with different formats
  • Configurable through application config or environment variables
  • Hot-reloadable configuration for runtime adjustments

🛠️ Developer Experience

  • Utility functions for common logging patterns
  • Type-safe interfaces for dependency injection
  • Test-friendly design with proper mocking support
  • Professional patterns for production-ready logging

Quick Start

1. Import the Logger

typescript
import { logger } from './logger.js';

// Basic usage
logger.info('Application started');
logger.error('Something went wrong', { error: errorObject });
logger.debug('Debug information', { userId: 123, action: 'login' });

2. Use Logger Utilities

typescript
import { loggerUtils } from './logger.js';

// Validation logging
loggerUtils.logValidationSuccess(logger, 'User data validated', userData);
loggerUtils.logValidationFailure(logger, 'Invalid input', errorMessage);

// Section headers for better organization
loggerUtils.logSectionHeader(logger, 'Database Migration');

// Application lifecycle
loggerUtils.logStartup(logger, 'MyApp', '1.0.0');
loggerUtils.logCompletion(logger, 'Process completed successfully');

3. Configure for Your Environment

typescript
import { createLoggerFromConfig } from './logger.js';

// Load from application config
const config = {
  level: 'info',
  outputFile: 'app.log',
  includeTimestamp: true,
  useColors: true
};

const logger = createLoggerFromConfig(config);

Log Levels

Winston supports multiple log levels with different priorities:

LevelPriorityUsageExample
error0System errors, exceptionsDatabase connection failed
warn1Warning conditionsDeprecated API usage
info2General informationUser logged in, server started
debug3Detailed debuggingFunction entry/exit, variable values

Level Filtering

typescript
// Only log 'error' and 'warn' messages in production
const productionLogger = createLogger({
  level: 'warn',
  outputFile: 'production.log',
  useColors: false
});

// Log everything in development
const developmentLogger = createLogger({
  level: 'debug',
  outputFile: null, // Console only
  useColors: true
});

Output Formats

Console Output (Development)

2024-01-15 10:30:45 [INFO]: Application started
2024-01-15 10:30:46 [ERROR]: Database connection failed { host: "localhost", port: 5432 }

JSON File Output (Production)

json
{
  "timestamp": "2024-01-15T10:30:45.123Z",
  "level": "info",
  "message": "Application started",
  "metadata": {}
}
{
  "timestamp": "2024-01-15T10:30:46.456Z",
  "level": "error",
  "message": "Database connection failed",
  "metadata": { "host": "localhost", "port": 5432 }
}

Configuration Options

Logger Configuration

typescript
interface LoggerConfig {
  level: 'error' | 'warn' | 'info' | 'debug';
  outputFile: string | null;
  includeTimestamp: boolean;
  useColors: boolean;
}

// Example configurations
const configs = {
  development: {
    level: 'debug',
    outputFile: null,
    includeTimestamp: true,
    useColors: true
  },
  production: {
    level: 'info',
    outputFile: 'app.log',
    includeTimestamp: true,
    useColors: false
  },
  test: {
    level: 'error',
    outputFile: null,
    includeTimestamp: false,
    useColors: false
  }
};

Environment Variables

bash
# Override configuration with environment variables
LOG_LEVEL=debug
LOG_FILE=debug.log
LOG_COLORS=true
LOG_TIMESTAMP=true

Integration with Validation

The logging system integrates seamlessly with the validation system:

typescript
import { validateUserInput } from './validation.js';
import { loggerUtils } from './logger.js';

function processUser(userData: unknown) {
  const result = validateUserInput(userData);
  
  if (result.success) {
    loggerUtils.logValidationSuccess(
      logger, 
      'User input validated successfully',
      { userId: result.data.name }
    );
    return result.data;
  } else {
    loggerUtils.logValidationFailure(
      logger,
      'User input validation failed',
      result.error
    );
    throw new Error(`Invalid user data: ${result.error}`);
  }
}

Professional Logging Patterns

Structured Logging Approach

typescript
// Professional logging with context and metadata
logger.info('User logged in', {
  userId: user.id,
  timestamp: new Date().toISOString(),
  ip: req.ip
});

logger.error('Database error', {
  error: { message: error.message, stack: error.stack },
  operation: 'user_lookup',
  duration: Date.now() - startTime
});

logger.info('Starting server', {
  port,
  host,
  environment: process.env.NODE_ENV
});

Key Benefits

  • Structured data with searchable metadata
  • Configurable output (console, file, remote services)
  • Log level filtering for different environments
  • Better performance in production
  • Rich context for debugging and monitoring

Best Practices

✅ Do

  • Use appropriate log levels - error for errors, info for general information
  • Include relevant metadata - user IDs, request IDs, error details
  • Use structured logging - objects instead of string concatenation
  • Configure for environment - debug in development, info in production
  • Log application lifecycle - startup, shutdown, major operations

❌ Don't

  • Log sensitive information - passwords, tokens, personal data
  • Over-log in production - avoid debug logs in production
  • Use basic console output - always use the structured logger
  • Log without context - include relevant metadata
  • Ignore log rotation - configure file rotation for production

Performance Considerations

Async Logging

typescript
// Winston handles async logging automatically
logger.info('This is logged asynchronously');

// For critical logs that must be written before continuing
await new Promise(resolve => logger.info('Critical log', resolve));

Log Sampling

typescript
// Sample logs in high-traffic scenarios
let logCounter = 0;
function conditionalLog(message: string, metadata?: object) {
  logCounter++;
  if (logCounter % 100 === 0) { // Log every 100th occurrence
    logger.info(message, metadata);
  }
}

Next Steps

Released under the MIT License.