📝 日志

微服务日志实现:构建可观测性体系

深入探讨微服务架构中的日志系统设计,包括结构化日志、日志聚合、分布式追踪、日志分析等核心技术

一、微服务日志挑战

微服务架构中的日志分散在多个服务中,需要统一收集和分析。

二、结构化日志设计

设计结构化的日志格式便于分析。

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<LoggingMiddleware> _logger;

    public async Task InvokeAsync(HttpContext context)
    {
        var startTime = DateTime.UtcNow;
        var requestId = Guid.NewGuid().ToString();
        
        using (_logger.BeginScope(new Dictionary<string, object> {
            ["RequestId"] = requestId,
            ["Path"] = context.Request.Path
        }))
        {
            _logger.LogInformation("Processing request");
            await _next(context);
            _logger.LogInformation("Request completed in {Duration}ms", 
                (DateTime.UtcNow - startTime).TotalMilliseconds);
        }
    }
}

三、日志框架选择

选择合适的日志框架。

// Serilog 配置
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .WriteTo.Console()
    .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
    .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")))
    .CreateLogger();

四、日志聚合系统

使用ELK栈聚合和分析日志。

# Filebeat 配置
filebeat.inputs:
- type: log
  paths:
    - /var/log/myapp/*.log

output.elasticsearch:
  hosts: ["elasticsearch:9200"]

setup.kibana:
  host: "kibana:5601"

五、分布式追踪

追踪跨服务的请求链路。

// OpenTelemetry 配置
public void ConfigureServices(IServiceCollection services)
{
    services.AddOpenTelemetry()
        .WithTracing(tracing => tracing
            .AddAspNetCoreInstrumentation()
            .AddHttpClientInstrumentation()
            .AddZipkinExporter()
            .AddConsoleExporter());
}

六、日志级别管理

合理设置日志级别。

// appsettings.json 日志配置
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

七、敏感数据脱敏

保护日志中的敏感信息。

public class SensitiveDataEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        // 脱敏处理
        var message = logEvent.MessageTemplate.Text;
        message = Regex.Replace(message, @"\b[\w.-]+@[\w.-]+\.\w+\b", "[REDACTED]");
        logEvent.MessageTemplate = new MessageTemplateParser().Parse(message);
    }
}

八、日志查询与分析

使用Kibana查询和可视化日志。

九、日志告警策略

设置日志告警规则。

十、日志最佳实践

编写高质量日志的建议。