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

255 lines
6.0 KiB
Markdown

# 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 <container-name>`
- **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 <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