logging-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Logging Best Practices

日志最佳实践

Expert guidance for production-grade logging based on Boris Tane's loggingsucks.com philosophy.
基于Boris Tane的loggingsucks.com理念的生产级日志专业指导。

Core Philosophy

核心理念

Stop logging "what your code is doing." Start logging "what happened to this request."
Traditional logging is optimized for writing, not querying. Developers emit logs for immediate debugging convenience without considering how they'll be searched later. This creates massive signal-to-noise ratios at scale.
停止记录“你的代码在做什么”。开始记录“这个请求发生了什么”。
传统日志针对“写入”进行优化,而非“查询”。开发人员为了即时调试便利输出日志,却未考虑后续如何搜索这些日志。这会在大规模场景下导致极高的信噪比。

The Wide Events Architecture

宽事件架构

Instead of scattered log statements throughout your code, build one comprehensive event per request per service:
javascript
// ❌ Traditional scattered logging
logger.info("Request started");
logger.info(`User ${userId} found`);
logger.info("Fetching cart");
logger.debug(`Cart has ${items.length} items`);
logger.info("Processing payment");
logger.error(`Payment failed: ${error.message}`);

// ✅ Wide event - build throughout request, emit once
const event = {
  request_id: req.id,
  timestamp: Date.now(),
  service: "checkout",
  version: "2.3.1",

  user: { id: userId, tier: "premium", account_age_days: 847 },
  cart: { id: cartId, item_count: 3, total_cents: 15999 },
  payment: { method: "card", provider: "stripe", latency_ms: 234 },

  outcome: "failure",
  error: { type: "PaymentDeclined", code: "card_declined", retriable: true }
};

logger.info(event);
不要在代码中分散放置日志语句,而是为每个服务的每个请求构建一个全面的事件
javascript
// ❌ 传统分散式日志记录
logger.info("Request started");
logger.info(`User ${userId} found`);
logger.info("Fetching cart");
logger.debug(`Cart has ${items.length} items`);
logger.info("Processing payment");
logger.error(`Payment failed: ${error.message}`);

// ✅ 宽事件 - 在请求处理过程中构建,仅输出一次
const event = {
  request_id: req.id,
  timestamp: Date.now(),
  service: "checkout",
  version: "2.3.1",

  user: { id: userId, tier: "premium", account_age_days: 847 },
  cart: { id: cartId, item_count: 3, total_cents: 15999 },
  payment: { method: "card", provider: "stripe", latency_ms: 234 },

  outcome: "failure",
  error: { type: "PaymentDeclined", code: "card_declined", retriable: true }
};

logger.info(event);

Key Concepts

核心概念

ConceptDefinition
Wide EventOne comprehensive, context-rich log per request per service
CardinalityNumber of unique values (user IDs = high, HTTP methods = low)
DimensionalityCount of fields per event (aim for 40+ meaningful fields)
Tail SamplingSample decisions after request completion based on outcomes
概念定义
宽事件(Wide Event)每个服务的每个请求对应一个全面、上下文丰富的日志
基数(Cardinality)唯一值的数量(用户ID = 高基数,HTTP方法 = 低基数)
维度(Dimensionality)每个事件的字段数量(目标为40+个有意义的字段)
尾部采样(Tail Sampling)根据请求完成后的结果决定是否采样

When to Apply This Skill

适用场景

  • Implementing logging in new services
  • Reviewing code with log statements
  • Debugging production issues
  • Designing observability strategy
  • Migrating from printf-style to structured logging
  • Reducing log volume while improving queryability
  • 在新服务中实现日志功能
  • 审查包含日志语句的代码
  • 调试生产环境问题
  • 设计可观测性策略
  • 从printf风格日志迁移到结构化日志
  • 在提升日志可查询性的同时减少日志量

What This Skill Provides

本技能提供的内容

  1. Wide event patterns for different frameworks and languages
  2. Field design guidance for high-cardinality debugging
  3. Sampling strategies that preserve signal
  4. Anti-pattern detection in existing logging code
  5. Query-first thinking for log architecture
  1. 适用于不同框架和语言的宽事件模式
  2. 用于高基数调试的字段设计指导
  3. 保留有效信息的采样策略
  4. 现有日志代码中的反模式检测
  5. 面向日志架构的查询优先思维