255 lines
6.0 KiB
Markdown
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
|