File size: 7,216 Bytes
1f7d0a1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# Correlation ID Implementation Guide

## Overview

Correlation ID logging has been implemented in the AUTH microservice to enable request tracing across distributed systems. This allows you to track a single request as it flows through multiple microservices.

## What is a Correlation ID?

A correlation ID is a unique identifier (UUID) that is:
- Generated for each incoming request (if not already present)
- Propagated through all logs for that request
- Passed to downstream services via HTTP headers
- Returned in response headers for client tracking

## Implementation Components

### 1. Correlation ID Middleware (`app/middleware/correlation_id.py`)

The middleware handles:
- Extracting correlation ID from `X-Correlation-ID` header
- Generating new UUID if not present
- Storing in context variable for request lifecycle
- Adding correlation ID to response headers

### 2. Logging Integration (`app/core/logging.py`)

The logging system includes:
- `CorrelationIdFilter`: Adds correlation ID to all log records
- JSON formatter includes `correlation_id` field
- All handlers (console, file) have the filter applied

### 3. HTTP Client Utility (`app/utils/http_client.py`)

The `CorrelationHttpClient` class provides methods that automatically propagate correlation IDs to downstream services:
- `get()`, `post()`, `put()`, `delete()` methods
- Automatically includes `X-Correlation-ID` header

## Usage Examples

### 1. Automatic Logging

All logs automatically include the correlation ID:

```python
from app.core.logging import get_logger

logger = get_logger(__name__)

# This log will automatically include correlation_id
logger.info("Processing user login", extra={"user_id": user_id})
```

### 2. Getting Current Correlation ID

```python
from app.middleware.correlation_id import get_correlation_id

correlation_id = get_correlation_id()
logger.info(f"Current correlation ID: {correlation_id}")
```

### 3. Making HTTP Calls to Other Services

```python
from app.utils.http_client import CorrelationHttpClient

# Correlation ID is automatically included in headers
response = await CorrelationHttpClient.post(
    url="http://scm-service/api/merchants/list",
    json={"filters": {}}
)
```

### 4. Manual Header Propagation

If you need to use a different HTTP client:

```python
from app.middleware.correlation_id import get_correlation_id, CORRELATION_ID_HEADER
import httpx

correlation_id = get_correlation_id()
headers = {CORRELATION_ID_HEADER: correlation_id}

async with httpx.AsyncClient() as client:
    response = await client.get(url, headers=headers)
```

## Log Format

Logs now include the correlation ID in JSON format:

```json
{
  "timestamp": "2024-03-07T10:30:45.123456",
  "level": "INFO",
  "logger": "app.auth.services.service",
  "message": "User login successful",
  "correlation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "module": "service",
  "function": "login_user",
  "line": 123,
  "user_id": "user123"
}
```

## Tracing Requests Across Services

### Client Request Flow

1. Client makes request (optionally with `X-Correlation-ID` header)
2. AUTH service receives request
3. Middleware extracts or generates correlation ID
4. All logs include correlation ID
5. AUTH service calls SCM service with correlation ID in header
6. SCM service logs with same correlation ID
7. Response includes `X-Correlation-ID` header

### Example: Tracing a Login Request

```bash
# Client request
curl -X POST https://api.example.com/auth/login \
  -H "X-Correlation-ID: abc-123" \
  -d '{"email": "user@example.com", "password": "pass"}'

# AUTH service logs (correlation_id: abc-123)
{"timestamp": "...", "correlation_id": "abc-123", "message": "Login request received"}
{"timestamp": "...", "correlation_id": "abc-123", "message": "Validating credentials"}
{"timestamp": "...", "correlation_id": "abc-123", "message": "Fetching user permissions from SCM"}

# SCM service logs (correlation_id: abc-123)
{"timestamp": "...", "correlation_id": "abc-123", "message": "Permission request received"}
{"timestamp": "...", "correlation_id": "abc-123", "message": "Returning user permissions"}

# AUTH service logs (correlation_id: abc-123)
{"timestamp": "...", "correlation_id": "abc-123", "message": "Login successful"}
```

## Searching Logs by Correlation ID

### Using grep

```bash
# Search all logs for a specific correlation ID
grep "abc-123" logs/app.log

# Search with jq for better formatting
grep "abc-123" logs/app.log | jq '.'
```

### Using log aggregation tools

If using ELK, Splunk, or similar:

```
correlation_id:"abc-123"
```

## Best Practices

1. **Always use CorrelationHttpClient** for inter-service communication
2. **Include correlation ID in error responses** for client debugging
3. **Log correlation ID at service boundaries** (entry/exit points)
4. **Pass correlation ID to background tasks** if they're part of the same logical operation
5. **Don't modify correlation IDs** once set - they should remain constant throughout the request lifecycle

## Testing

### Test Correlation ID Generation

```bash
# Request without correlation ID (will be generated)
curl -X GET http://localhost:8002/health -v

# Check response headers for X-Correlation-ID
```

### Test Correlation ID Propagation

```bash
# Request with correlation ID
curl -X GET http://localhost:8002/health \
  -H "X-Correlation-ID: test-123" -v

# Verify same ID is returned in response headers
```

### Test Logging

```bash
# Make request with known correlation ID
curl -X POST http://localhost:8002/auth/login \
  -H "X-Correlation-ID: test-456" \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com", "password": "test"}'

# Check logs
grep "test-456" logs/app.log | jq '.'
```

## Troubleshooting

### Correlation ID not appearing in logs

1. Check that middleware is properly registered in `main.py`
2. Verify `CorrelationIdFilter` is added to all log handlers
3. Ensure logging is configured before making requests

### Correlation ID not propagating to downstream services

1. Use `CorrelationHttpClient` instead of direct httpx calls
2. Verify downstream service supports `X-Correlation-ID` header
3. Check that correlation ID is in context (`get_correlation_id()` returns value)

### Different correlation IDs in related logs

1. Ensure you're not creating new async contexts without propagating correlation ID
2. For background tasks, explicitly pass correlation ID
3. Verify middleware is processing requests before other middlewares

## Integration with Other Microservices

To implement correlation ID in other microservices (SCM, POS, SPA, etc.):

1. Copy `app/middleware/correlation_id.py` to the service
2. Update `app/core/logging.py` to include `CorrelationIdFilter`
3. Add `CorrelationIdMiddleware` to `main.py`
4. Copy `app/utils/http_client.py` for HTTP client utilities
5. Update inter-service calls to use `CorrelationHttpClient`

## Benefits

- **Debugging**: Trace requests across multiple services
- **Performance Analysis**: Identify bottlenecks in request flow
- **Error Tracking**: Link errors across service boundaries
- **Audit Trail**: Complete request history for compliance
- **Monitoring**: Better observability in distributed systems