fast-telemetry 0.0.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.
Files changed (48) hide show
  1. fast_telemetry-0.0.0/.gitignore +10 -0
  2. fast_telemetry-0.0.0/.gitlab-ci.yml +33 -0
  3. fast_telemetry-0.0.0/PKG-INFO +11 -0
  4. fast_telemetry-0.0.0/README.md +199 -0
  5. fast_telemetry-0.0.0/examples/.gitignore +1 -0
  6. fast_telemetry-0.0.0/examples/app_example/.gitignore +2 -0
  7. fast_telemetry-0.0.0/examples/app_example/_grafana-data/grafana.db +0 -0
  8. fast_telemetry-0.0.0/examples/app_example/apps/fastapi/.dockerignore +1 -0
  9. fast_telemetry-0.0.0/examples/app_example/apps/fastapi/Dockerfile +10 -0
  10. fast_telemetry-0.0.0/examples/app_example/apps/fastapi/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
  11. fast_telemetry-0.0.0/examples/app_example/apps/fastapi/main.py +73 -0
  12. fast_telemetry-0.0.0/examples/app_example/apps/fastapi/requirements.txt +6 -0
  13. fast_telemetry-0.0.0/examples/app_example/apps/faststream/.dockerignore +1 -0
  14. fast_telemetry-0.0.0/examples/app_example/apps/faststream/Dockerfile +10 -0
  15. fast_telemetry-0.0.0/examples/app_example/apps/faststream/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
  16. fast_telemetry-0.0.0/examples/app_example/apps/faststream/main.py +81 -0
  17. fast_telemetry-0.0.0/examples/app_example/apps/faststream/requirements.txt +5 -0
  18. fast_telemetry-0.0.0/examples/app_example/apps/post_init/.dockerignore +1 -0
  19. fast_telemetry-0.0.0/examples/app_example/apps/post_init/Dockerfile +11 -0
  20. fast_telemetry-0.0.0/examples/app_example/apps/post_init/main.py +31 -0
  21. fast_telemetry-0.0.0/examples/app_example/apps/post_init/requirements.txt +2 -0
  22. fast_telemetry-0.0.0/examples/app_example/apps/worker/.dockerignore +1 -0
  23. fast_telemetry-0.0.0/examples/app_example/apps/worker/Dockerfile +10 -0
  24. fast_telemetry-0.0.0/examples/app_example/apps/worker/fast_telemetry-0.1.0-py3-none-any.whl +0 -0
  25. fast_telemetry-0.0.0/examples/app_example/apps/worker/main.py +46 -0
  26. fast_telemetry-0.0.0/examples/app_example/apps/worker/requirements.txt +3 -0
  27. fast_telemetry-0.0.0/examples/app_example/docker-compose.yaml +95 -0
  28. fast_telemetry-0.0.0/examples/app_example/env.example +6 -0
  29. fast_telemetry-0.0.0/examples/app_example/prometheus/prometheus.yaml +10 -0
  30. fast_telemetry-0.0.0/examples/dishka_example.py +19 -0
  31. fast_telemetry-0.0.0/grafana/fastapi.json +1055 -0
  32. fast_telemetry-0.0.0/grafana/faststream.json +1821 -0
  33. fast_telemetry-0.0.0/grafana/fasttelemetry.json +527 -0
  34. fast_telemetry-0.0.0/pyproject.toml +36 -0
  35. fast_telemetry-0.0.0/requirements.txt +4 -0
  36. fast_telemetry-0.0.0/setup.cfg +4 -0
  37. fast_telemetry-0.0.0/src/__init__.py +0 -0
  38. fast_telemetry-0.0.0/src/fast_telemetry/__init__.py +10 -0
  39. fast_telemetry-0.0.0/src/fast_telemetry/core.py +232 -0
  40. fast_telemetry-0.0.0/src/fast_telemetry/integrations/__init__.py +0 -0
  41. fast_telemetry-0.0.0/src/fast_telemetry/integrations/fastapi.py +30 -0
  42. fast_telemetry-0.0.0/src/fast_telemetry/integrations/faststream.py +102 -0
  43. fast_telemetry-0.0.0/src/fast_telemetry/integrations/worker.py +124 -0
  44. fast_telemetry-0.0.0/src/fast_telemetry.egg-info/PKG-INFO +11 -0
  45. fast_telemetry-0.0.0/src/fast_telemetry.egg-info/SOURCES.txt +46 -0
  46. fast_telemetry-0.0.0/src/fast_telemetry.egg-info/dependency_links.txt +1 -0
  47. fast_telemetry-0.0.0/src/fast_telemetry.egg-info/requires.txt +8 -0
  48. fast_telemetry-0.0.0/src/fast_telemetry.egg-info/top_level.txt +2 -0
