mdb-engine 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdb_engine/README.md +144 -0
- mdb_engine/__init__.py +37 -0
- mdb_engine/auth/README.md +631 -0
- mdb_engine/auth/__init__.py +128 -0
- mdb_engine/auth/casbin_factory.py +199 -0
- mdb_engine/auth/casbin_models.py +46 -0
- mdb_engine/auth/config_defaults.py +71 -0
- mdb_engine/auth/config_helpers.py +213 -0
- mdb_engine/auth/cookie_utils.py +158 -0
- mdb_engine/auth/decorators.py +350 -0
- mdb_engine/auth/dependencies.py +747 -0
- mdb_engine/auth/helpers.py +64 -0
- mdb_engine/auth/integration.py +578 -0
- mdb_engine/auth/jwt.py +225 -0
- mdb_engine/auth/middleware.py +241 -0
- mdb_engine/auth/oso_factory.py +323 -0
- mdb_engine/auth/provider.py +570 -0
- mdb_engine/auth/restrictions.py +271 -0
- mdb_engine/auth/session_manager.py +477 -0
- mdb_engine/auth/token_lifecycle.py +213 -0
- mdb_engine/auth/token_store.py +289 -0
- mdb_engine/auth/users.py +1516 -0
- mdb_engine/auth/utils.py +614 -0
- mdb_engine/cli/__init__.py +13 -0
- mdb_engine/cli/commands/__init__.py +7 -0
- mdb_engine/cli/commands/generate.py +105 -0
- mdb_engine/cli/commands/migrate.py +83 -0
- mdb_engine/cli/commands/show.py +70 -0
- mdb_engine/cli/commands/validate.py +63 -0
- mdb_engine/cli/main.py +41 -0
- mdb_engine/cli/utils.py +92 -0
- mdb_engine/config.py +217 -0
- mdb_engine/constants.py +160 -0
- mdb_engine/core/README.md +542 -0
- mdb_engine/core/__init__.py +42 -0
- mdb_engine/core/app_registration.py +392 -0
- mdb_engine/core/connection.py +243 -0
- mdb_engine/core/engine.py +749 -0
- mdb_engine/core/index_management.py +162 -0
- mdb_engine/core/manifest.py +2793 -0
- mdb_engine/core/seeding.py +179 -0
- mdb_engine/core/service_initialization.py +355 -0
- mdb_engine/core/types.py +413 -0
- mdb_engine/database/README.md +522 -0
- mdb_engine/database/__init__.py +31 -0
- mdb_engine/database/abstraction.py +635 -0
- mdb_engine/database/connection.py +387 -0
- mdb_engine/database/scoped_wrapper.py +1721 -0
- mdb_engine/embeddings/README.md +184 -0
- mdb_engine/embeddings/__init__.py +62 -0
- mdb_engine/embeddings/dependencies.py +193 -0
- mdb_engine/embeddings/service.py +759 -0
- mdb_engine/exceptions.py +167 -0
- mdb_engine/indexes/README.md +651 -0
- mdb_engine/indexes/__init__.py +21 -0
- mdb_engine/indexes/helpers.py +145 -0
- mdb_engine/indexes/manager.py +895 -0
- mdb_engine/memory/README.md +451 -0
- mdb_engine/memory/__init__.py +30 -0
- mdb_engine/memory/service.py +1285 -0
- mdb_engine/observability/README.md +515 -0
- mdb_engine/observability/__init__.py +42 -0
- mdb_engine/observability/health.py +296 -0
- mdb_engine/observability/logging.py +161 -0
- mdb_engine/observability/metrics.py +297 -0
- mdb_engine/routing/README.md +462 -0
- mdb_engine/routing/__init__.py +73 -0
- mdb_engine/routing/websockets.py +813 -0
- mdb_engine/utils/__init__.py +7 -0
- mdb_engine-0.1.6.dist-info/METADATA +213 -0
- mdb_engine-0.1.6.dist-info/RECORD +75 -0
- mdb_engine-0.1.6.dist-info/WHEEL +5 -0
- mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
- mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
- mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
# Observability Module
|
|
2
|
+
|
|
3
|
+
Comprehensive observability tools for MDB_ENGINE applications including metrics collection, structured logging with correlation IDs, and health check monitoring.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Metrics Collection**: Operation timing, error rates, and performance statistics
|
|
8
|
+
- **Structured Logging**: Contextual logging with correlation IDs and app context
|
|
9
|
+
- **Health Checks**: MongoDB, engine, and connection pool health monitoring
|
|
10
|
+
- **Context Tracking**: Automatic context propagation across async operations
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
The observability module is part of MDB_ENGINE. No additional installation required.
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Metrics
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from mdb_engine.observability import record_operation, get_metrics_collector
|
|
22
|
+
|
|
23
|
+
# Record an operation
|
|
24
|
+
record_operation(
|
|
25
|
+
operation_name="database.query",
|
|
26
|
+
duration_ms=45.2,
|
|
27
|
+
success=True,
|
|
28
|
+
app_slug="my_app",
|
|
29
|
+
collection_name="users"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Get metrics summary
|
|
33
|
+
collector = get_metrics_collector()
|
|
34
|
+
summary = collector.get_summary()
|
|
35
|
+
print(summary)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Logging
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from mdb_engine.observability import get_logger, set_correlation_id, set_app_context
|
|
42
|
+
|
|
43
|
+
# Get contextual logger
|
|
44
|
+
logger = get_logger(__name__)
|
|
45
|
+
|
|
46
|
+
# Set correlation ID for request tracking
|
|
47
|
+
correlation_id = set_correlation_id()
|
|
48
|
+
|
|
49
|
+
# Set app context
|
|
50
|
+
set_app_context(app_slug="my_app", user_id="user123")
|
|
51
|
+
|
|
52
|
+
# Log with automatic context
|
|
53
|
+
logger.info("Processing request", extra={"operation": "process_data"})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Health Checks
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from mdb_engine.observability import check_mongodb_health, check_engine_health, HealthChecker
|
|
60
|
+
|
|
61
|
+
# Check MongoDB health
|
|
62
|
+
mongodb_status = await check_mongodb_health(engine.mongo_client)
|
|
63
|
+
print(mongodb_status.status) # "healthy", "degraded", or "unhealthy"
|
|
64
|
+
|
|
65
|
+
# Check engine health
|
|
66
|
+
engine_status = await check_engine_health(engine)
|
|
67
|
+
print(engine_status.status)
|
|
68
|
+
|
|
69
|
+
# Use HealthChecker for multiple checks
|
|
70
|
+
checker = HealthChecker()
|
|
71
|
+
checker.register_check(check_mongodb_health)
|
|
72
|
+
checker.register_check(check_engine_health)
|
|
73
|
+
|
|
74
|
+
results = await checker.check_all()
|
|
75
|
+
print(results)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Metrics Collection
|
|
79
|
+
|
|
80
|
+
### Record Operations
|
|
81
|
+
|
|
82
|
+
Track operation performance and errors:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from mdb_engine.observability import record_operation
|
|
86
|
+
import time
|
|
87
|
+
|
|
88
|
+
# Record successful operation
|
|
89
|
+
start = time.time()
|
|
90
|
+
result = await db.collection.find_one({"_id": "doc123"})
|
|
91
|
+
duration_ms = (time.time() - start) * 1000
|
|
92
|
+
|
|
93
|
+
record_operation(
|
|
94
|
+
operation_name="database.find_one",
|
|
95
|
+
duration_ms=duration_ms,
|
|
96
|
+
success=True,
|
|
97
|
+
app_slug="my_app",
|
|
98
|
+
collection_name="documents"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Record failed operation
|
|
102
|
+
try:
|
|
103
|
+
await db.collection.insert_one(document)
|
|
104
|
+
except Exception as e:
|
|
105
|
+
record_operation(
|
|
106
|
+
operation_name="database.insert_one",
|
|
107
|
+
duration_ms=0,
|
|
108
|
+
success=False,
|
|
109
|
+
app_slug="my_app",
|
|
110
|
+
error=str(e)
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Get Metrics
|
|
115
|
+
|
|
116
|
+
Retrieve collected metrics:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from mdb_engine.observability import get_metrics_collector
|
|
120
|
+
|
|
121
|
+
collector = get_metrics_collector()
|
|
122
|
+
|
|
123
|
+
# Get all metrics
|
|
124
|
+
all_metrics = collector.get_metrics()
|
|
125
|
+
|
|
126
|
+
# Get metrics for specific operation
|
|
127
|
+
db_metrics = collector.get_metrics("database")
|
|
128
|
+
|
|
129
|
+
# Get summary
|
|
130
|
+
summary = collector.get_summary()
|
|
131
|
+
print(summary["summary"]["database.find_one"])
|
|
132
|
+
# {
|
|
133
|
+
# "operation": "database.find_one",
|
|
134
|
+
# "count": 150,
|
|
135
|
+
# "avg_duration_ms": 45.2,
|
|
136
|
+
# "min_duration_ms": 12.5,
|
|
137
|
+
# "max_duration_ms": 234.8,
|
|
138
|
+
# "error_count": 2,
|
|
139
|
+
# "error_rate_percent": 1.33,
|
|
140
|
+
# "last_execution": "2024-01-01T12:00:00"
|
|
141
|
+
# }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Metrics Collector
|
|
145
|
+
|
|
146
|
+
Use the MetricsCollector directly:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from mdb_engine.observability import MetricsCollector
|
|
150
|
+
|
|
151
|
+
collector = MetricsCollector()
|
|
152
|
+
|
|
153
|
+
# Record operations
|
|
154
|
+
collector.record_operation("custom.operation", 100.5, success=True)
|
|
155
|
+
collector.record_operation("custom.operation", 50.2, success=True, tag="read")
|
|
156
|
+
collector.record_operation("custom.operation", 200.0, success=False, tag="write")
|
|
157
|
+
|
|
158
|
+
# Get metrics
|
|
159
|
+
metrics = collector.get_metrics("custom.operation")
|
|
160
|
+
|
|
161
|
+
# Get operation count
|
|
162
|
+
count = collector.get_operation_count("custom.operation")
|
|
163
|
+
|
|
164
|
+
# Reset metrics
|
|
165
|
+
collector.reset()
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Structured Logging
|
|
169
|
+
|
|
170
|
+
### Contextual Logger
|
|
171
|
+
|
|
172
|
+
Get a logger that automatically adds context:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from mdb_engine.observability import get_logger, set_correlation_id, set_app_context
|
|
176
|
+
|
|
177
|
+
logger = get_logger(__name__)
|
|
178
|
+
|
|
179
|
+
# Set correlation ID (for request tracking)
|
|
180
|
+
correlation_id = set_correlation_id() # Generates UUID
|
|
181
|
+
|
|
182
|
+
# Set app context
|
|
183
|
+
set_app_context(app_slug="my_app", user_id="user123", collection_name="users")
|
|
184
|
+
|
|
185
|
+
# Log messages (context automatically added)
|
|
186
|
+
logger.info("User logged in")
|
|
187
|
+
logger.error("Failed to process request", extra={"error": "timeout"})
|
|
188
|
+
logger.debug("Processing data", extra={"item_count": 100})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Correlation IDs
|
|
192
|
+
|
|
193
|
+
Track requests across services:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from mdb_engine.observability import (
|
|
197
|
+
set_correlation_id,
|
|
198
|
+
get_correlation_id,
|
|
199
|
+
clear_correlation_id
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Set correlation ID at request start
|
|
203
|
+
correlation_id = set_correlation_id("req-12345")
|
|
204
|
+
|
|
205
|
+
# Get current correlation ID
|
|
206
|
+
current_id = get_correlation_id() # Returns "req-12345"
|
|
207
|
+
|
|
208
|
+
# Clear correlation ID
|
|
209
|
+
clear_correlation_id()
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### App Context
|
|
213
|
+
|
|
214
|
+
Set context that's automatically included in all logs:
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
from mdb_engine.observability import set_app_context, clear_app_context
|
|
218
|
+
|
|
219
|
+
# Set app context
|
|
220
|
+
set_app_context(
|
|
221
|
+
app_slug="my_app",
|
|
222
|
+
user_id="user123",
|
|
223
|
+
collection_name="documents",
|
|
224
|
+
operation="process_data"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
# All subsequent logs include this context
|
|
228
|
+
logger.info("Processing document")
|
|
229
|
+
|
|
230
|
+
# Clear context
|
|
231
|
+
clear_app_context()
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Logging Context
|
|
235
|
+
|
|
236
|
+
Get current logging context:
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
from mdb_engine.observability import get_logging_context
|
|
240
|
+
|
|
241
|
+
context = get_logging_context()
|
|
242
|
+
# {
|
|
243
|
+
# "timestamp": "2024-01-01T12:00:00",
|
|
244
|
+
# "correlation_id": "req-12345",
|
|
245
|
+
# "app_slug": "my_app",
|
|
246
|
+
# "user_id": "user123"
|
|
247
|
+
# }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Log Operations
|
|
251
|
+
|
|
252
|
+
Log operations with structured context:
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
from mdb_engine.observability import log_operation
|
|
256
|
+
import logging
|
|
257
|
+
|
|
258
|
+
logger = logging.getLogger(__name__)
|
|
259
|
+
|
|
260
|
+
# Log successful operation
|
|
261
|
+
log_operation(
|
|
262
|
+
logger=logger,
|
|
263
|
+
operation="process_document",
|
|
264
|
+
level=logging.INFO,
|
|
265
|
+
success=True,
|
|
266
|
+
duration_ms=125.5,
|
|
267
|
+
document_id="doc123"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Log failed operation
|
|
271
|
+
log_operation(
|
|
272
|
+
logger=logger,
|
|
273
|
+
operation="process_document",
|
|
274
|
+
level=logging.ERROR,
|
|
275
|
+
success=False,
|
|
276
|
+
error="timeout"
|
|
277
|
+
)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Health Checks
|
|
281
|
+
|
|
282
|
+
### MongoDB Health
|
|
283
|
+
|
|
284
|
+
Check MongoDB connection health:
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
from mdb_engine.observability import check_mongodb_health
|
|
288
|
+
|
|
289
|
+
# Check health
|
|
290
|
+
result = await check_mongodb_health(engine.mongo_client, timeout_seconds=5.0)
|
|
291
|
+
|
|
292
|
+
print(result.status) # "healthy", "degraded", or "unhealthy"
|
|
293
|
+
print(result.message) # Human-readable message
|
|
294
|
+
print(result.details) # Additional details
|
|
295
|
+
print(result.timestamp) # Check timestamp
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Engine Health
|
|
299
|
+
|
|
300
|
+
Check MongoDBEngine health:
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
from mdb_engine.observability import check_engine_health
|
|
304
|
+
|
|
305
|
+
result = await check_engine_health(engine)
|
|
306
|
+
|
|
307
|
+
print(result.status) # "healthy" or "unhealthy"
|
|
308
|
+
print(result.message)
|
|
309
|
+
print(result.details) # Includes app_count, etc.
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Connection Pool Health
|
|
313
|
+
|
|
314
|
+
Check connection pool health:
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from mdb_engine.observability import check_pool_health
|
|
318
|
+
|
|
319
|
+
result = await check_pool_health(engine.mongo_client)
|
|
320
|
+
|
|
321
|
+
print(result.status)
|
|
322
|
+
print(result.details) # Includes pool_size, active_connections, etc.
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### HealthChecker
|
|
326
|
+
|
|
327
|
+
Register and run multiple health checks:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from mdb_engine.observability import HealthChecker, check_mongodb_health, check_engine_health
|
|
331
|
+
|
|
332
|
+
checker = HealthChecker()
|
|
333
|
+
|
|
334
|
+
# Register checks
|
|
335
|
+
checker.register_check(lambda: check_mongodb_health(engine.mongo_client))
|
|
336
|
+
checker.register_check(lambda: check_engine_health(engine))
|
|
337
|
+
|
|
338
|
+
# Run all checks
|
|
339
|
+
results = await checker.check_all()
|
|
340
|
+
|
|
341
|
+
print(results["status"]) # Overall status
|
|
342
|
+
print(results["checks"]) # List of individual check results
|
|
343
|
+
print(results["timestamp"]) # Check timestamp
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Custom Health Checks
|
|
347
|
+
|
|
348
|
+
Create custom health checks:
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
from mdb_engine.observability import HealthCheckResult, HealthStatus
|
|
352
|
+
|
|
353
|
+
async def check_custom_service():
|
|
354
|
+
try:
|
|
355
|
+
# Check your service
|
|
356
|
+
response = await my_service.ping()
|
|
357
|
+
if response.ok:
|
|
358
|
+
return HealthCheckResult(
|
|
359
|
+
name="custom_service",
|
|
360
|
+
status=HealthStatus.HEALTHY,
|
|
361
|
+
message="Service is healthy",
|
|
362
|
+
details={"response_time_ms": response.elapsed.total_seconds() * 1000}
|
|
363
|
+
)
|
|
364
|
+
else:
|
|
365
|
+
return HealthCheckResult(
|
|
366
|
+
name="custom_service",
|
|
367
|
+
status=HealthStatus.DEGRADED,
|
|
368
|
+
message="Service responded with error",
|
|
369
|
+
details={"status_code": response.status_code}
|
|
370
|
+
)
|
|
371
|
+
except Exception as e:
|
|
372
|
+
return HealthCheckResult(
|
|
373
|
+
name="custom_service",
|
|
374
|
+
status=HealthStatus.UNHEALTHY,
|
|
375
|
+
message=f"Service check failed: {str(e)}"
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
# Register custom check
|
|
379
|
+
checker = HealthChecker()
|
|
380
|
+
checker.register_check(check_custom_service)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## API Reference
|
|
384
|
+
|
|
385
|
+
### Metrics
|
|
386
|
+
|
|
387
|
+
#### Functions
|
|
388
|
+
|
|
389
|
+
- `record_operation(operation_name, duration_ms, success=True, **tags)` - Record operation
|
|
390
|
+
- `get_metrics_collector()` - Get global metrics collector
|
|
391
|
+
|
|
392
|
+
#### MetricsCollector
|
|
393
|
+
|
|
394
|
+
- `record_operation(operation_name, duration_ms, success=True, **tags)` - Record operation
|
|
395
|
+
- `get_metrics(operation_name=None)` - Get metrics
|
|
396
|
+
- `get_summary()` - Get metrics summary
|
|
397
|
+
- `get_operation_count(operation_name)` - Get operation count
|
|
398
|
+
- `reset()` - Reset all metrics
|
|
399
|
+
|
|
400
|
+
### Logging
|
|
401
|
+
|
|
402
|
+
#### Functions
|
|
403
|
+
|
|
404
|
+
- `get_logger(name)` - Get contextual logger
|
|
405
|
+
- `set_correlation_id(correlation_id=None)` - Set correlation ID
|
|
406
|
+
- `get_correlation_id()` - Get current correlation ID
|
|
407
|
+
- `clear_correlation_id()` - Clear correlation ID
|
|
408
|
+
- `set_app_context(app_slug=None, **kwargs)` - Set app context
|
|
409
|
+
- `clear_app_context()` - Clear app context
|
|
410
|
+
- `get_logging_context()` - Get current logging context
|
|
411
|
+
- `log_operation(logger, operation, level, success, duration_ms, **context)` - Log operation
|
|
412
|
+
|
|
413
|
+
#### ContextualLoggerAdapter
|
|
414
|
+
|
|
415
|
+
Logger adapter that automatically adds context to log records.
|
|
416
|
+
|
|
417
|
+
### Health Checks
|
|
418
|
+
|
|
419
|
+
#### Functions
|
|
420
|
+
|
|
421
|
+
- `check_mongodb_health(mongo_client, timeout_seconds=5.0)` - Check MongoDB health
|
|
422
|
+
- `check_engine_health(engine)` - Check engine health
|
|
423
|
+
- `check_pool_health(mongo_client)` - Check connection pool health
|
|
424
|
+
|
|
425
|
+
#### HealthChecker
|
|
426
|
+
|
|
427
|
+
- `register_check(check_func)` - Register health check function
|
|
428
|
+
- `check_all()` - Run all registered checks
|
|
429
|
+
|
|
430
|
+
#### HealthCheckResult
|
|
431
|
+
|
|
432
|
+
- `name` - Check name
|
|
433
|
+
- `status` - HealthStatus enum value
|
|
434
|
+
- `message` - Human-readable message
|
|
435
|
+
- `details` - Additional details dict
|
|
436
|
+
- `timestamp` - Check timestamp
|
|
437
|
+
- `to_dict()` - Convert to dictionary
|
|
438
|
+
|
|
439
|
+
#### HealthStatus
|
|
440
|
+
|
|
441
|
+
Enum values:
|
|
442
|
+
- `HEALTHY` - Service is healthy
|
|
443
|
+
- `DEGRADED` - Service is degraded but functional
|
|
444
|
+
- `UNHEALTHY` - Service is unhealthy
|
|
445
|
+
- `UNKNOWN` - Health status unknown
|
|
446
|
+
|
|
447
|
+
## Integration Examples
|
|
448
|
+
|
|
449
|
+
### FastAPI Health Endpoint
|
|
450
|
+
|
|
451
|
+
```python
|
|
452
|
+
from fastapi import FastAPI
|
|
453
|
+
from mdb_engine.observability import HealthChecker, check_mongodb_health, check_engine_health
|
|
454
|
+
|
|
455
|
+
app = FastAPI()
|
|
456
|
+
|
|
457
|
+
@app.get("/health")
|
|
458
|
+
async def health_check():
|
|
459
|
+
checker = HealthChecker()
|
|
460
|
+
checker.register_check(lambda: check_mongodb_health(engine.mongo_client))
|
|
461
|
+
checker.register_check(lambda: check_engine_health(engine))
|
|
462
|
+
|
|
463
|
+
results = await checker.check_all()
|
|
464
|
+
return results
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Request Correlation
|
|
468
|
+
|
|
469
|
+
```python
|
|
470
|
+
from fastapi import Request
|
|
471
|
+
from mdb_engine.observability import set_correlation_id, get_logger
|
|
472
|
+
|
|
473
|
+
logger = get_logger(__name__)
|
|
474
|
+
|
|
475
|
+
@app.middleware("http")
|
|
476
|
+
async def correlation_middleware(request: Request, call_next):
|
|
477
|
+
# Set correlation ID from header or generate new one
|
|
478
|
+
correlation_id = request.headers.get("X-Correlation-ID")
|
|
479
|
+
set_correlation_id(correlation_id)
|
|
480
|
+
|
|
481
|
+
response = await call_next(request)
|
|
482
|
+
response.headers["X-Correlation-ID"] = get_correlation_id()
|
|
483
|
+
return response
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Metrics Endpoint
|
|
487
|
+
|
|
488
|
+
```python
|
|
489
|
+
from fastapi import FastAPI
|
|
490
|
+
from mdb_engine.observability import get_metrics_collector
|
|
491
|
+
|
|
492
|
+
app = FastAPI()
|
|
493
|
+
|
|
494
|
+
@app.get("/metrics")
|
|
495
|
+
async def get_metrics():
|
|
496
|
+
collector = get_metrics_collector()
|
|
497
|
+
return collector.get_summary()
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Best Practices
|
|
501
|
+
|
|
502
|
+
1. **Use correlation IDs** - Set correlation ID at request start for distributed tracing
|
|
503
|
+
2. **Set app context early** - Set app context as early as possible in request lifecycle
|
|
504
|
+
3. **Record all operations** - Record metrics for all significant operations
|
|
505
|
+
4. **Use structured logging** - Include structured context in logs for better searchability
|
|
506
|
+
5. **Monitor health regularly** - Set up periodic health checks
|
|
507
|
+
6. **Track error rates** - Monitor error rates in metrics
|
|
508
|
+
7. **Use appropriate log levels** - Use DEBUG for development, INFO for production
|
|
509
|
+
8. **Include context** - Always include relevant context (user_id, app_slug, etc.)
|
|
510
|
+
|
|
511
|
+
## Related Modules
|
|
512
|
+
|
|
513
|
+
- **`core/`** - MongoDBEngine integration
|
|
514
|
+
- **`database/`** - Database operation metrics
|
|
515
|
+
- **`auth/`** - Authentication event logging
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Observability components.
|
|
3
|
+
|
|
4
|
+
Provides structured logging, metrics collection, request tracing,
|
|
5
|
+
and health check capabilities.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .health import (HealthChecker, HealthCheckResult, HealthStatus,
|
|
9
|
+
check_engine_health, check_mongodb_health,
|
|
10
|
+
check_pool_health)
|
|
11
|
+
from .logging import (ContextualLoggerAdapter, clear_app_context,
|
|
12
|
+
clear_correlation_id, get_correlation_id, get_logger,
|
|
13
|
+
get_logging_context, log_operation, set_app_context,
|
|
14
|
+
set_correlation_id)
|
|
15
|
+
from .metrics import (MetricsCollector, OperationMetrics,
|
|
16
|
+
get_metrics_collector, record_operation, timed_operation)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
# Metrics
|
|
20
|
+
"MetricsCollector",
|
|
21
|
+
"OperationMetrics",
|
|
22
|
+
"get_metrics_collector",
|
|
23
|
+
"record_operation",
|
|
24
|
+
"timed_operation",
|
|
25
|
+
# Logging
|
|
26
|
+
"get_correlation_id",
|
|
27
|
+
"set_correlation_id",
|
|
28
|
+
"clear_correlation_id",
|
|
29
|
+
"set_app_context",
|
|
30
|
+
"clear_app_context",
|
|
31
|
+
"get_logging_context",
|
|
32
|
+
"ContextualLoggerAdapter",
|
|
33
|
+
"get_logger",
|
|
34
|
+
"log_operation",
|
|
35
|
+
# Health
|
|
36
|
+
"HealthStatus",
|
|
37
|
+
"HealthCheckResult",
|
|
38
|
+
"HealthChecker",
|
|
39
|
+
"check_mongodb_health",
|
|
40
|
+
"check_engine_health",
|
|
41
|
+
"check_pool_health",
|
|
42
|
+
]
|