logging-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Logging Best Practices

日志记录最佳实践

Implement secure, structured logging with proper levels and context.
实现具备适当级别和上下文的安全、结构化日志记录。

Log Levels

日志级别

LevelUse ForProduction
DEBUGDetailed debuggingOff
INFONormal operationsOn
WARNPotential issuesOn
ERRORErrors with recoveryOn
FATALCritical failuresOn
级别使用场景生产环境状态
DEBUG详细调试信息关闭
INFO正常操作记录开启
WARN潜在问题预警开启
ERROR可恢复的错误开启
FATAL严重故障开启

Structured Logging (Winston)

结构化日志记录(Winston)

javascript
const winston = require('winston');

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  defaultMeta: { service: 'api-service' },
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'error.log', level: 'error' })
  ]
});

// Usage
logger.info('User logged in', { userId: '123', ip: '192.168.1.1' });
logger.error('Payment failed', { error: err.message, orderId: '456' });
javascript
const winston = require('winston');

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  defaultMeta: { service: 'api-service' },
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'error.log', level: 'error' })
  ]
});

// Usage
logger.info('User logged in', { userId: '123', ip: '192.168.1.1' });
logger.error('Payment failed', { error: err.message, orderId: '456' });

Request Context

请求上下文

javascript
const { AsyncLocalStorage } = require('async_hooks');
const storage = new AsyncLocalStorage();

app.use((req, res, next) => {
  const context = {
    requestId: req.headers['x-request-id'] || uuid(),
    userId: req.user?.id
  };
  storage.run(context, next);
});

function log(level, message, meta = {}) {
  const context = storage.getStore() || {};
  logger.log(level, message, { ...context, ...meta });
}
javascript
const { AsyncLocalStorage } = require('async_hooks');
const storage = new AsyncLocalStorage();

app.use((req, res, next) => {
  const context = {
    requestId: req.headers['x-request-id'] || uuid(),
    userId: req.user?.id
  };
  storage.run(context, next);
});

function log(level, message, meta = {}) {
  const context = storage.getStore() || {};
  logger.log(level, message, { ...context, ...meta });
}

PII Sanitization

PII脱敏

javascript
const sensitiveFields = ['password', 'ssn', 'creditCard', 'token'];

function sanitize(obj) {
  const sanitized = { ...obj };
  for (const field of sensitiveFields) {
    if (sanitized[field]) sanitized[field] = '[REDACTED]';
  }
  if (sanitized.email) {
    sanitized.email = sanitized.email.replace(/(.{2}).*@/, '$1***@');
  }
  return sanitized;
}
javascript
const sensitiveFields = ['password', 'ssn', 'creditCard', 'token'];

function sanitize(obj) {
  const sanitized = { ...obj };
  for (const field of sensitiveFields) {
    if (sanitized[field]) sanitized[field] = '[REDACTED]';
  }
  if (sanitized.email) {
    sanitized.email = sanitized.email.replace(/(.{2}).*@/, '$1***@');
  }
  return sanitized;
}

Best Practices

最佳实践

  • Use structured JSON format
  • Include correlation IDs across services
  • Sanitize all PII before logging
  • Use async logging for performance
  • Implement log rotation
  • Never log at DEBUG in production
  • 使用结构化JSON格式
  • 在跨服务场景中包含关联ID
  • 日志记录前对所有PII进行脱敏处理
  • 使用异步日志记录提升性能
  • 实现日志轮转
  • 生产环境中绝不启用DEBUG级别日志

Additional Implementations

其他实现方案

See references/advanced-logging.md for:
  • Python structlog setup
  • Go zap high-performance logging
  • ELK Stack integration
  • AWS CloudWatch configuration
  • OpenTelemetry tracing
查看references/advanced-logging.md了解:
  • Python structlog配置
  • Go zap高性能日志记录
  • ELK Stack集成
  • AWS CloudWatch配置
  • OpenTelemetry追踪

Never Do

禁止操作

  • Log passwords or tokens
  • Use console.log in production
  • Log inside tight loops
  • Include stack traces for client errors
  • 记录密码或令牌
  • 生产环境中使用console.log
  • 在紧密循环中记录日志
  • 为客户端错误包含堆栈跟踪