PECLibrary 0.7.0__tar.gz
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.
- peclibrary-0.7.0/ARCHITECTURE.md +484 -0
- peclibrary-0.7.0/MANIFEST.in +8 -0
- peclibrary-0.7.0/PKG-INFO +312 -0
- peclibrary-0.7.0/README.md +272 -0
- peclibrary-0.7.0/pyproject.toml +91 -0
- peclibrary-0.7.0/requirements.txt +13 -0
- peclibrary-0.7.0/setup.cfg +4 -0
- peclibrary-0.7.0/setup.py +10 -0
- peclibrary-0.7.0/src/PECLibrary/config/__init__.py +14 -0
- peclibrary-0.7.0/src/PECLibrary/config/defaults.py +59 -0
- peclibrary-0.7.0/src/PECLibrary/config/settings.py +178 -0
- peclibrary-0.7.0/src/PECLibrary/decorators/__init__.py +17 -0
- peclibrary-0.7.0/src/PECLibrary/decorators/capture.py +279 -0
- peclibrary-0.7.0/src/PECLibrary/models/__init__.py +0 -0
- peclibrary-0.7.0/src/PECLibrary/models/captured_models.py +206 -0
- peclibrary-0.7.0/src/PECLibrary/models/pydantic_compat.py +75 -0
- peclibrary-0.7.0/src/PECLibrary/services/__init__.py +38 -0
- peclibrary-0.7.0/src/PECLibrary/services/error_capture.py +297 -0
- peclibrary-0.7.0/src/PECLibrary/services/storage_service.py +365 -0
- peclibrary-0.7.0/src/PECLibrary/services/transport.py +444 -0
- peclibrary-0.7.0/src/PECLibrary/utils/__init__.py +40 -0
- peclibrary-0.7.0/src/PECLibrary/utils/context_managers.py +149 -0
- peclibrary-0.7.0/src/PECLibrary/utils/decorators.py +0 -0
- peclibrary-0.7.0/src/PECLibrary/utils/helpers.py +319 -0
- peclibrary-0.7.0/src/PECLibrary/utils/logger_config.py +68 -0
- peclibrary-0.7.0/src/PECLibrary/utils/monitor_errors.py +58 -0
- peclibrary-0.7.0/src/PECLibrary.egg-info/PKG-INFO +312 -0
- peclibrary-0.7.0/src/PECLibrary.egg-info/SOURCES.txt +30 -0
- peclibrary-0.7.0/src/PECLibrary.egg-info/dependency_links.txt +1 -0
- peclibrary-0.7.0/src/PECLibrary.egg-info/requires.txt +22 -0
- peclibrary-0.7.0/src/PECLibrary.egg-info/top_level.txt +1 -0
- peclibrary-0.7.0/src/__init__.py +41 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
# Palantir Event Capture - Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `palantir-event-capture` library provides a comprehensive event capture system for data pipelines. It follows a layered architecture with clear separation of concerns.
|
|
6
|
+
|
|
7
|
+
## Architecture Layers
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ Application Layer │
|
|
12
|
+
│ (User Functions/Pipelines) │
|
|
13
|
+
└───────────────────┬─────────────────────────────────────────┘
|
|
14
|
+
│
|
|
15
|
+
│ @capture_errors
|
|
16
|
+
│ @async_capture_errors
|
|
17
|
+
│ @retry_with_capture
|
|
18
|
+
│
|
|
19
|
+
┌───────────────────▼─────────────────────────────────────────┐
|
|
20
|
+
│ Decorator Layer │
|
|
21
|
+
│ (decorators/capture.py) │
|
|
22
|
+
│ - Function wrapping │
|
|
23
|
+
│ - Exception handling │
|
|
24
|
+
│ - Context extraction │
|
|
25
|
+
└───────────────────┬─────────────────────────────────────────┘
|
|
26
|
+
│
|
|
27
|
+
│ ErrorEvent
|
|
28
|
+
│
|
|
29
|
+
┌───────────────────▼─────────────────────────────────────────┐
|
|
30
|
+
│ Service Layer │
|
|
31
|
+
│ (services/error_capture.py) │
|
|
32
|
+
│ - Event validation │
|
|
33
|
+
│ - Metadata enrichment │
|
|
34
|
+
│ - Transport routing │
|
|
35
|
+
└───────────────────┬─────────────────────────────────────────┘
|
|
36
|
+
│
|
|
37
|
+
┌───────┴───────┐
|
|
38
|
+
│ │
|
|
39
|
+
┌───────────▼────┐ ┌──────▼──────────┐
|
|
40
|
+
│ Storage Layer │ │ Transport Layer │
|
|
41
|
+
│ (Optional) │ │ (Kafka/Custom) │
|
|
42
|
+
│ - Local cache │ │ - Kafka │
|
|
43
|
+
│ - Database │ │ - Console │
|
|
44
|
+
└────────────────┘ └─────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Core Components
|
|
48
|
+
|
|
49
|
+
### 1. Models Layer (`models/`)
|
|
50
|
+
|
|
51
|
+
**Purpose**: Define data structures and validation schemas
|
|
52
|
+
|
|
53
|
+
- `captured_models.py`: Pydantic models for events and configuration
|
|
54
|
+
- `ErrorEvent`: Standardized event structure
|
|
55
|
+
- `CaptureConfig`: Configuration for capture behavior
|
|
56
|
+
- `PipelineComponent`: Enum of supported components (expanded list)
|
|
57
|
+
- `Severity`: Event severity levels
|
|
58
|
+
- `EventType`: Types of events (ERROR, WARNING, INFO, SUCCESS)
|
|
59
|
+
|
|
60
|
+
**Key Features**:
|
|
61
|
+
|
|
62
|
+
- Pydantic validation (V1 and V2 compatible)
|
|
63
|
+
- UUID tracking prevents duplicate events
|
|
64
|
+
- Timezone-aware timestamps (UTC)
|
|
65
|
+
- JSON serialization support
|
|
66
|
+
|
|
67
|
+
### 2. Decorators Layer (`decorators/`)
|
|
68
|
+
|
|
69
|
+
**Purpose**: Provide easy-to-use function wrappers
|
|
70
|
+
|
|
71
|
+
- `capture.py`: Core decorator implementations
|
|
72
|
+
- `@capture_errors`: Sync function error capture
|
|
73
|
+
- `@async_capture_errors`: Async function error capture
|
|
74
|
+
- `@retry_with_capture`: Retry logic with capture
|
|
75
|
+
- `@capture_method_errors`: Class-level decoration
|
|
76
|
+
|
|
77
|
+
**Responsibilities**:
|
|
78
|
+
|
|
79
|
+
- Wrap user functions transparently
|
|
80
|
+
- Extract execution context (function name, file, line number)
|
|
81
|
+
- Handle exceptions and capture stack traces
|
|
82
|
+
- Pass events to service layer
|
|
83
|
+
|
|
84
|
+
### 3. Services Layer (`services/`)
|
|
85
|
+
|
|
86
|
+
**Purpose**: Core business logic and coordination
|
|
87
|
+
|
|
88
|
+
- `error_capture.py`: Main capture service
|
|
89
|
+
|
|
90
|
+
- Event creation and validation
|
|
91
|
+
- Frame analysis for context extraction
|
|
92
|
+
- Transport coordination
|
|
93
|
+
- Singleton pattern for global access
|
|
94
|
+
- `transport.py`: Event transport abstraction
|
|
95
|
+
|
|
96
|
+
- Base `Transport` interface
|
|
97
|
+
- `KafkaTransport`: Kafka producer wrapper
|
|
98
|
+
- `ConsoleTransport`: Console logging
|
|
99
|
+
- `MultiTransport`: Combine multiple transports
|
|
100
|
+
- `BackgroundTransport`: Async background worker for any transport
|
|
101
|
+
- `storage_service.py`: Optional event persistence
|
|
102
|
+
|
|
103
|
+
- Local file storage
|
|
104
|
+
- Database integration
|
|
105
|
+
- Event query and retrieval
|
|
106
|
+
|
|
107
|
+
**Key Design Patterns**:
|
|
108
|
+
|
|
109
|
+
- Singleton: Global service instance
|
|
110
|
+
- Strategy: Pluggable transport backends
|
|
111
|
+
- Chain of Responsibility: Multiple transports
|
|
112
|
+
|
|
113
|
+
### 4. Configuration Layer (`config/`)
|
|
114
|
+
|
|
115
|
+
**Purpose**: Centralized configuration management
|
|
116
|
+
|
|
117
|
+
- `defaults.py`: Default configuration values
|
|
118
|
+
- `settings.py`: Configuration loading and validation
|
|
119
|
+
- Environment variable support
|
|
120
|
+
- Programmatic configuration
|
|
121
|
+
- Config validation
|
|
122
|
+
|
|
123
|
+
**Configuration Sources** (priority order):
|
|
124
|
+
|
|
125
|
+
1. Programmatic configuration
|
|
126
|
+
2. Environment variables
|
|
127
|
+
3. Default values
|
|
128
|
+
|
|
129
|
+
### 5. Utilities Layer (`utils/`)
|
|
130
|
+
|
|
131
|
+
**Purpose**: Reusable helper functions
|
|
132
|
+
|
|
133
|
+
- `helpers.py`: Common utility functions
|
|
134
|
+
|
|
135
|
+
- Frame analysis
|
|
136
|
+
- Stack trace formatting
|
|
137
|
+
- Type conversions
|
|
138
|
+
- `context_managers.py`: Context manager implementations
|
|
139
|
+
|
|
140
|
+
- `capture_context`: Capture errors in code blocks
|
|
141
|
+
- Automatic cleanup and error propagation
|
|
142
|
+
- `logging.py`: Logging setup and configuration
|
|
143
|
+
|
|
144
|
+
- `structured_logging`: Loguru integration
|
|
145
|
+
- `monitor_errors.py`: Simple Kafka event monitoring script
|
|
146
|
+
|
|
147
|
+
## Data Flow
|
|
148
|
+
|
|
149
|
+
### 1. Normal Execution Flow
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
User Function
|
|
153
|
+
│
|
|
154
|
+
│ Decorated with @capture_errors
|
|
155
|
+
│
|
|
156
|
+
▼
|
|
157
|
+
Decorator intercepts execution
|
|
158
|
+
│
|
|
159
|
+
│ try: execute function
|
|
160
|
+
│
|
|
161
|
+
▼
|
|
162
|
+
Function executes successfully
|
|
163
|
+
│
|
|
164
|
+
▼
|
|
165
|
+
Return result to user
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 2. Error Capture Flow
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
User Function raises Exception
|
|
172
|
+
│
|
|
173
|
+
▼
|
|
174
|
+
Decorator catches exception
|
|
175
|
+
│
|
|
176
|
+
├─► Extract frame info (file, line, function)
|
|
177
|
+
├─► Extract stack trace
|
|
178
|
+
└─► Create CaptureConfig
|
|
179
|
+
│
|
|
180
|
+
▼
|
|
181
|
+
ErrorCaptureService.capture_exception()
|
|
182
|
+
│
|
|
183
|
+
├─► Validate exception type
|
|
184
|
+
├─► Enrich metadata
|
|
185
|
+
├─► Create ErrorEvent (Pydantic)
|
|
186
|
+
│
|
|
187
|
+
▼
|
|
188
|
+
For each registered transport:
|
|
189
|
+
│
|
|
190
|
+
├─► ConsoleTransport.send()
|
|
191
|
+
│ └─► Log to console
|
|
192
|
+
│
|
|
193
|
+
├─► KafkaTransport.send()
|
|
194
|
+
│ └─► Producer.send(topic, event)
|
|
195
|
+
│
|
|
196
|
+
└─► CustomTransport.send()
|
|
197
|
+
└─► Your custom logic
|
|
198
|
+
│
|
|
199
|
+
▼
|
|
200
|
+
Reraise exception (if configured)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 3. Retry Flow
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
User Function (with @retry_with_capture)
|
|
207
|
+
│
|
|
208
|
+
▼
|
|
209
|
+
Attempt 1: Exception raised
|
|
210
|
+
│
|
|
211
|
+
├─► Capture event (LOW severity)
|
|
212
|
+
├─► Sleep delay (e.g., 1s)
|
|
213
|
+
│
|
|
214
|
+
▼
|
|
215
|
+
Attempt 2: Exception raised
|
|
216
|
+
│
|
|
217
|
+
├─► Capture event (LOW severity)
|
|
218
|
+
├─► Sleep delay * backoff (e.g., 2s)
|
|
219
|
+
│
|
|
220
|
+
▼
|
|
221
|
+
Attempt 3 (final): Exception raised
|
|
222
|
+
│
|
|
223
|
+
├─► Capture event (HIGH severity)
|
|
224
|
+
├─► Send to transport
|
|
225
|
+
│
|
|
226
|
+
▼
|
|
227
|
+
Raise exception to caller
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Event Model Schema
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
ErrorEvent:
|
|
234
|
+
id: UUID # Unique event identifier
|
|
235
|
+
event_type: EventType # ERROR, WARNING, INFO, SUCCESS
|
|
236
|
+
|
|
237
|
+
# Pipeline Context
|
|
238
|
+
pipeline_name: Optional[str] # Name of the pipeline
|
|
239
|
+
engine_name: Optional[str] # Processing engine
|
|
240
|
+
|
|
241
|
+
# Component Info
|
|
242
|
+
component: PipelineComponent # KAFKA, POSTGRES, etc.
|
|
243
|
+
component_name: Optional[str] # Custom component name
|
|
244
|
+
severity: Severity # CRITICAL, HIGH, MEDIUM, LOW
|
|
245
|
+
|
|
246
|
+
# Error Details
|
|
247
|
+
message: str # Human-readable message
|
|
248
|
+
timestamp: float # Unix timestamp
|
|
249
|
+
timestamp_iso: str # ISO 8601 format
|
|
250
|
+
error_type: str # Exception class name
|
|
251
|
+
stack_trace: Optional[str] # Full stack trace
|
|
252
|
+
|
|
253
|
+
# Execution Context
|
|
254
|
+
function_name: Optional[str] # Function where error occurred
|
|
255
|
+
file_path: Optional[str] # File path
|
|
256
|
+
line_number: Optional[int] # Line number
|
|
257
|
+
metadata: Dict[str, Any] # Custom metadata
|
|
258
|
+
|
|
259
|
+
# Resolution Tracking
|
|
260
|
+
resolved: bool # Resolution status
|
|
261
|
+
resolved_at: Optional[float] # Resolution timestamp
|
|
262
|
+
resolved_by: Optional[str] # Who resolved it
|
|
263
|
+
resolution_notes: Optional[str] # Resolution notes
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Transport Architecture
|
|
267
|
+
|
|
268
|
+
### Base Transport Interface
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
class Transport(ABC):
|
|
272
|
+
@abstractmethod
|
|
273
|
+
def send(self, event: ErrorEvent) -> bool:
|
|
274
|
+
"""Send event to destination"""
|
|
275
|
+
pass
|
|
276
|
+
|
|
277
|
+
@abstractmethod
|
|
278
|
+
def close(self) -> None:
|
|
279
|
+
"""Cleanup resources"""
|
|
280
|
+
pass
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Kafka Transport
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
KafkaTransport:
|
|
287
|
+
- Lazy connection (on first send)
|
|
288
|
+
- Automatic reconnection
|
|
289
|
+
- Topic routing by severity
|
|
290
|
+
- Batch sending support
|
|
291
|
+
- Compression (optional)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Multi Transport
|
|
295
|
+
|
|
296
|
+
Combine multiple transports:
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
MultiTransport([
|
|
300
|
+
ConsoleTransport(),
|
|
301
|
+
BackgroundTransport(KafkaTransport()),
|
|
302
|
+
CustomDatabaseTransport()
|
|
303
|
+
])
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Background Transport
|
|
307
|
+
|
|
308
|
+
Wraps any other transport to send events asynchronously using a worker thread and queue:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
transport = BackgroundTransport(
|
|
312
|
+
base_transport=KafkaTransport(),
|
|
313
|
+
max_queue_size=1000
|
|
314
|
+
)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Configuration System
|
|
318
|
+
|
|
319
|
+
### Environment Variables
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Kafka
|
|
323
|
+
KAFKA_BOOTSTRAP_SERVERS_RCA=localhost:9092
|
|
324
|
+
KAFKA_EVENT_TOPIC_RCA=rca.events
|
|
325
|
+
KAFKA_ENABLED_RCA=true
|
|
326
|
+
KAFKA_COMPRESSION_RCA=gzip
|
|
327
|
+
|
|
328
|
+
# Behavior
|
|
329
|
+
LOG_LEVEL=INFO
|
|
330
|
+
LOG_TO_CONSOLE=true
|
|
331
|
+
SEND_TO_TRANSPORT=true
|
|
332
|
+
DEFAULT_SEVERITY=MEDIUM
|
|
333
|
+
ENABLE_STACK_TRACES=true
|
|
334
|
+
USE_BACKGROUND_TRANSPORT=false
|
|
335
|
+
|
|
336
|
+
# Retry
|
|
337
|
+
DEFAULT_MAX_RETRIES=3
|
|
338
|
+
DEFAULT_RETRY_DELAY=1.0
|
|
339
|
+
DEFAULT_RETRY_BACKOFF=2.0
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Configuration Priority
|
|
343
|
+
|
|
344
|
+
1. **Decorator arguments** (highest priority)
|
|
345
|
+
2. **Programmatic configuration** via `configure()`
|
|
346
|
+
3. **Environment variables**
|
|
347
|
+
4. **Default values** (lowest priority)
|
|
348
|
+
|
|
349
|
+
## Error Handling Philosophy
|
|
350
|
+
|
|
351
|
+
### 1. Fail-Safe Design
|
|
352
|
+
|
|
353
|
+
The library never causes application failures:
|
|
354
|
+
|
|
355
|
+
- Capture errors are logged, not raised
|
|
356
|
+
- Transport failures are silent
|
|
357
|
+
- Invalid configuration falls back to defaults
|
|
358
|
+
|
|
359
|
+
### 2. Zero Performance Impact
|
|
360
|
+
|
|
361
|
+
- Minimal overhead on success path
|
|
362
|
+
- Lazy initialization
|
|
363
|
+
- Async transport (optional)
|
|
364
|
+
- Batch sending (optional)
|
|
365
|
+
|
|
366
|
+
### 3. Rich Context
|
|
367
|
+
|
|
368
|
+
Capture maximum context without user effort:
|
|
369
|
+
|
|
370
|
+
- Automatic stack traces
|
|
371
|
+
- Function metadata
|
|
372
|
+
- Frame analysis
|
|
373
|
+
- Custom metadata support
|
|
374
|
+
|
|
375
|
+
## Extension Points
|
|
376
|
+
|
|
377
|
+
### 1. Custom Transport
|
|
378
|
+
|
|
379
|
+
```python
|
|
380
|
+
class MyTransport(Transport):
|
|
381
|
+
def send(self, event: ErrorEvent) -> bool:
|
|
382
|
+
# Your logic here
|
|
383
|
+
return True
|
|
384
|
+
|
|
385
|
+
def close(self) -> None:
|
|
386
|
+
# Cleanup
|
|
387
|
+
pass
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### 2. Custom Storage
|
|
391
|
+
|
|
392
|
+
```python
|
|
393
|
+
class MyStorage(StorageService):
|
|
394
|
+
def save(self, event: ErrorEvent) -> None:
|
|
395
|
+
# Your storage logic
|
|
396
|
+
pass
|
|
397
|
+
|
|
398
|
+
def query(self, filters: dict) -> List[ErrorEvent]:
|
|
399
|
+
# Your query logic
|
|
400
|
+
pass
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### 3. Event Enrichment
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
def enrich_event(event: ErrorEvent) -> ErrorEvent:
|
|
407
|
+
event.metadata['hostname'] = socket.gethostname()
|
|
408
|
+
event.metadata['env'] = os.getenv('ENV')
|
|
409
|
+
return event
|
|
410
|
+
|
|
411
|
+
service = get_capture_service()
|
|
412
|
+
service.add_enricher(enrich_event)
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Performance Considerations
|
|
416
|
+
|
|
417
|
+
### Memory
|
|
418
|
+
|
|
419
|
+
- Events are created on-demand
|
|
420
|
+
- UUID registry cleaned periodically
|
|
421
|
+
- Stack traces truncated (configurable)
|
|
422
|
+
- Metadata size limits (recommended)
|
|
423
|
+
|
|
424
|
+
### Latency
|
|
425
|
+
|
|
426
|
+
- Decorator overhead: ~0.1ms (no error)
|
|
427
|
+
- Event creation: ~0.5ms
|
|
428
|
+
- Kafka send (async): ~1-5ms
|
|
429
|
+
- Synchronous send: ~10-50ms (depends on network)
|
|
430
|
+
|
|
431
|
+
### Optimization Tips
|
|
432
|
+
|
|
433
|
+
1. Use async transports for production
|
|
434
|
+
2. Batch events when possible
|
|
435
|
+
3. Disable stack traces for low-severity events
|
|
436
|
+
4. Set appropriate metadata size limits
|
|
437
|
+
5. Use connection pooling for transports
|
|
438
|
+
|
|
439
|
+
## Testing Strategy
|
|
440
|
+
|
|
441
|
+
### Unit Tests
|
|
442
|
+
|
|
443
|
+
- Model validation
|
|
444
|
+
- Decorator behavior
|
|
445
|
+
- Service logic
|
|
446
|
+
- Transport implementations
|
|
447
|
+
|
|
448
|
+
### Integration Tests
|
|
449
|
+
|
|
450
|
+
- End-to-end capture flow
|
|
451
|
+
- Kafka integration
|
|
452
|
+
- Configuration loading
|
|
453
|
+
- Error scenarios
|
|
454
|
+
|
|
455
|
+
### Mock Support
|
|
456
|
+
|
|
457
|
+
All external dependencies can be mocked:
|
|
458
|
+
|
|
459
|
+
- Kafka producer
|
|
460
|
+
- File system
|
|
461
|
+
- Database connections
|
|
462
|
+
|
|
463
|
+
## Security Considerations
|
|
464
|
+
|
|
465
|
+
### PII Protection
|
|
466
|
+
|
|
467
|
+
- Avoid capturing sensitive data in metadata
|
|
468
|
+
- Sanitize stack traces (optional)
|
|
469
|
+
- Redact patterns (configurable)
|
|
470
|
+
|
|
471
|
+
### Authentication
|
|
472
|
+
|
|
473
|
+
- Kafka SASL support
|
|
474
|
+
- Custom transport auth
|
|
475
|
+
- Certificate-based auth
|
|
476
|
+
|
|
477
|
+
## Future Enhancements
|
|
478
|
+
|
|
479
|
+
1. **Metrics**: Prometheus/StatsD integration
|
|
480
|
+
2. **Tracing**: OpenTelemetry support
|
|
481
|
+
3. **Sampling**: Intelligent event sampling
|
|
482
|
+
4. **Aggregation**: Event deduplication
|
|
483
|
+
5. **Alerting**: Direct alerting integration
|
|
484
|
+
6. **Dashboard**: Real-time event dashboard
|