# 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 ```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 ```csharp 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: ```bash docker run -d --name seq -p 5341:80 -e ACCEPT_EULA=Y datalust/seq:latest ``` 2. Cập nhật appsettings.json: ```json { "Serilog": { "SeqUrl": "http://localhost:5341" } } ``` 3. 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`: ```csharp 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: ```yaml # 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 ``` 2. Cấu hình export trong code (nếu cần): ```csharp .AddOtlpExporter(options => { options.Endpoint = new Uri("http://otlp-collector:4317"); }) ``` 3. Export đến Jaeger, Zipkin, hoặc Grafana Tempo ### Tích hợp với Jaeger 1. Chạy Jaeger: ```bash docker run -d --name jaeger \ -p 16686:16686 \ -p 4317:4317 \ jaegertracing/all-in-one:latest ``` 2. Xem traces tại: http://localhost:16686 ## Best Practices ### 1. Structured Logging ✅ **Tốt**: Sử dụng structured logging với properties ```csharp _logger.Information("User {UserId} created order {OrderId}", userId, orderId); ``` ❌ **Không tốt**: String interpolation ```csharp _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: ```csharp // 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 ` - **Files**: `logs/log-*.txt` trong container - **Seq/ELK**: Nếu đã cấu hình ### Xem logs trong Docker ```bash # 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 ` ### 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