fast-telemetry 0.0.1__tar.gz → 0.1.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 (46) hide show
  1. {fast_telemetry-0.0.1/src/fast_telemetry.egg-info → fast_telemetry-0.1.0}/PKG-INFO +1 -1
  2. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/_version.py +3 -3
  3. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/core.py +77 -32
  4. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/integrations/fastapi.py +3 -4
  5. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/integrations/faststream.py +13 -13
  6. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0/src/fast_telemetry.egg-info}/PKG-INFO +1 -1
  7. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/.gitignore +0 -0
  8. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/.gitlab-ci.yml +0 -0
  9. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/README.md +0 -0
  10. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/.gitignore +0 -0
  11. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/.gitignore +0 -0
  12. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/_grafana-data/grafana.db +0 -0
  13. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/fastapi/.dockerignore +0 -0
  14. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/fastapi/Dockerfile +0 -0
  15. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/fastapi/main.py +0 -0
  16. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/fastapi/requirements.txt +0 -0
  17. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/faststream/.dockerignore +0 -0
  18. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/faststream/Dockerfile +0 -0
  19. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/faststream/main.py +0 -0
  20. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/faststream/requirements.txt +0 -0
  21. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/post_init/.dockerignore +0 -0
  22. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/post_init/Dockerfile +0 -0
  23. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/post_init/main.py +0 -0
  24. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/post_init/requirements.txt +0 -0
  25. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/worker/.dockerignore +0 -0
  26. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/worker/Dockerfile +0 -0
  27. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/worker/main.py +0 -0
  28. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/apps/worker/requirements.txt +0 -0
  29. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/docker-compose.yaml +0 -0
  30. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/env.example +0 -0
  31. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/app_example/prometheus/prometheus.yaml +0 -0
  32. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/examples/dishka_example.py +0 -0
  33. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/grafana/fastapi.json +0 -0
  34. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/grafana/faststream.json +0 -0
  35. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/grafana/fasttelemetry.json +0 -0
  36. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/pyproject.toml +0 -0
  37. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/requirements.txt +0 -0
  38. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/setup.cfg +0 -0
  39. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/__init__.py +0 -0
  40. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/__init__.py +0 -0
  41. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/integrations/__init__.py +0 -0
  42. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry/integrations/worker.py +0 -0
  43. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry.egg-info/SOURCES.txt +0 -0
  44. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry.egg-info/dependency_links.txt +0 -0
  45. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry.egg-info/requires.txt +0 -0
  46. {fast_telemetry-0.0.1 → fast_telemetry-0.1.0}/src/fast_telemetry.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-telemetry
3
- Version: 0.0.1
3
+ Version: 0.1.0
4
4
  Summary: Internal standardized metrics library
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.1'
32
- __version_tuple__ = version_tuple = (0, 0, 1)
31
+ __version__ = version = '0.1.0'
32
+ __version_tuple__ = version_tuple = (0, 1, 0)
33
33
 
34
- __commit_id__ = commit_id = 'ge8b1cc512'
34
+ __commit_id__ = commit_id = 'g8f02c6373'
@@ -2,6 +2,7 @@ import os
2
2
  import functools
3
3
  import inspect
4
4
  from abc import abstractmethod, ABC
5
+ from types import TracebackType
5
6
  from typing import (
6
7
  Callable,
7
8
  Any,
@@ -98,13 +99,82 @@ class MetricsCollector(ABC):
98
99
 
99
100
  return sync_wrapper
100
101
 
102
+ @overload
103
+ def track_exception(self, func: Callable[P, R]) -> Callable[P, R]:
104
+ pass
105
+
106
+ @overload
107
+ def track_exception(self, *, exclude: list[Type[BaseException]] | None = None) -> "_ExceptionTracker":
108
+ pass
109
+
101
110
  @abstractmethod
102
111
  def track_exception(
103
- self, *, exclude: list[Type[BaseException]] | None = None
104
- ) -> Callable[[Callable[P, R]], Callable[P, R]]:
112
+ self, arg: Callable[P, R] | None = None, *, exclude: list[Type[BaseException]] | None = None
113
+ ) -> Any:
105
114
  pass
106
115
 
107
116
 
