fast-telemetry 0.0.0__tar.gz → 0.0.2__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.
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/.gitlab-ci.yml +4 -0
- fast_telemetry-0.0.2/PKG-INFO +212 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/fastapi/requirements.txt +1 -1
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/requirements.txt +1 -1
- fast_telemetry-0.0.2/examples/app_example/apps/worker/requirements.txt +3 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/pyproject.toml +4 -0
- fast_telemetry-0.0.2/src/fast_telemetry/_version.py +34 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/integrations/fastapi.py +3 -1
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/integrations/faststream.py +13 -13
- fast_telemetry-0.0.2/src/fast_telemetry.egg-info/PKG-INFO +212 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry.egg-info/SOURCES.txt +1 -3
- fast_telemetry-0.0.0/PKG-INFO +0 -11
- fast_telemetry-0.0.0/examples/app_example/apps/fastapi/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
- fast_telemetry-0.0.0/examples/app_example/apps/faststream/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
- fast_telemetry-0.0.0/examples/app_example/apps/worker/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
- fast_telemetry-0.0.0/examples/app_example/apps/worker/requirements.txt +0 -3
- fast_telemetry-0.0.0/src/fast_telemetry.egg-info/PKG-INFO +0 -11
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/.gitignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/README.md +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/.gitignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/.gitignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/_grafana-data/grafana.db +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/fastapi/.dockerignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/fastapi/Dockerfile +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/fastapi/main.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/.dockerignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/Dockerfile +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/main.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/.dockerignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/Dockerfile +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/main.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/requirements.txt +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/worker/.dockerignore +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/worker/Dockerfile +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/worker/main.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/docker-compose.yaml +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/env.example +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/prometheus/prometheus.yaml +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/dishka_example.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/grafana/fastapi.json +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/grafana/faststream.json +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/grafana/fasttelemetry.json +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/requirements.txt +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/setup.cfg +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/__init__.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/__init__.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/core.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/integrations/__init__.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry/integrations/worker.py +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry.egg-info/dependency_links.txt +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry.egg-info/requires.txt +0 -0
- {fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry.egg-info/top_level.txt +0 -0
|
@@ -3,6 +3,7 @@ stages:
|
|
|
3
3
|
- deploy
|
|
4
4
|
|
|
5
5
|
variables:
|
|
6
|
+
GIT_DEPTH: 0
|
|
6
7
|
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
7
8
|
|
|
8
9
|
cache:
|
|
@@ -14,6 +15,8 @@ build_package:
|
|
|
14
15
|
image: python:3.11
|
|
15
16
|
script:
|
|
16
17
|
- pip install build
|
|
18
|
+
- echo "Проверяем, видит ли git теги:"
|
|
19
|
+
- git describe --tags || echo "Git не видит тегов!"
|
|
17
20
|
- python -m build
|
|
18
21
|
artifacts:
|
|
19
22
|
paths:
|
|
@@ -28,6 +31,7 @@ upload_to_pypi:
|
|
|
28
31
|
needs: ["build_package"]
|
|
29
32
|
script:
|
|
30
33
|
- pip install twine
|
|
34
|
+
- twine check dist/*
|
|
31
35
|
- twine upload dist/*
|
|
32
36
|
only:
|
|
33
37
|
- tags
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fast-telemetry
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Internal standardized metrics library
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: prometheus-client~=0.21.0
|
|
8
|
+
Provides-Extra: web
|
|
9
|
+
Requires-Dist: fastapi~=0.115.0; extra == "web"
|
|
10
|
+
Requires-Dist: prometheus-fastapi-instrumentator~=7.1.0; extra == "web"
|
|
11
|
+
Provides-Extra: stream
|
|
12
|
+
Requires-Dist: faststream~=0.6.0; extra == "stream"
|
|
13
|
+
|
|
14
|
+
# 📊 fast-telemetry
|
|
15
|
+
|
|
16
|
+
**Production-ready Prometheus integration for FastAPI, FastStream, and Python Workers.**
|
|
17
|
+
|
|
18
|
+
`fast-telemetry` — это "клей", который объединяет метрики вашего микросервиса в единый стандарт. Библиотека навязывает
|
|
19
|
+
правильные практики (единые метки `env`, `version`, `service`) и предоставляет удобные абстракции для HTTP-сервисов,
|
|
20
|
+
обработчиков очередей и периодических задач.
|
|
21
|
+
|
|
22
|
+
### 🌟 Особенности
|
|
23
|
+
|
|
24
|
+
* **Единый стандарт:** Автоматически добавляет метки `service`, `env`, `version` ко всем метрикам.
|
|
25
|
+
* **FastAPI:** Автоконфигурация через `Instrumentator`, исключение служебных ручек (`/metrics` и других переданных).
|
|
26
|
+
* **FastStream:** Поддержка RabbitMQ, Kafka, Redis, NATS "из коробки" (автоопределение драйвера).
|
|
27
|
+
* **Workers & Cron:**
|
|
28
|
+
* Поддержка Long-running процессов (daemon thread server).
|
|
29
|
+
* Поддержка Batch-jobs (Pushgateway) через **универсальный контекстный менеджер** (sync/async).
|
|
30
|
+
* **Декораторы:** Удобные `@measure_task` и `@track_exception`, которые сами понимают, синхронная функция или
|
|
31
|
+
асинхронная.
|
|
32
|
+
* **Безопасность типов:** Полная типизация (mypy strict).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### 📦 Установка
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install fast-telemetry
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### 🚀 Quick Start
|
|
45
|
+
|
|
46
|
+
#### 1. Core Concepts
|
|
47
|
+
|
|
48
|
+
В основе всего лежит класс `PrometheusMetrics` (или его наследники). Вы инициализируете его один раз при старте
|
|
49
|
+
приложения.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from fast_telemetry import PrometheusMetrics
|
|
53
|
+
|
|
54
|
+
metrics = PrometheusMetrics(
|
|
55
|
+
service_name="payment_service",
|
|
56
|
+
version="1.0.4",
|
|
57
|
+
env="production"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Использование в коде
|
|
61
|
+
metrics.inc_error("validation_error")
|
|
62
|
+
|
|
63
|
+
with metrics.timer("db_query", long_task=False):
|
|
64
|
+
# ... logic ...
|
|
65
|
+
pass
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### 2. FastAPI Integration
|
|
69
|
+
|
|
70
|
+
Автоматически добавляет эндпоинт `/metrics` и собирает RED-метрики (Requests, Errors, Duration).
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from fastapi import FastAPI
|
|
74
|
+
from fast_telemetry import PrometheusMetrics, setup_fastapi_metrics
|
|
75
|
+
|
|
76
|
+
app = FastAPI()
|
|
77
|
+
metrics = PrometheusMetrics(service_name="api_core", env="dev", version="1.2.3")
|
|
78
|
+
|
|
79
|
+
# Настройка (исключает /docs, /openapi.json + readiness)
|
|
80
|
+
setup_fastapi_metrics(app, metrics, excluded_routes=["/readiness"])
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@app.get("/")
|
|
84
|
+
@metrics.measure_task("root_handler", long_task=False)
|
|
85
|
+
async def root():
|
|
86
|
+
return {"status": "ok"}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 3. FastStream Integration
|
|
90
|
+
|
|
91
|
+
Поддерживает автоматическое определение брокера (Rabbit/Kafka/Redis/NATS) и инъекцию middleware.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from faststream.asgi import AsgiFastStream, make_ping_asgi
|
|
95
|
+
from faststream.rabbit import RabbitBroker
|
|
96
|
+
from fast_telemetry import PrometheusMetrics, setup_faststream_metrics
|
|
97
|
+
|
|
98
|
+
broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
|
|
99
|
+
app = AsgiFastStream(
|
|
100
|
+
broker,
|
|
101
|
+
asgi_routes=[
|
|
102
|
+
("/health", make_ping_asgi(broker))
|
|
103
|
+
],
|
|
104
|
+
lifespan=None,
|
|
105
|
+
asyncapi_path="/docs",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
metrics = PrometheusMetrics(service_name="worker_core", env="dev")
|
|
109
|
+
setup_faststream_metrics(app, metrics)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### 4. Workers & Cron Jobs
|
|
113
|
+
|
|
114
|
+
Для скриптов без веб-сервера. Поддерживает два режима:
|
|
115
|
+
|
|
116
|
+
1. **Daemon Server** (для бесконечных циклов).
|
|
117
|
+
2. **Push Gateway** (для скриптов, запускаемых по расписанию).
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import asyncio
|
|
121
|
+
from fast_telemetry import WorkerMetrics
|
|
122
|
+
|
|
123
|
+
metrics = WorkerMetrics(service_name="nightly_job", env="prod")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# --- Вариант А: Long-running worker ---
|
|
127
|
+
def run_worker():
|
|
128
|
+
# Запускает HTTP сервер в фоновом потоке
|
|
129
|
+
metrics.start_server(port=8000)
|
|
130
|
+
while True:
|
|
131
|
+
process_data()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# --- Вариант Б: Batch Job (Cron) ---
|
|
135
|
+
# Универсальный трекер (работает и с with, и с async with)
|
|
136
|
+
async def run_batch_job():
|
|
137
|
+
# Автоматически отправит метрики в Pushgateway при выходе из блока
|
|
138
|
+
# Группирует по instance_id, чтобы воркеры не перезатирали друг друга
|
|
139
|
+
async with metrics.track_job(gateway_url="http://pushgateway:9091", timeout=5.0):
|
|
140
|
+
await do_heavy_calculation()
|
|
141
|
+
metrics.inc_error("calc_error")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
asyncio.run(run_batch_job())
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### 🛠 Декораторы
|
|
151
|
+
|
|
152
|
+
Библиотека предоставляет "умные" декораторы, которые работают с sync и async функциями прозрачно.
|
|
153
|
+
|
|
154
|
+
**`@track_exception()`**
|
|
155
|
+
Считает количество исключений. Использует имя класса исключения как метку.
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
@metrics.track_exception
|
|
159
|
+
async def dangerous_operation():
|
|
160
|
+
raise ValueError("Oops")
|
|
161
|
+
# Увеличит счетчик fasttelemetry_business_errors_total{error_type="ValueError", ...}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**`@measure_task("task_name")`**
|
|
165
|
+
Замеряет время выполнения функции (Histogram).
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
@metrics.measure_task("image_processing")
|
|
169
|
+
def process_image(img):
|
|
170
|
+
time.sleep(1)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### 📊 Grafana & Prometheus
|
|
176
|
+
|
|
177
|
+
Библиотека экспортирует следующие базовые метрики:
|
|
178
|
+
|
|
179
|
+
1. **`fasttelemetry_app_info`** (Gauge) — всегда `1`. Содержит метки `version`, `env`, `service`. Используйте для
|
|
180
|
+
аннотаций деплоев на графиках.
|
|
181
|
+
2. **`fasttelemetry_business_errors_total`** (Counter) — счетчик ошибок бизнес-логики.
|
|
182
|
+
3. **`fasttelemetry_task_processing_seconds`** (Histogram) — время выполнения внутренних задач.
|
|
183
|
+
4. **`http_requests_...`** — [fastapi.json](grafana/fastapi.json) (если используется FastAPI).
|
|
184
|
+
5. **`faststream_...`** — [faststream.json](grafana/faststream.json) (если используется FastStream).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 📈 Base Metrics & Grafana Dashboard
|
|
189
|
+
|
|
190
|
+
Библиотека предоставляет "Ready-to-use" набор метрик
|
|
191
|
+
|
|
192
|
+
### Metric Schema
|
|
193
|
+
|
|
194
|
+
| Metric Name | Type | Labels | Description |
|
|
195
|
+
|----------------------------------------------|-----------|-----------------------------|----------------------------------------------------------------------------------|
|
|
196
|
+
| `fasttelemetry_app_info` | Gauge | `env`, `service`, `version` | Информация о запущенном инстансе. Всегда `1`. |
|
|
197
|
+
| `fasttelemetry_business_errors_total` | Counter | `error_type` | Количество ошибок бизнес-логики (пойманных через `track_exception` или вручную). |
|
|
198
|
+
| `fasttelemetry_task_processing_seconds` | Histogram | `task_type` | Время выполнения задач (обернутых в `@measure_task` или `timer`). |
|
|
199
|
+
| `fasttelemetry_long_task_processing_seconds` | Histogram | `task_type` | Время выполнения долгих задач (обернутых в `@measure_task` или `timer`). |
|
|
200
|
+
|
|
201
|
+
### ⚙️ Configuration
|
|
202
|
+
|
|
203
|
+
Вы можете передать параметры явно в `__init__` или использовать переменные окружения:
|
|
204
|
+
|
|
205
|
+
| Environment Variable | Description | Default |
|
|
206
|
+
|----------------------|----------------------------|-----------|
|
|
207
|
+
| `APP_ENV` | Окружение (prod/dev/stage) | `dev` |
|
|
208
|
+
| `APP_VERSION` | Версия приложения | `unknown` |
|
|
209
|
+
|
|
210
|
+
### 🖥️ Grafana Dashboard JSON
|
|
211
|
+
|
|
212
|
+
Дашборды можно импортировать из [папки](grafana)
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
requires = ["setuptools>=64", "setuptools-scm>=8"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
|
+
[tool.setuptools_scm]
|
|
6
|
+
version_file = "src/fast_telemetry/_version.py"
|
|
7
|
+
|
|
5
8
|
[project]
|
|
6
9
|
name = "fast-telemetry"
|
|
7
10
|
dynamic = ["version"]
|
|
11
|
+
readme = "README.md"
|
|
8
12
|
description = "Internal standardized metrics library"
|
|
9
13
|
requires-python = ">=3.11"
|
|
10
14
|
dependencies = [
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.0.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 2)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g717dce5f2'
|
|
@@ -2,11 +2,13 @@ from typing import Iterable
|
|
|
2
2
|
|
|
3
3
|
from fastapi import FastAPI
|
|
4
4
|
from prometheus_fastapi_instrumentator import Instrumentator
|
|
5
|
+
|
|
6
|
+
from .. import MetricsExporter
|
|
5
7
|
from ..core import PrometheusMetrics
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
def setup_fastapi_metrics(
|
|
9
|
-
app: FastAPI, metrics:
|
|
11
|
+
app: FastAPI, metrics: MetricsExporter, excluded_routes: Iterable[str] | None = None
|
|
10
12
|
) -> None:
|
|
11
13
|
"""
|
|
12
14
|
Настраивает автоматический мониторинг HTTP запросов
|
|
@@ -5,11 +5,11 @@ from faststream.asgi import AsgiFastStream
|
|
|
5
5
|
from faststream.prometheus import PrometheusMiddleware
|
|
6
6
|
from prometheus_client import make_asgi_app
|
|
7
7
|
|
|
8
|
-
from ..core import
|
|
8
|
+
from ..core import MetricsExporter
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class MiddlewareFactory(Protocol):
|
|
12
|
-
def __call__(self, metrics:
|
|
12
|
+
def __call__(self, metrics: MetricsExporter) -> PrometheusMiddleware: ...
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
_BROKER_MIDDLEWARE_MAP: dict[Type[BrokerUsecase], MiddlewareFactory] = {}
|
|
@@ -20,8 +20,8 @@ try:
|
|
|
20
20
|
from faststream.rabbit.prometheus import RabbitPrometheusMiddleware
|
|
21
21
|
|
|
22
22
|
class CustomRabbitMiddleware(RabbitPrometheusMiddleware):
|
|
23
|
-
def __init__(self, metrics:
|
|
24
|
-
super().__init__(registry=metrics.get_registry()
|
|
23
|
+
def __init__(self, metrics: MetricsExporter):
|
|
24
|
+
super().__init__(registry=metrics.get_registry())
|
|
25
25
|
|
|
26
26
|
_BROKER_MIDDLEWARE_MAP[RabbitBroker] = CustomRabbitMiddleware
|
|
27
27
|
except ImportError:
|
|
@@ -33,8 +33,8 @@ try:
|
|
|
33
33
|
from faststream.kafka.prometheus import KafkaPrometheusMiddleware
|
|
34
34
|
|
|
35
35
|
class CustomKafkaMiddleware(KafkaPrometheusMiddleware):
|
|
36
|
-
def __init__(self, metrics:
|
|
37
|
-
super().__init__(registry=metrics.get_registry()
|
|
36
|
+
def __init__(self, metrics: MetricsExporter):
|
|
37
|
+
super().__init__(registry=metrics.get_registry())
|
|
38
38
|
|
|
39
39
|
_BROKER_MIDDLEWARE_MAP[KafkaBroker] = CustomKafkaMiddleware
|
|
40
40
|
except ImportError:
|
|
@@ -46,8 +46,8 @@ try:
|
|
|
46
46
|
from faststream.redis.prometheus import RedisPrometheusMiddleware
|
|
47
47
|
|
|
48
48
|
class CustomRedisMiddleware(RedisPrometheusMiddleware):
|
|
49
|
-
def __init__(self, metrics:
|
|
50
|
-
super().__init__(registry=metrics.get_registry()
|
|
49
|
+
def __init__(self, metrics: MetricsExporter):
|
|
50
|
+
super().__init__(registry=metrics.get_registry())
|
|
51
51
|
|
|
52
52
|
_BROKER_MIDDLEWARE_MAP[RedisBroker] = CustomRedisMiddleware
|
|
53
53
|
except ImportError:
|
|
@@ -58,8 +58,8 @@ try:
|
|
|
58
58
|
from faststream.confluent.prometheus import KafkaPrometheusMiddleware as ConfluentPrometheusMiddleware
|
|
59
59
|
|
|
60
60
|
class CustomConfluentPrometheusMiddleware(ConfluentPrometheusMiddleware):
|
|
61
|
-
def __init__(self, metrics:
|
|
62
|
-
super().__init__(registry=metrics.get_registry()
|
|
61
|
+
def __init__(self, metrics: MetricsExporter):
|
|
62
|
+
super().__init__(registry=metrics.get_registry())
|
|
63
63
|
|
|
64
64
|
_BROKER_MIDDLEWARE_MAP[ConfluentBroker] = CustomConfluentPrometheusMiddleware
|
|
65
65
|
except ImportError:
|
|
@@ -71,8 +71,8 @@ try:
|
|
|
71
71
|
from faststream.nats.prometheus import NatsPrometheusMiddleware
|
|
72
72
|
|
|
73
73
|
class CustomNatsPrometheusMiddleware(NatsPrometheusMiddleware):
|
|
74
|
-
def __init__(self, metrics:
|
|
75
|
-
super().__init__(registry=metrics.get_registry()
|
|
74
|
+
def __init__(self, metrics: MetricsExporter):
|
|
75
|
+
super().__init__(registry=metrics.get_registry())
|
|
76
76
|
|
|
77
77
|
_BROKER_MIDDLEWARE_MAP[NatsBroker] = CustomNatsPrometheusMiddleware
|
|
78
78
|
|
|
@@ -80,7 +80,7 @@ except ImportError:
|
|
|
80
80
|
pass
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def setup_faststream_metrics(app: AsgiFastStream, metrics:
|
|
83
|
+
def setup_faststream_metrics(app: AsgiFastStream, metrics: MetricsExporter) -> None:
|
|
84
84
|
broker = app.broker
|
|
85
85
|
broker_type = type(broker)
|
|
86
86
|
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fast-telemetry
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Internal standardized metrics library
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: prometheus-client~=0.21.0
|
|
8
|
+
Provides-Extra: web
|
|
9
|
+
Requires-Dist: fastapi~=0.115.0; extra == "web"
|
|
10
|
+
Requires-Dist: prometheus-fastapi-instrumentator~=7.1.0; extra == "web"
|
|
11
|
+
Provides-Extra: stream
|
|
12
|
+
Requires-Dist: faststream~=0.6.0; extra == "stream"
|
|
13
|
+
|
|
14
|
+
# 📊 fast-telemetry
|
|
15
|
+
|
|
16
|
+
**Production-ready Prometheus integration for FastAPI, FastStream, and Python Workers.**
|
|
17
|
+
|
|
18
|
+
`fast-telemetry` — это "клей", который объединяет метрики вашего микросервиса в единый стандарт. Библиотека навязывает
|
|
19
|
+
правильные практики (единые метки `env`, `version`, `service`) и предоставляет удобные абстракции для HTTP-сервисов,
|
|
20
|
+
обработчиков очередей и периодических задач.
|
|
21
|
+
|
|
22
|
+
### 🌟 Особенности
|
|
23
|
+
|
|
24
|
+
* **Единый стандарт:** Автоматически добавляет метки `service`, `env`, `version` ко всем метрикам.
|
|
25
|
+
* **FastAPI:** Автоконфигурация через `Instrumentator`, исключение служебных ручек (`/metrics` и других переданных).
|
|
26
|
+
* **FastStream:** Поддержка RabbitMQ, Kafka, Redis, NATS "из коробки" (автоопределение драйвера).
|
|
27
|
+
* **Workers & Cron:**
|
|
28
|
+
* Поддержка Long-running процессов (daemon thread server).
|
|
29
|
+
* Поддержка Batch-jobs (Pushgateway) через **универсальный контекстный менеджер** (sync/async).
|
|
30
|
+
* **Декораторы:** Удобные `@measure_task` и `@track_exception`, которые сами понимают, синхронная функция или
|
|
31
|
+
асинхронная.
|
|
32
|
+
* **Безопасность типов:** Полная типизация (mypy strict).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### 📦 Установка
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install fast-telemetry
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### 🚀 Quick Start
|
|
45
|
+
|
|
46
|
+
#### 1. Core Concepts
|
|
47
|
+
|
|
48
|
+
В основе всего лежит класс `PrometheusMetrics` (или его наследники). Вы инициализируете его один раз при старте
|
|
49
|
+
приложения.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from fast_telemetry import PrometheusMetrics
|
|
53
|
+
|
|
54
|
+
metrics = PrometheusMetrics(
|
|
55
|
+
service_name="payment_service",
|
|
56
|
+
version="1.0.4",
|
|
57
|
+
env="production"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Использование в коде
|
|
61
|
+
metrics.inc_error("validation_error")
|
|
62
|
+
|
|
63
|
+
with metrics.timer("db_query", long_task=False):
|
|
64
|
+
# ... logic ...
|
|
65
|
+
pass
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### 2. FastAPI Integration
|
|
69
|
+
|
|
70
|
+
Автоматически добавляет эндпоинт `/metrics` и собирает RED-метрики (Requests, Errors, Duration).
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from fastapi import FastAPI
|
|
74
|
+
from fast_telemetry import PrometheusMetrics, setup_fastapi_metrics
|
|
75
|
+
|
|
76
|
+
app = FastAPI()
|
|
77
|
+
metrics = PrometheusMetrics(service_name="api_core", env="dev", version="1.2.3")
|
|
78
|
+
|
|
79
|
+
# Настройка (исключает /docs, /openapi.json + readiness)
|
|
80
|
+
setup_fastapi_metrics(app, metrics, excluded_routes=["/readiness"])
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@app.get("/")
|
|
84
|
+
@metrics.measure_task("root_handler", long_task=False)
|
|
85
|
+
async def root():
|
|
86
|
+
return {"status": "ok"}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 3. FastStream Integration
|
|
90
|
+
|
|
91
|
+
Поддерживает автоматическое определение брокера (Rabbit/Kafka/Redis/NATS) и инъекцию middleware.
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from faststream.asgi import AsgiFastStream, make_ping_asgi
|
|
95
|
+
from faststream.rabbit import RabbitBroker
|
|
96
|
+
from fast_telemetry import PrometheusMetrics, setup_faststream_metrics
|
|
97
|
+
|
|
98
|
+
broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
|
|
99
|
+
app = AsgiFastStream(
|
|
100
|
+
broker,
|
|
101
|
+
asgi_routes=[
|
|
102
|
+
("/health", make_ping_asgi(broker))
|
|
103
|
+
],
|
|
104
|
+
lifespan=None,
|
|
105
|
+
asyncapi_path="/docs",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
metrics = PrometheusMetrics(service_name="worker_core", env="dev")
|
|
109
|
+
setup_faststream_metrics(app, metrics)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### 4. Workers & Cron Jobs
|
|
113
|
+
|
|
114
|
+
Для скриптов без веб-сервера. Поддерживает два режима:
|
|
115
|
+
|
|
116
|
+
1. **Daemon Server** (для бесконечных циклов).
|
|
117
|
+
2. **Push Gateway** (для скриптов, запускаемых по расписанию).
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import asyncio
|
|
121
|
+
from fast_telemetry import WorkerMetrics
|
|
122
|
+
|
|
123
|
+
metrics = WorkerMetrics(service_name="nightly_job", env="prod")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# --- Вариант А: Long-running worker ---
|
|
127
|
+
def run_worker():
|
|
128
|
+
# Запускает HTTP сервер в фоновом потоке
|
|
129
|
+
metrics.start_server(port=8000)
|
|
130
|
+
while True:
|
|
131
|
+
process_data()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# --- Вариант Б: Batch Job (Cron) ---
|
|
135
|
+
# Универсальный трекер (работает и с with, и с async with)
|
|
136
|
+
async def run_batch_job():
|
|
137
|
+
# Автоматически отправит метрики в Pushgateway при выходе из блока
|
|
138
|
+
# Группирует по instance_id, чтобы воркеры не перезатирали друг друга
|
|
139
|
+
async with metrics.track_job(gateway_url="http://pushgateway:9091", timeout=5.0):
|
|
140
|
+
await do_heavy_calculation()
|
|
141
|
+
metrics.inc_error("calc_error")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
asyncio.run(run_batch_job())
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### 🛠 Декораторы
|
|
151
|
+
|
|
152
|
+
Библиотека предоставляет "умные" декораторы, которые работают с sync и async функциями прозрачно.
|
|
153
|
+
|
|
154
|
+
**`@track_exception()`**
|
|
155
|
+
Считает количество исключений. Использует имя класса исключения как метку.
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
@metrics.track_exception
|
|
159
|
+
async def dangerous_operation():
|
|
160
|
+
raise ValueError("Oops")
|
|
161
|
+
# Увеличит счетчик fasttelemetry_business_errors_total{error_type="ValueError", ...}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**`@measure_task("task_name")`**
|
|
165
|
+
Замеряет время выполнения функции (Histogram).
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
@metrics.measure_task("image_processing")
|
|
169
|
+
def process_image(img):
|
|
170
|
+
time.sleep(1)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### 📊 Grafana & Prometheus
|
|
176
|
+
|
|
177
|
+
Библиотека экспортирует следующие базовые метрики:
|
|
178
|
+
|
|
179
|
+
1. **`fasttelemetry_app_info`** (Gauge) — всегда `1`. Содержит метки `version`, `env`, `service`. Используйте для
|
|
180
|
+
аннотаций деплоев на графиках.
|
|
181
|
+
2. **`fasttelemetry_business_errors_total`** (Counter) — счетчик ошибок бизнес-логики.
|
|
182
|
+
3. **`fasttelemetry_task_processing_seconds`** (Histogram) — время выполнения внутренних задач.
|
|
183
|
+
4. **`http_requests_...`** — [fastapi.json](grafana/fastapi.json) (если используется FastAPI).
|
|
184
|
+
5. **`faststream_...`** — [faststream.json](grafana/faststream.json) (если используется FastStream).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 📈 Base Metrics & Grafana Dashboard
|
|
189
|
+
|
|
190
|
+
Библиотека предоставляет "Ready-to-use" набор метрик
|
|
191
|
+
|
|
192
|
+
### Metric Schema
|
|
193
|
+
|
|
194
|
+
| Metric Name | Type | Labels | Description |
|
|
195
|
+
|----------------------------------------------|-----------|-----------------------------|----------------------------------------------------------------------------------|
|
|
196
|
+
| `fasttelemetry_app_info` | Gauge | `env`, `service`, `version` | Информация о запущенном инстансе. Всегда `1`. |
|
|
197
|
+
| `fasttelemetry_business_errors_total` | Counter | `error_type` | Количество ошибок бизнес-логики (пойманных через `track_exception` или вручную). |
|
|
198
|
+
| `fasttelemetry_task_processing_seconds` | Histogram | `task_type` | Время выполнения задач (обернутых в `@measure_task` или `timer`). |
|
|
199
|
+
| `fasttelemetry_long_task_processing_seconds` | Histogram | `task_type` | Время выполнения долгих задач (обернутых в `@measure_task` или `timer`). |
|
|
200
|
+
|
|
201
|
+
### ⚙️ Configuration
|
|
202
|
+
|
|
203
|
+
Вы можете передать параметры явно в `__init__` или использовать переменные окружения:
|
|
204
|
+
|
|
205
|
+
| Environment Variable | Description | Default |
|
|
206
|
+
|----------------------|----------------------------|-----------|
|
|
207
|
+
| `APP_ENV` | Окружение (prod/dev/stage) | `dev` |
|
|
208
|
+
| `APP_VERSION` | Версия приложения | `unknown` |
|
|
209
|
+
|
|
210
|
+
### 🖥️ Grafana Dashboard JSON
|
|
211
|
+
|
|
212
|
+
Дашборды можно импортировать из [папки](grafana)
|
|
@@ -11,12 +11,10 @@ examples/app_example/env.example
|
|
|
11
11
|
examples/app_example/_grafana-data/grafana.db
|
|
12
12
|
examples/app_example/apps/fastapi/.dockerignore
|
|
13
13
|
examples/app_example/apps/fastapi/Dockerfile
|
|
14
|
-
examples/app_example/apps/fastapi/fast_telemetry-0.1.0-py3-none-any.whl
|
|
15
14
|
examples/app_example/apps/fastapi/main.py
|
|
16
15
|
examples/app_example/apps/fastapi/requirements.txt
|
|
17
16
|
examples/app_example/apps/faststream/.dockerignore
|
|
18
17
|
examples/app_example/apps/faststream/Dockerfile
|
|
19
|
-
examples/app_example/apps/faststream/fast_telemetry-0.1.0-py3-none-any.whl
|
|
20
18
|
examples/app_example/apps/faststream/main.py
|
|
21
19
|
examples/app_example/apps/faststream/requirements.txt
|
|
22
20
|
examples/app_example/apps/post_init/.dockerignore
|
|
@@ -25,7 +23,6 @@ examples/app_example/apps/post_init/main.py
|
|
|
25
23
|
examples/app_example/apps/post_init/requirements.txt
|
|
26
24
|
examples/app_example/apps/worker/.dockerignore
|
|
27
25
|
examples/app_example/apps/worker/Dockerfile
|
|
28
|
-
examples/app_example/apps/worker/fast_telemetry-0.1.0-py3-none-any.whl
|
|
29
26
|
examples/app_example/apps/worker/main.py
|
|
30
27
|
examples/app_example/apps/worker/requirements.txt
|
|
31
28
|
examples/app_example/prometheus/prometheus.yaml
|
|
@@ -34,6 +31,7 @@ grafana/faststream.json
|
|
|
34
31
|
grafana/fasttelemetry.json
|
|
35
32
|
src/__init__.py
|
|
36
33
|
src/fast_telemetry/__init__.py
|
|
34
|
+
src/fast_telemetry/_version.py
|
|
37
35
|
src/fast_telemetry/core.py
|
|
38
36
|
src/fast_telemetry.egg-info/PKG-INFO
|
|
39
37
|
src/fast_telemetry.egg-info/SOURCES.txt
|
fast_telemetry-0.0.0/PKG-INFO
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: fast-telemetry
|
|
3
|
-
Version: 0.0.0
|
|
4
|
-
Summary: Internal standardized metrics library
|
|
5
|
-
Requires-Python: >=3.11
|
|
6
|
-
Requires-Dist: prometheus-client~=0.21.0
|
|
7
|
-
Provides-Extra: web
|
|
8
|
-
Requires-Dist: fastapi~=0.115.0; extra == "web"
|
|
9
|
-
Requires-Dist: prometheus-fastapi-instrumentator~=7.1.0; extra == "web"
|
|
10
|
-
Provides-Extra: stream
|
|
11
|
-
Requires-Dist: faststream~=0.6.0; extra == "stream"
|
fast_telemetry-0.0.0/examples/app_example/apps/fastapi/fast_telemetry-0.1.0-py3-none-any.whl
DELETED
|
Binary file
|
fast_telemetry-0.0.0/examples/app_example/apps/faststream/fast_telemetry-0.1.0-py3-none-any.whl
DELETED
|
Binary file
|
|
Binary file
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: fast-telemetry
|
|
3
|
-
Version: 0.0.0
|
|
4
|
-
Summary: Internal standardized metrics library
|
|
5
|
-
Requires-Python: >=3.11
|
|
6
|
-
Requires-Dist: prometheus-client~=0.21.0
|
|
7
|
-
Provides-Extra: web
|
|
8
|
-
Requires-Dist: fastapi~=0.115.0; extra == "web"
|
|
9
|
-
Requires-Dist: prometheus-fastapi-instrumentator~=7.1.0; extra == "web"
|
|
10
|
-
Provides-Extra: stream
|
|
11
|
-
Requires-Dist: faststream~=0.6.0; extra == "stream"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/fastapi/.dockerignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/.dockerignore
RENAMED
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/faststream/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/.dockerignore
RENAMED
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/post_init/requirements.txt
RENAMED
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/apps/worker/.dockerignore
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/examples/app_example/prometheus/prometheus.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fast_telemetry-0.0.0 → fast_telemetry-0.0.2}/src/fast_telemetry.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|