impulse-telemetry 0.1.0__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.
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: impulse-telemetry
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Observability SDK for Impulse microservices
|
|
5
|
+
License: MIT
|
|
6
|
+
Keywords: observability,telemetry,opentelemetry,prometheus,fastapi,ml
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Topic :: System :: Monitoring
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: opentelemetry-sdk>=1.24
|
|
17
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.24
|
|
18
|
+
Requires-Dist: opentelemetry-propagator-b3>=1.24
|
|
19
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.45b0
|
|
20
|
+
Requires-Dist: opentelemetry-instrumentation-requests>=0.45b0
|
|
21
|
+
Requires-Dist: opentelemetry-instrumentation-httpx>=0.45b0
|
|
22
|
+
Requires-Dist: prometheus-client>=0.20
|
|
23
|
+
Requires-Dist: structlog>=24.0
|
|
24
|
+
Provides-Extra: extras
|
|
25
|
+
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.45b0; extra == "extras"
|
|
26
|
+
Requires-Dist: opentelemetry-instrumentation-redis>=0.45b0; extra == "extras"
|
|
27
|
+
Requires-Dist: opentelemetry-instrumentation-celery>=0.45b0; extra == "extras"
|
|
28
|
+
Provides-Extra: ml
|
|
29
|
+
Requires-Dist: pandas>=2.0; extra == "ml"
|
|
30
|
+
|
|
31
|
+
# impulse_telemetry
|
|
32
|
+
|
|
33
|
+
Observability SDK for Impulse microservices. One `init()` call wires up distributed tracing, Prometheus metrics, structured logging, and FastAPI middleware.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install impulse-telemetry
|
|
39
|
+
|
|
40
|
+
# With SQLAlchemy / Redis / Celery auto-instrumentation
|
|
41
|
+
pip install "impulse-telemetry[extras]"
|
|
42
|
+
|
|
43
|
+
# With ML data quality checks (pandas required)
|
|
44
|
+
pip install "impulse-telemetry[ml]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quickstart
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from fastapi import FastAPI
|
|
51
|
+
from impulse_telemetry import init
|
|
52
|
+
|
|
53
|
+
app = FastAPI()
|
|
54
|
+
init(app, service="my-service", version="1.0.0", env="production")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Every HTTP request now emits RED metrics, a distributed trace, and a structured JSON log line — automatically.
|
|
58
|
+
|
|
59
|
+
## `init()` parameters
|
|
60
|
+
|
|
61
|
+
| Parameter | Default | Description |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `app` | `None` | FastAPI app. Pass to enable HTTP middleware. |
|
|
64
|
+
| `service` | **required** | Service name — appears on all telemetry. |
|
|
65
|
+
| `version` | `"0.0.0"` | Semver string tagged on all telemetry. |
|
|
66
|
+
| `env` | `$ENV` | `"production"` \| `"staging"` \| `"dev"` |
|
|
67
|
+
| `otlp_endpoint` | `$OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP Collector gRPC address. |
|
|
68
|
+
| `prometheus_port` | `None` | Expose `/metrics` on this port (for workers without HTTP). |
|
|
69
|
+
| `log_level` | `"INFO"` | `"DEBUG"` \| `"INFO"` \| `"WARNING"` \| `"ERROR"` |
|
|
70
|
+
| `enable_ml` | `False` | Register ML-specific metric instruments. |
|
|
71
|
+
|
|
72
|
+
## Logging
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from impulse_telemetry.logging import get_logger
|
|
76
|
+
|
|
77
|
+
log = get_logger(__name__)
|
|
78
|
+
log.info("prediction_served", model_id="rec-v3", latency_ms=43)
|
|
79
|
+
# {"service":"my-service","trace_id":"abc..","event":"prediction_served","model_id":"rec-v3",...}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`trace_id` and `span_id` are injected automatically from the active OTEL span.
|
|
83
|
+
|
|
84
|
+
### Per-request context
|
|
85
|
+
|
|
86
|
+
Bind fields once per request — they appear on every subsequent log line for that request.
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from impulse_telemetry.logging import bind_request_context, clear_request_context
|
|
90
|
+
|
|
91
|
+
token = bind_request_context(user_id="usr_123", request_id="req_456")
|
|
92
|
+
log.info("doing_work") # user_id + request_id injected automatically
|
|
93
|
+
clear_request_context(token)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Metrics
|
|
97
|
+
|
|
98
|
+
Prometheus metrics are pre-registered and labeled with `service` and `env`.
|
|
99
|
+
|
|
100
|
+
### Automatic (via middleware)
|
|
101
|
+
|
|
102
|
+
| Metric | Type | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `http_requests_total` | Counter | Requests by route, method, status |
|
|
105
|
+
| `http_request_errors_total` | Counter | 4xx / 5xx responses |
|
|
106
|
+
| `http_request_duration_seconds` | Histogram | Request latency |
|
|
107
|
+
| `http_active_requests` | Gauge | In-flight requests |
|
|
108
|
+
|
|
109
|
+
### Manual
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from impulse_telemetry.metrics import get_metrics
|
|
113
|
+
|
|
114
|
+
m = get_metrics()
|
|
115
|
+
m.dependency_latency.labels(**m.labels(dependency="redis")).observe(elapsed)
|
|
116
|
+
m.dependency_errors.labels(**m.labels(dependency="redis")).inc()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Available instruments: `rate_limiter_hits`, `rate_limiter_remaining`, `dependency_latency`, `dependency_errors`, `queue_depth`, `circuit_breaker`.
|
|
120
|
+
|
|
121
|
+
## Tracing
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from impulse_telemetry.tracing import get_tracer, inject_headers
|
|
125
|
+
|
|
126
|
+
tracer = get_tracer(__name__)
|
|
127
|
+
|
|
128
|
+
with tracer.start_as_current_span("my_operation") as span:
|
|
129
|
+
span.set_attribute("key", "value")
|
|
130
|
+
headers = inject_headers({}) # propagate W3C traceparent to downstream
|
|
131
|
+
requests.get("http://other-service/api", headers=headers)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Auto-instrumented libraries (when installed): `requests`, `httpx`, `SQLAlchemy`, `Redis`, `Celery`.
|
|
135
|
+
|
|
136
|
+
## ML Monitoring
|
|
137
|
+
|
|
138
|
+
Enable at startup with `enable_ml=True`.
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from impulse_telemetry.ml import MLMonitor
|
|
142
|
+
|
|
143
|
+
monitor = MLMonitor(model_id="rec-v3", user_id=user_id)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Inference tracing
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
# Context manager
|
|
150
|
+
with monitor.inference(features=df) as span:
|
|
151
|
+
result = model.predict(df)
|
|
152
|
+
span.record_output(result)
|
|
153
|
+
|
|
154
|
+
# Decorator
|
|
155
|
+
@monitor.trace
|
|
156
|
+
def predict(features):
|
|
157
|
+
return model.predict(features)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Both record inference latency, error count, and run data quality checks (missing values, schema violations) automatically.
|
|
161
|
+
|
|
162
|
+
### Drift & performance metrics
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
# Call from batch evaluation jobs
|
|
166
|
+
monitor.record_drift("age", score=0.18, metric="psi")
|
|
167
|
+
monitor.record_performance(rmse=0.042, precision=0.87, recall=0.81)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### ML metric instruments
|
|
171
|
+
|
|
172
|
+
| Metric | Type | Description |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| `ml_inference_duration_seconds` | Histogram | Per-model inference latency |
|
|
175
|
+
| `ml_inference_requests_total` | Counter | Inference count |
|
|
176
|
+
| `ml_inference_errors_total` | Counter | Inference errors |
|
|
177
|
+
| `ml_missing_feature_rate` | Gauge | Missing values per column |
|
|
178
|
+
| `ml_schema_violations_total` | Counter | Schema violation count |
|
|
179
|
+
| `ml_feature_drift` | Gauge | Feature drift score |
|
|
180
|
+
| `ml_prediction_drift` | Gauge | Prediction drift score |
|
|
181
|
+
| `ml_rmse` | Gauge | Rolling RMSE |
|
|
182
|
+
| `ml_precision` | Gauge | Rolling precision |
|
|
183
|
+
| `ml_recall` | Gauge | Rolling recall |
|
|
184
|
+
|
|
185
|
+
## Background workers
|
|
186
|
+
|
|
187
|
+
For services without an HTTP server, expose metrics on a dedicated port:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
init(service="ingest-worker", prometheus_port=9090)
|
|
191
|
+
# Prometheus scrapes localhost:9090/metrics
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Environment variables
|
|
195
|
+
|
|
196
|
+
| Variable | Description |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP Collector gRPC address |
|
|
199
|
+
| `ENV` | Deployment environment (`production`, `staging`, `dev`) |
|
|
200
|
+
|
|
201
|
+
## See also
|
|
202
|
+
|
|
203
|
+
[examples.py](examples.py) — minimal, runnable code for every feature.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
impulse_telemetry-0.1.0.dist-info/METADATA,sha256=Anwqv1ZjId8n9OnQa5VPwWYljC-CzWWHFIu8g3n28Uc,6587
|
|
2
|
+
impulse_telemetry-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
3
|
+
impulse_telemetry-0.1.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
4
|
+
impulse_telemetry-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|