117
+ class _ExceptionTracker:
118
+ """
119
+ Гибридный класс: Context Manager + Decorator.
120
+ Используется внутри track_exception.
121
+ """
122
+
123
+ def __init__(
124
+ self,
125
+ metrics: MetricsCollector,
126
+ exclude: list[Type[BaseException]] | None = None,
127
+ ):
128
+ self.metrics = metrics
129
+ self.exclude = tuple(exclude) if exclude else ()
130
+
131
+ def _handle_exception(self, exc_val: BaseException) -> None:
132
+ if not isinstance(exc_val, self.exclude):
133
+ self.metrics.inc_error(exc_val)
134
+
135
+ def __enter__(self) -> "_ExceptionTracker":
136
+ return self
137
+
138
+ def __exit__(
139
+ self,
140
+ exc_type: Type[BaseException] | None,
141
+ exc_val: BaseException | None,
142
+ exc_tb: TracebackType | None,
143
+ ) -> None:
144
+ if exc_val:
145
+ self._handle_exception(exc_val)
146
+
147
+ async def __aenter__(self) -> "_ExceptionTracker":
148
+ return self
149
+
150
+ async def __aexit__(
151
+ self,
152
+ exc_type: Type[BaseException] | None,
153
+ exc_val: BaseException | None,
154
+ exc_tb: TracebackType | None,
155
+ ) -> None:
156
+ if exc_val:
157
+ self._handle_exception(exc_val)
158
+
159
+ def __call__(self, func: Callable[P, R]) -> Callable[P, R]:
160
+ if inspect.iscoroutinefunction(func):
161
+
162
+ @functools.wraps(func)
163
+ async def async_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
164
+ async with self:
165
+ return await func(*args, **kwargs)
166
+
167
+ return async_wrapper # type: ignore
168
+ else:
169
+
170
+ @functools.wraps(func)
171
+ def sync_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
172
+ with self:
173
+ return func(*args, **kwargs)
174
+
175
+ return sync_wrapper
176
+
177
+
108
178
  class PrometheusMetrics(MetricsCollector, MetricsExporter):
109
179
  """
110
180
  Реализация метрик на базе prometheus-client.
@@ -186,39 +256,14 @@ class PrometheusMetrics(MetricsCollector, MetricsExporter):
186
256
  self, arg: Callable[P, R] | None = None, *, exclude: list[Type[BaseException]] | None = None
187
257
  ) -> Any:
188
258
  """
189
- Декоратор для подсчета исключений.
190
- Использует имя класса исключения как метку error_type.
259
+ Декоратор и контекстный менеджер для подсчета исключений.
191
260
  """
192
-
193
- def decorator(func: Callable[P, R]) -> Callable[P, R]:
194
- if inspect.iscoroutinefunction(func):
195
-
196
- @functools.wraps(func)
197
- async def async_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
198
- try:
199
- return await func(*args, **kwargs) # type: ignore
200
- except Exception as e:
201
- if not exclude or not isinstance(e, tuple(exclude)):
202
- self.inc_error(e)
203
- raise
204
-
205
- return async_wrapper # type: ignore
206
- else:
207
-
208
- @functools.wraps(func)
209
- def sync_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
210
- try:
211
- return func(*args, **kwargs)
212
- except Exception as e:
213
- if not exclude or not isinstance(e, tuple(exclude)):
214
- self.inc_error(e)
215
- raise
216
-
217
- return sync_wrapper
261
+ tracker = _ExceptionTracker(self, exclude=exclude)
218
262
 
219
263
  if callable(arg):
220
- return decorator(arg)
221
- return decorator
264
+ return tracker(arg)
265
+
266
+ return tracker
222
267
 
223
268
  def timer(self, task_type: str, long_task: bool = False) -> ContextManager[Any]:
224
269
  if long_task:
@@ -2,12 +2,11 @@ from typing import Iterable
2
2
 
3
3
  from fastapi import FastAPI
4
4
  from prometheus_fastapi_instrumentator import Instrumentator
5
- from ..core import PrometheusMetrics
6
5
 
6
+ from .. import MetricsExporter
7
7
 
8
- def setup_fastapi_metrics(
9
- app: FastAPI, metrics: PrometheusMetrics, excluded_routes: Iterable[str] | None = None
10
- ) -> None:
8
+
9
+ def setup_fastapi_metrics(app: FastAPI, metrics: MetricsExporter, excluded_routes: Iterable[str] | None = None) -> None:
11
10
  """
12
11
  Настраивает автоматический мониторинг HTTP запросов
13
12
  и добавляет эндпоинт /metrics.
@@ -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 PrometheusMetrics
8
+ from ..core import MetricsExporter
9
9
 
10
10
 
11
11
  class MiddlewareFactory(Protocol):
12
- def __call__(self, metrics: PrometheusMetrics) -> PrometheusMiddleware: ...
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: PrometheusMetrics):
24
- super().__init__(registry=metrics.get_registry(), custom_labels={"service": metrics.service_name})
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: PrometheusMetrics):
37
- super().__init__(registry=metrics.get_registry(), custom_labels={"service": metrics.service_name})
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: PrometheusMetrics):
50
- super().__init__(registry=metrics.get_registry(), custom_labels={"service": metrics.service_name})
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: PrometheusMetrics):
62
- super().__init__(registry=metrics.get_registry(), custom_labels={"service": metrics.service_name})
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: PrometheusMetrics):
75
- super().__init__(registry=metrics.get_registry(), custom_labels={"service": metrics.service_name})
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: PrometheusMetrics) -> None:
83
+ def setup_faststream_metrics(app: AsgiFastStream, metrics: MetricsExporter) -> None:
84
84
  broker = app.broker
85
85
  broker_type = type(broker)
86
86
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-telemetry
3
- Version: 0.0.1
3
+ Version: 0.1.0
4
4
  Summary: Internal standardized metrics library
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
File without changes
File without changes