Files
CleanArchitecture-template/docs/Observability-Guide.md
2026-02-26 14:04:18 +07:00

6.0 KiB

Observability Guide - Serilog & OpenTelemetry

Tổng quan

Dự án đã được tích hợp Serilog (Structured Logging) và OpenTelemetry (Distributed Tracing) để hỗ trợ giám sát và debug ứng dụng khi chạy trên production/Docker.

Serilog - Structured Logging

Tính năng

  • JSON Format: Log được ghi dưới dạng JSON, dễ dàng parse và filter
  • Multiple Sinks: Console, File, Seq, Elasticsearch
  • Enrichment: Tự động thêm thông tin như Environment, MachineName, ThreadId
  • Rolling Files: Tự động rotate log files theo ngày/tuần/tháng

Cấu hình trong appsettings.json

{
  "Serilog": {
    "MinimumLevel": "Information",
    "Override": {
      "Microsoft": "Warning",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.EntityFrameworkCore": "Warning"
    },
    "WriteToConsole": true,
    "WriteToFile": true,
    "FilePath": "logs/log-.txt",
    "RollingInterval": "Day",
    "RetainedFileCountLimit": 31,
    "SeqUrl": "http://localhost:5341",
    "ElasticsearchUrl": null
  }
}

Sử dụng trong Code

using Serilog;

public class MyService
{
    private readonly ILogger _logger;

    public MyService(ILogger logger)
    {
        _logger = logger;
    }

    public void DoSomething()
    {
        // Structured logging với properties
        _logger.Information(
            "Processing order {OrderId} for user {UserId}",
            orderId,
            userId
        );

        // Log với exception
        try
        {
            // ...
        }
        catch (Exception ex)
        {
            _logger.Error(ex, "Failed to process order {OrderId}", orderId);
        }
    }
}

Log Levels

  • Verbose: Chi tiết nhất, dùng cho debug
  • Debug: Thông tin debug
  • Information: Thông tin thông thường (mặc định)
  • Warning: Cảnh báo
  • Error: Lỗi
  • Fatal: Lỗi nghiêm trọng, ứng dụng có thể crash

Tích hợp với Seq (Development)

  1. Chạy Seq trong Docker:
docker run -d --name seq -p 5341:80 -e ACCEPT_EULA=Y datalust/seq:latest
  1. Cập nhật appsettings.json:
{
  "Serilog": {
    "SeqUrl": "http://localhost:5341"
  }
}
  1. Xem logs tại: http://localhost:5341

Tích hợp với ELK Stack (Production)

  1. Cài đặt Elasticsearch và Kibana
  2. Cập nhật appsettings.json với ElasticsearchUrl
  3. Xem logs trong Kibana dashboard

OpenTelemetry - Distributed Tracing

Tính năng

  • Distributed Tracing: Theo dõi request qua nhiều services
  • Performance Monitoring: Đo thời gian thực thi từng operation
  • Automatic Instrumentation: Tự động instrument ASP.NET Core, HTTP Client, EF Core
  • OTLP Export: Export traces đến các hệ thống như Jaeger, Zipkin, Grafana

Cấu hình

OpenTelemetry đã được cấu hình tự động trong Program.cs:

builder.Services.AddOpenTelemetryTracing("MyNewProjectName.WebAPI");

Instrumentation tự động

  • ASP.NET Core: Tự động trace HTTP requests/responses
  • HTTP Client: Trace các HTTP calls đến external APIs
  • Entity Framework Core: Trace database queries

Xem Traces

Option 1: Console (Development)

Traces được export ra console, có thể thấy trong log output.

Option 2: OTLP Collector (Production)

  1. Chạy OTLP Collector:
# docker-compose.yml
services:
  otlp-collector:
    image: otel/opentelemetry-collector:latest
    ports:
      - "4317:4317" # OTLP gRPC receiver
      - "4318:4318" # OTLP HTTP receiver
    volumes:
      - ./otel-collector-config.yaml:/etc/otelcol/config.yaml
  1. Cấu hình export trong code (nếu cần):
.AddOtlpExporter(options =>
{
    options.Endpoint = new Uri("http://otlp-collector:4317");
})
  1. Export đến Jaeger, Zipkin, hoặc Grafana Tempo

Tích hợp với Jaeger

  1. Chạy Jaeger:
docker run -d --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  jaegertracing/all-in-one:latest
  1. Xem traces tại: http://localhost:16686

Best Practices

1. Structured Logging

Tốt: Sử dụng structured logging với properties

_logger.Information("User {UserId} created order {OrderId}", userId, orderId);

Không tốt: String interpolation

_logger.Information($"User {userId} created order {orderId}");

2. Log Levels

  • Information: Business events (user login, order created)
  • Warning: Unexpected situations (retry, fallback)
  • Error: Exceptions và failures
  • Debug: Chi tiết kỹ thuật (chỉ trong development)

3. Correlation ID

Sử dụng correlation ID để link logs và traces:

// Trong middleware
var correlationId = Guid.NewGuid().ToString();
LogContext.PushProperty("CorrelationId", correlationId);

4. Sensitive Data

Không log:

  • Passwords
  • Credit card numbers
  • API keys
  • Personal information (PII)

Log:

  • User IDs (không phải username/email)
  • Order IDs
  • Request/Response metadata (không có sensitive data)

Monitoring trong Docker

Khi chạy trong Docker, logs được ghi vào:

  • Console: docker logs <container-name>
  • Files: logs/log-*.txt trong container
  • Seq/ELK: Nếu đã cấu hình

Xem logs trong Docker

# Xem logs real-time
docker logs -f webapi

# Xem logs với timestamp
docker logs -t webapi

# Xem logs của 100 dòng cuối
docker logs --tail 100 webapi

Troubleshooting

Logs không xuất hiện

  1. Kiểm tra Serilog:WriteToConsole trong appsettings.json
  2. Kiểm tra Serilog:MinimumLevel có quá cao không
  3. Kiểm tra Docker logs: docker logs <container-name>

Traces không hiển thị

  1. Kiểm tra OpenTelemetry đã được add trong Program.cs
  2. Kiểm tra OTLP endpoint nếu dùng collector
  3. Kiểm tra network connectivity đến collector

Performance Impact

  • Serilog: Minimal impact, async logging
  • OpenTelemetry: ~1-2% overhead, có thể disable trong development nếu cần