|
1 | | -# Observability Module |
| 1 | +# List of source files stored in `src/observability` directory |
2 | 2 |
|
3 | | -This module provides telemetry capabilities for sending inference events to external systems like Splunk HEC. |
| 3 | +## [__init__.py](__init__.py) |
| 4 | +Observability module for telemetry and event collection. |
4 | 5 |
|
5 | | -## Architecture |
| 6 | +## [splunk.py](splunk.py) |
| 7 | +Async Splunk HEC client for sending telemetry events. |
6 | 8 |
|
7 | | -``` |
8 | | -observability/ |
9 | | -├── __init__.py # Public API exports |
10 | | -├── splunk.py # Async Splunk HEC client |
11 | | -└── formats/ |
12 | | - ├── __init__.py # Format exports |
13 | | - └── rlsapi.py # rlsapi v1 event format |
14 | | -``` |
15 | | - |
16 | | -## Usage |
17 | | - |
18 | | -### Sending Events to Splunk |
19 | | - |
20 | | -```python |
21 | | -from fastapi import BackgroundTasks |
22 | | -from observability import send_splunk_event, build_inference_event, InferenceEventData |
23 | | - |
24 | | -# Build the event payload |
25 | | -event_data = InferenceEventData( |
26 | | - question="How do I configure SSH?", |
27 | | - response="To configure SSH...", |
28 | | - inference_time=2.34, |
29 | | - model="granite-3-8b-instruct", |
30 | | - org_id="12345678", |
31 | | - system_id="abc-def-123", |
32 | | - request_id="req_xyz789", |
33 | | - cla_version="CLA/0.6.0rc2", |
34 | | - system_os="RHEL", |
35 | | - system_version="9.3", |
36 | | - system_arch="x86_64", |
37 | | -) |
38 | | - |
39 | | -event = build_inference_event(event_data) |
40 | | - |
41 | | -# Queue for async sending via BackgroundTasks |
42 | | -background_tasks.add_task(send_splunk_event, event, "infer_with_llm") |
43 | | -``` |
44 | | - |
45 | | -### Source Types |
46 | | - |
47 | | -| Source Type | Description | |
48 | | -|-------------|-------------| |
49 | | -| `infer_with_llm` | Successful inference requests | |
50 | | -| `infer_error` | Failed inference requests | |
51 | | - |
52 | | -## Creating Custom Event Formats |
53 | | - |
54 | | -To add a new event format for a different endpoint: |
55 | | - |
56 | | -1. Create a new module in `observability/formats/`: |
57 | | - |
58 | | -```python |
59 | | -# observability/formats/my_endpoint.py |
60 | | -from dataclasses import dataclass |
61 | | -from typing import Any |
62 | | - |
63 | | -@dataclass |
64 | | -class MyEventData: |
65 | | - field1: str |
66 | | - field2: int |
67 | | - |
68 | | -def build_my_event(data: MyEventData) -> dict[str, Any]: |
69 | | - return { |
70 | | - "field1": data.field1, |
71 | | - "field2": data.field2, |
72 | | - } |
73 | | -``` |
74 | | - |
75 | | -2. Export from `observability/formats/__init__.py` |
76 | | - |
77 | | -3. Use with `send_splunk_event()`: |
78 | | - |
79 | | -```python |
80 | | -from observability import send_splunk_event |
81 | | -from observability.formats.my_endpoint import build_my_event, MyEventData |
82 | | - |
83 | | -event = build_my_event(MyEventData(field1="value", field2=42)) |
84 | | -background_tasks.add_task(send_splunk_event, event, "my_sourcetype") |
85 | | -``` |
86 | | - |
87 | | -## Graceful Degradation |
88 | | - |
89 | | -The Splunk client is designed to never block or fail the main request: |
90 | | - |
91 | | -- Skips sending when Splunk is disabled or not configured |
92 | | -- Logs warnings on HTTP errors (does not raise exceptions) |
93 | | -- Token is read from file on each request (supports rotation without restart) |
94 | | - |
95 | | -## Configuration |
96 | | - |
97 | | -See [docs/splunk.md](../../docs/splunk.md) for configuration options. |
0 commit comments