@@ -0,0 +1,10 @@
1
+ dist
2
+ fast_telemetry.egg-info
3
+ .venv
4
+ *__pycharm__
5
+ src/test.py
6
+ .pytest_cache
7
+ *__pycache__
8
+ .idea
9
+ .DS_Store
10
+ .env
@@ -0,0 +1,33 @@
1
+ stages:
2
+ - build
3
+ - deploy
4
+
5
+ variables:
6
+ PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
7
+
8
+ cache:
9
+ paths:
10
+ - .cache/pip
11
+
12
+ build_package:
13
+ stage: build
14
+ image: python:3.11
15
+ script:
16
+ - pip install build
17
+ - python -m build
18
+ artifacts:
19
+ paths:
20
+ - dist/
21
+ expire_in: 3 hour
22
+ only:
23
+ - tags
24
+
25
+ upload_to_pypi:
26
+ stage: deploy
27
+ image: python:3.11
28
+ needs: ["build_package"]
29
+ script:
30
+ - pip install twine
31
+ - twine upload dist/*
32
+ only:
33
+ - tags
@@ -0,0 +1,11 @@
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"
@@ -0,0 +1,199 @@
1
+ # 📊 fast-telemetry
2
+
3
+ **Production-ready Prometheus integration for FastAPI, FastStream, and Python Workers.**
4
+
5
+ `fast-telemetry` — это "клей", который объединяет метрики вашего микросервиса в единый стандарт. Библиотека навязывает
6
+ правильные практики (единые метки `env`, `version`, `service`) и предоставляет удобные абстракции для HTTP-сервисов,
7
+ обработчиков очередей и периодических задач.
8
+
9
+ ### 🌟 Особенности
10
+
11
+ * **Единый стандарт:** Автоматически добавляет метки `service`, `env`, `version` ко всем метрикам.
12
+ * **FastAPI:** Автоконфигурация через `Instrumentator`, исключение служебных ручек (`/metrics` и других переданных).
13
+ * **FastStream:** Поддержка RabbitMQ, Kafka, Redis, NATS "из коробки" (автоопределение драйвера).
14
+ * **Workers & Cron:**
15
+ * Поддержка Long-running процессов (daemon thread server).
16
+ * Поддержка Batch-jobs (Pushgateway) через **универсальный контекстный менеджер** (sync/async).
17
+ * **Декораторы:** Удобные `@measure_task` и `@track_exception`, которые сами понимают, синхронная функция или
18
+ асинхронная.
19
+ * **Безопасность типов:** Полная типизация (mypy strict).
20
+
21
+ ---
22
+
23
+ ### 📦 Установка
24
+
25
+ ```bash
26
+ pip install fast-telemetry
27
+ ```
28
+
29
+ ---
30
+
31
+ ### 🚀 Quick Start
32
+
33
+ #### 1. Core Concepts
34
+
35
+ В основе всего лежит класс `PrometheusMetrics` (или его наследники). Вы инициализируете его один раз при старте
36
+ приложения.
37
+
38
+ ```python
39
+ from fast_telemetry import PrometheusMetrics
40
+
41
+ metrics = PrometheusMetrics(
42
+ service_name="payment_service",
43
+ version="1.0.4",
44
+ env="production"
45
+ )
46
+
47
+ # Использование в коде
48
+ metrics.inc_error("validation_error")
49
+
50
+ with metrics.timer("db_query", long_task=False):
51
+ # ... logic ...
52
+ pass
53
+ ```
54
+
55
+ #### 2. FastAPI Integration
56
+
57
+ Автоматически добавляет эндпоинт `/metrics` и собирает RED-метрики (Requests, Errors, Duration).
58
+
59
+ ```python
60
+ from fastapi import FastAPI
61
+ from fast_telemetry import PrometheusMetrics, setup_fastapi_metrics
62
+
63
+ app = FastAPI()
64
+ metrics = PrometheusMetrics(service_name="api_core", env="dev", version="1.2.3")
65
+
66
+ # Настройка (исключает /docs, /openapi.json + readiness)
67
+ setup_fastapi_metrics(app, metrics, excluded_routes=["/readiness"])
68
+
69
+
70
+ @app.get("/")
71
+ @metrics.measure_task("root_handler", long_task=False)
72
+ async def root():
73
+ return {"status": "ok"}
74
+ ```
75
+
76
+ #### 3. FastStream Integration
77
+
78
+ Поддерживает автоматическое определение брокера (Rabbit/Kafka/Redis/NATS) и инъекцию middleware.
79
+
80
+ ```python
81
+ from faststream.asgi import AsgiFastStream, make_ping_asgi
82
+ from faststream.rabbit import RabbitBroker
83
+ from fast_telemetry import PrometheusMetrics, setup_faststream_metrics
84
+
85
+ broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
86
+ app = AsgiFastStream(
87
+ broker,
88
+ asgi_routes=[
89
+ ("/health", make_ping_asgi(broker))
90
+ ],
91
+ lifespan=None,
92
+ asyncapi_path="/docs",
93
+ )
94
+
95
+ metrics = PrometheusMetrics(service_name="worker_core", env="dev")
96
+ setup_faststream_metrics(app, metrics)
97
+ ```
98
+
99
+ #### 4. Workers & Cron Jobs
100
+
101
+ Для скриптов без веб-сервера. Поддерживает два режима:
102
+
103
+ 1. **Daemon Server** (для бесконечных циклов).
104
+ 2. **Push Gateway** (для скриптов, запускаемых по расписанию).
105
+
106
+ ```python
107
+ import asyncio
108
+ from fast_telemetry import WorkerMetrics
109
+
110
+ metrics = WorkerMetrics(service_name="nightly_job", env="prod")
111
+
112
+
113
+ # --- Вариант А: Long-running worker ---
114
+ def run_worker():
115
+ # Запускает HTTP сервер в фоновом потоке
116
+ metrics.start_server(port=8000)
117
+ while True:
118
+ process_data()
119
+
120
+
121
+ # --- Вариант Б: Batch Job (Cron) ---
122
+ # Универсальный трекер (работает и с with, и с async with)
123
+ async def run_batch_job():
124
+ # Автоматически отправит метрики в Pushgateway при выходе из блока
125
+ # Группирует по instance_id, чтобы воркеры не перезатирали друг друга
126
+ async with metrics.track_job(gateway_url="http://pushgateway:9091", timeout=5.0):
127
+ await do_heavy_calculation()
128
+ metrics.inc_error("calc_error")
129
+
130
+
131
+ if __name__ == "__main__":
132
+ asyncio.run(run_batch_job())
133
+ ```
134
+
135
+ ---
136
+
137
+ ### 🛠 Декораторы
138
+
139
+ Библиотека предоставляет "умные" декораторы, которые работают с sync и async функциями прозрачно.
140
+
141
+ **`@track_exception()`**
142
+ Считает количество исключений. Использует имя класса исключения как метку.
143
+
144
+ ```python
145
+ @metrics.track_exception
146
+ async def dangerous_operation():
147
+ raise ValueError("Oops")
148
+ # Увеличит счетчик fasttelemetry_business_errors_total{error_type="ValueError", ...}
149
+ ```
150
+
151
+ **`@measure_task("task_name")`**
152
+ Замеряет время выполнения функции (Histogram).
153
+
154
+ ```python
155
+ @metrics.measure_task("image_processing")
156
+ def process_image(img):
157
+ time.sleep(1)
158
+ ```
159
+
160
+ ---
161
+
162
+ ### 📊 Grafana & Prometheus
163
+
164
+ Библиотека экспортирует следующие базовые метрики:
165
+
166
+ 1. **`fasttelemetry_app_info`** (Gauge) — всегда `1`. Содержит метки `version`, `env`, `service`. Используйте для
167
+ аннотаций деплоев на графиках.
168
+ 2. **`fasttelemetry_business_errors_total`** (Counter) — счетчик ошибок бизнес-логики.
169
+ 3. **`fasttelemetry_task_processing_seconds`** (Histogram) — время выполнения внутренних задач.
170
+ 4. **`http_requests_...`** — [fastapi.json](grafana/fastapi.json) (если используется FastAPI).
171
+ 5. **`faststream_...`** — [faststream.json](grafana/faststream.json) (если используется FastStream).
172
+
173
+ ---
174
+
175
+ ## 📈 Base Metrics & Grafana Dashboard
176
+
177
+ Библиотека предоставляет "Ready-to-use" набор метрик
178
+
179
+ ### Metric Schema
180
+
181
+ | Metric Name | Type | Labels | Description |
182
+ |----------------------------------------------|-----------|-----------------------------|----------------------------------------------------------------------------------|
183
+ | `fasttelemetry_app_info` | Gauge | `env`, `service`, `version` | Информация о запущенном инстансе. Всегда `1`. |
184
+ | `fasttelemetry_business_errors_total` | Counter | `error_type` | Количество ошибок бизнес-логики (пойманных через `track_exception` или вручную). |
185
+ | `fasttelemetry_task_processing_seconds` | Histogram | `task_type` | Время выполнения задач (обернутых в `@measure_task` или `timer`). |
186
+ | `fasttelemetry_long_task_processing_seconds` | Histogram | `task_type` | Время выполнения долгих задач (обернутых в `@measure_task` или `timer`). |
187
+
188
+ ### ⚙️ Configuration
189
+
190
+ Вы можете передать параметры явно в `__init__` или использовать переменные окружения:
191
+
192
+ | Environment Variable | Description | Default |
193
+ |----------------------|----------------------------|-----------|
194
+ | `APP_ENV` | Окружение (prod/dev/stage) | `dev` |
195
+ | `APP_VERSION` | Версия приложения | `unknown` |
196
+
197
+ ### 🖥️ Grafana Dashboard JSON
198
+
199
+ Дашборды можно импортировать из [папки](grafana)
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,2 @@
1
+ _prometheus_data
2
+ _rabbitmq_data
@@ -0,0 +1,10 @@
1
+ FROM python:3.11-alpine
2
+ WORKDIR /app
3
+ RUN apk add --update helm && \
4
+ adduser -D -u 1000 appuser
5
+
6
+ COPY --chown=appuser:appuser . .
7
+ RUN pip install --upgrade pip \
8
+ && pip install --root-user-action=ignore --no-cache-dir -r requirements.txt
9
+ USER appuser
10
+ CMD ["python", "-m", "main"]
@@ -0,0 +1,73 @@
1
+ import asyncio
2
+ import random
3
+ from contextlib import asynccontextmanager
4
+
5
+ import uvicorn
6
+ from fastapi import FastAPI
7
+ from fast_telemetry.core import PrometheusMetrics
8
+ from fast_telemetry.integrations.fastapi import setup_fastapi_metrics
9
+ from starlette import status
10
+
11
+ service_name = "demo_service"
12
+ env = "production"
13
+ version = "1.0.0"
14
+
15
+ metrics = PrometheusMetrics(service_name=service_name, env=env, version=version)
16
+
17
+
18
+ @metrics.measure_task("heavy_calculation", long_task=True)
19
+ async def heavy_task():
20
+ await asyncio.sleep(random.uniform(1, 5))
21
+
22
+
23
+ @metrics.track_exception
24
+ async def risky_task():
25
+ if random.random() < 0.3:
26
+ raise PaymentError("Payment declined")
27
+ if random.random() < 0.1:
28
+ raise DatabaseError("Connection lost")
29
+ await asyncio.sleep(0.05)
30
+
31
+
32
+ async def traffic_generator():
33
+ print("🚀 Traffic generator started...")
34
+ while True:
35
+ try:
36
+ await heavy_task()
37
+ await risky_task()
38
+ except Exception as ex:
39
+ print(f"Error: {ex}")
40
+ await asyncio.sleep(5)
41
+
42
+
43
+ @asynccontextmanager
44
+ async def lifespan(_: FastAPI):
45
+ asyncio.create_task(traffic_generator())
46
+ yield
47
+
48
+
49
+ app = FastAPI(title=service_name, lifespan=lifespan, version=version)
50
+
51
+ setup_fastapi_metrics(app, metrics)
52
+
53
+
54
+ class PaymentError(Exception):
55
+ pass
56
+
57
+
58
+ class DatabaseError(Exception):
59
+ pass
60
+
61
+
62
+ @app.post("/foo")
63
+ async def foo(message: dict) -> None:
64
+ print(f"Incoming message: {message}")
65
+
66
+
67
+ @app.get("/health", status_code=status.HTTP_204_NO_CONTENT)
68
+ async def health() -> None:
69
+ return None
70
+
71
+
72
+ if __name__ == "__main__":
73
+ uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -0,0 +1,6 @@
1
+ fastapi>=0.115.0
2
+ prometheus-client>=0.21.0
3
+ prometheus-fastapi-instrumentator>=6.1.0
4
+ uvicorn>=0.40.0
5
+
6
+ ./fast_telemetry-0.1.0-py3-none-any.whl[web]
@@ -0,0 +1,10 @@
1
+ FROM python:3.11-alpine
2
+ WORKDIR /app
3
+ RUN apk add --update helm && \
4
+ adduser -D -u 1000 appuser
5
+
6
+ COPY --chown=appuser:appuser . .
7
+ RUN pip install --upgrade pip \
8
+ && pip install --root-user-action=ignore --no-cache-dir -r requirements.txt
9
+ USER appuser
10
+ CMD ["python", "-m", "main"]
@@ -0,0 +1,81 @@
1
+ import asyncio
2
+ import os
3
+ import random
4
+ from contextlib import asynccontextmanager
5
+
6
+ import uvicorn
7
+ from faststream.asgi import make_ping_asgi, AsgiFastStream
8
+ from faststream.rabbit import RabbitBroker
9
+
10
+ from fast_telemetry.core import PrometheusMetrics
11
+ from fast_telemetry.integrations.faststream import setup_faststream_metrics
12
+
13
+ service_name = "foo_service"
14
+ env = "dev"
15
+ version = "1.2.3"
16
+ queue = "foo"
17
+ metrics = PrometheusMetrics(service_name=service_name, version=version, env=env)
18
+
19
+ url = (
20
+ f"amqp://{os.getenv('RABBITMQ_DEFAULT_USER')}:{os.getenv('RABBITMQ_DEFAULT_PASS')}"
21
+ f"@{os.getenv('RABBITMQ_DEFAULT_HOST')}:{os.getenv('RABBITMQ_DEFAULT_PORT')}/"
22
+ )
23
+ broker = RabbitBroker(url)
24
+
25
+
26
+ @metrics.measure_task("heavy_calculation")
27
+ async def heavy_task():
28
+ await asyncio.sleep(random.uniform(0.1, 0.5))
29
+
30
+
31
+ @metrics.track_exception
32
+ async def risky_task():
33
+ if random.random() < 0.3:
34
+ raise PaymentError("Payment declined")
35
+ if random.random() < 0.1:
36
+ raise DatabaseError("Connection lost")
37
+ await asyncio.sleep(0.05)
38
+
39
+
40
+ async def traffic_generator():
41
+ print("🚀 Traffic generator started...")
42
+ while True:
43
+ try:
44
+ await heavy_task()
45
+ await risky_task()
46
+ except Exception as ex:
47
+ print(f"Error: {ex}")
48
+ await asyncio.sleep(5)
49
+
50
+
51
+ @asynccontextmanager
52
+ async def lifespan():
53
+ asyncio.create_task(traffic_generator())
54
+ yield
55
+
56
+
57
+ app = AsgiFastStream(
58
+ broker, asgi_routes=[("/health", make_ping_asgi(broker))], asyncapi_path="/docs", lifespan=lifespan
59
+ )
60
+
61
+
62
+ setup_faststream_metrics(app, metrics)
63
+
64
+
65
+ class PaymentError(Exception):
66
+ pass
67
+
68
+
69
+ class DatabaseError(Exception):
70
+ pass
71
+
72
+
73
+ @broker.subscriber(queue)
74
+ async def foo(msg: dict) -> dict:
75
+ print("incoming message:", msg)
76
+ await broker.publish({"some_number": random.randint(1, 100)}, "delete_me")
77
+ return {"message": msg}
78
+
79
+
80
+ if __name__ == "__main__":
81
+ uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -0,0 +1,5 @@
1
+ prometheus-client>=0.21.0
2
+ faststream[rabbit]>=0.6.5
3
+ uvicorn>=0.40.0
4
+
5
+ ./fast_telemetry-0.1.0-py3-none-any.whl[stream]
@@ -0,0 +1,11 @@
1
+ FROM python:3.11-alpine
2
+ WORKDIR /app
3
+ RUN apk add --update helm && \
4
+ adduser -D -u 1000 appuser
5
+
6
+ COPY --chown=appuser:appuser requirements.txt .
7
+ RUN pip install --upgrade pip \
8
+ && pip install --root-user-action=ignore --no-cache-dir -r requirements.txt
9
+ COPY --chown=appuser:appuser . .
10
+ USER appuser
11
+ CMD ["python", "-m", "main"]
@@ -0,0 +1,31 @@
1
+ import asyncio
2
+ import os
3
+
4
+ from faststream.rabbit import RabbitBroker
5
+ from httpx import AsyncClient
6
+
7
+
8
+ async def main():
9
+ queue = "foo"
10
+ broker_url = (
11
+ f"amqp://{os.getenv('RABBITMQ_DEFAULT_USER')}:{os.getenv('RABBITMQ_DEFAULT_PASS')}"
12
+ f"@{os.getenv('RABBITMQ_DEFAULT_HOST')}:{os.getenv('RABBITMQ_DEFAULT_PORT')}/"
13
+ )
14
+ broker = RabbitBroker(broker_url)
15
+ fastapi_url = os.getenv("FASTAPI_URL")
16
+ async with AsyncClient(base_url=fastapi_url) as client:
17
+ async with broker:
18
+ await broker.start()
19
+ i = 0
20
+ while True:
21
+ message = {"Hello": "World", "message_number": i}
22
+ print("Send message", message)
23
+ await client.post("/foo", json=message)
24
+ await broker.publish(message, queue)
25
+ i += 1
26
+ print("Sleep...")
27
+ await asyncio.sleep(1)
28
+
29
+
30
+ if __name__ == "__main__":
31
+ asyncio.run(main())
@@ -0,0 +1,2 @@
1
+ faststream[rabbit]~=0.6.5
2
+ httpx~=0.28.1
@@ -0,0 +1,10 @@
1
+ FROM python:3.11-alpine
2
+ WORKDIR /app
3
+ RUN apk add --update helm && \
4
+ adduser -D -u 1000 appuser
5
+
6
+ COPY --chown=appuser:appuser . .
7
+ RUN pip install --upgrade pip \
8
+ && pip install --root-user-action=ignore --no-cache-dir -r requirements.txt
9
+ USER appuser
10
+ CMD ["python", "-m", "main"]
@@ -0,0 +1,46 @@
1
+ import asyncio
2
+ import random
3
+
4
+ from fast_telemetry.integrations.worker import WorkerMetrics
5
+
6
+ metrics = WorkerMetrics(service_name="nightly_job", env="prod")
7
+
8
+
9
+ class PaymentError(Exception):
10
+ pass
11
+
12
+
13
+ class DatabaseError(Exception):
14
+ pass
15
+
16
+
17
+ @metrics.measure_task("heavy_calculation")
18
+ async def heavy_task():
19
+ await asyncio.sleep(random.uniform(0.1, 0.5))
20
+
21
+
22
+ @metrics.track_exception
23
+ async def risky_task():
24
+ if random.random() < 0.3:
25
+ raise PaymentError("Payment declined")
26
+ if random.random() < 0.1:
27
+ raise DatabaseError("Connection lost")
28
+ await asyncio.sleep(0.05)
29
+
30
+
31
+ async def run_worker():
32
+ metrics.start_server(port=8000)
33
+ while True:
34
+ await risky_task()
35
+ await heavy_task()
36
+ await asyncio.sleep(5)
37
+
38
+
39
+ # async def run_batch_job():
40
+ # async with metrics.track_job(gateway_url="http://pushgateway:9091"):
41
+ # await do_heavy_calculation()
42
+ # metrics.inc_error("calc_error")
43
+
44
+
45
+ if __name__ == "__main__":
46
+ asyncio.run(run_worker())
@@ -0,0 +1,3 @@
1
+ prometheus-client>=0.21.0
2
+
3
+ ./fast_telemetry-0.1.0-py3-none-any.whl