first commit
This commit is contained in:
254
docs/Observability-Guide.md
Normal file
254
docs/Observability-Guide.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user