jararaca 0.3.26__py3-none-any.whl → 0.3.29__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.
Potentially problematic release.
This version of jararaca might be problematic. Click here for more details.
- jararaca/__init__.py +24 -0
- jararaca/observability/constants.py +3 -0
- jararaca/observability/decorators.py +21 -2
- jararaca/observability/fastapi_exception_handler.py +33 -0
- jararaca/observability/hooks.py +51 -2
- jararaca/observability/providers/otel.py +46 -4
- {jararaca-0.3.26.dist-info → jararaca-0.3.29.dist-info}/METADATA +1 -1
- {jararaca-0.3.26.dist-info → jararaca-0.3.29.dist-info}/RECORD +12 -10
- pyproject.toml +1 -1
- {jararaca-0.3.26.dist-info → jararaca-0.3.29.dist-info}/LICENSE +0 -0
- {jararaca-0.3.26.dist-info → jararaca-0.3.29.dist-info}/WHEEL +0 -0
- {jararaca-0.3.26.dist-info → jararaca-0.3.29.dist-info}/entry_points.txt +0 -0
jararaca/__init__.py
CHANGED
|
@@ -18,12 +18,20 @@ if TYPE_CHECKING:
|
|
|
18
18
|
use_app_type,
|
|
19
19
|
)
|
|
20
20
|
from jararaca.observability.decorators import TracedClass, TracedFunc, traced_class
|
|
21
|
+
from jararaca.observability.fastapi_exception_handler import (
|
|
22
|
+
setup_fastapi_exception_handler,
|
|
23
|
+
)
|
|
21
24
|
from jararaca.observability.hooks import (
|
|
22
25
|
add_event,
|
|
26
|
+
add_span_link,
|
|
27
|
+
get_current_span,
|
|
28
|
+
get_current_span_context,
|
|
23
29
|
get_tracing_provider,
|
|
24
30
|
record_exception,
|
|
31
|
+
set_span_attribute,
|
|
25
32
|
set_span_status,
|
|
26
33
|
spawn_trace,
|
|
34
|
+
start_span,
|
|
27
35
|
)
|
|
28
36
|
from jararaca.observability.interceptor import ObservabilityInterceptor
|
|
29
37
|
from jararaca.observability.providers.otel import OtelObservabilityProvider
|
|
@@ -233,8 +241,14 @@ if TYPE_CHECKING:
|
|
|
233
241
|
"TracedFunc",
|
|
234
242
|
"TracedClass",
|
|
235
243
|
"traced_class",
|
|
244
|
+
"start_span",
|
|
245
|
+
"add_span_link",
|
|
246
|
+
"get_current_span",
|
|
247
|
+
"get_current_span_context",
|
|
236
248
|
"spawn_trace",
|
|
249
|
+
"set_span_attribute",
|
|
237
250
|
"add_event",
|
|
251
|
+
"setup_fastapi_exception_handler",
|
|
238
252
|
"set_span_status",
|
|
239
253
|
"record_exception",
|
|
240
254
|
"get_tracing_provider",
|
|
@@ -412,6 +426,16 @@ _dynamic_imports: "dict[str, tuple[str, str, str | None]]" = {
|
|
|
412
426
|
"TracedClass": (__SPEC_PARENT__, "observability.decorators", None),
|
|
413
427
|
"traced_class": (__SPEC_PARENT__, "observability.decorators", None),
|
|
414
428
|
"spawn_trace": (__SPEC_PARENT__, "observability.hooks", None),
|
|
429
|
+
"setup_fastapi_exception_handler": (
|
|
430
|
+
__SPEC_PARENT__,
|
|
431
|
+
"observability.fastapi_exception_handler",
|
|
432
|
+
None,
|
|
433
|
+
),
|
|
434
|
+
"set_span_attribute": (__SPEC_PARENT__, "observability.hooks", None),
|
|
435
|
+
"start_span": (__SPEC_PARENT__, "observability.hooks", None),
|
|
436
|
+
"add_span_link": (__SPEC_PARENT__, "observability.hooks", None),
|
|
437
|
+
"get_current_span": (__SPEC_PARENT__, "observability.hooks", None),
|
|
438
|
+
"get_current_span_context": (__SPEC_PARENT__, "observability.hooks", None),
|
|
415
439
|
"add_event": (__SPEC_PARENT__, "observability.hooks", None),
|
|
416
440
|
"set_span_status": (__SPEC_PARENT__, "observability.hooks", None),
|
|
417
441
|
"record_exception": (__SPEC_PARENT__, "observability.hooks", None),
|
|
@@ -35,9 +35,15 @@ AttributeValue = Union[
|
|
|
35
35
|
AttributeMap = Mapping[str, AttributeValue]
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
class TracingSpan(Protocol): ...
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class TracingSpanContext(Protocol): ...
|
|
42
|
+
|
|
43
|
+
|
|
38
44
|
class TracingContextProvider(Protocol):
|
|
39
45
|
|
|
40
|
-
def
|
|
46
|
+
def start_span_context(
|
|
41
47
|
self, trace_name: str, context_attributes: AttributeMap | None
|
|
42
48
|
) -> ContextManager[Any]: ...
|
|
43
49
|
|
|
@@ -56,6 +62,19 @@ class TracingContextProvider(Protocol):
|
|
|
56
62
|
escaped: bool = False,
|
|
57
63
|
) -> None: ...
|
|
58
64
|
|
|
65
|
+
def set_span_attribute(
|
|
66
|
+
self,
|
|
67
|
+
key: str,
|
|
68
|
+
value: AttributeValue,
|
|
69
|
+
) -> None: ...
|
|
70
|
+
|
|
71
|
+
def update_span_name(self, new_name: str) -> None: ...
|
|
72
|
+
|
|
73
|
+
def add_link(self, span_context: TracingSpanContext) -> None: ...
|
|
74
|
+
|
|
75
|
+
def get_current_span(self) -> TracingSpan | None: ...
|
|
76
|
+
def get_current_span_context(self) -> TracingSpanContext | None: ...
|
|
77
|
+
|
|
59
78
|
|
|
60
79
|
class TracingContextProviderFactory(Protocol):
|
|
61
80
|
|
|
@@ -117,7 +136,7 @@ class TracedFunc:
|
|
|
117
136
|
) -> Any:
|
|
118
137
|
|
|
119
138
|
if ctx_provider := get_tracing_ctx_provider():
|
|
120
|
-
with ctx_provider.
|
|
139
|
+
with ctx_provider.start_span_context(
|
|
121
140
|
self.trace_name,
|
|
122
141
|
self.trace_mapper(*args, **kwargs),
|
|
123
142
|
):
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from fastapi import FastAPI, Request, Response
|
|
2
|
+
from fastapi.exception_handlers import (
|
|
3
|
+
http_exception_handler,
|
|
4
|
+
request_validation_exception_handler,
|
|
5
|
+
)
|
|
6
|
+
from fastapi.exceptions import RequestValidationError
|
|
7
|
+
from fastapi.responses import JSONResponse
|
|
8
|
+
from starlette.exceptions import HTTPException
|
|
9
|
+
|
|
10
|
+
from jararaca.observability.constants import TRACEPARENT_KEY
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def setup_fastapi_exception_handler(
|
|
14
|
+
app: FastAPI, trace_header_name: str = "traceparent"
|
|
15
|
+
) -> None:
|
|
16
|
+
async def base_http_exception_handler(
|
|
17
|
+
request: Request, exc: HTTPException | RequestValidationError
|
|
18
|
+
) -> JSONResponse | Response:
|
|
19
|
+
|
|
20
|
+
if isinstance(exc, RequestValidationError):
|
|
21
|
+
response = await request_validation_exception_handler(request, exc)
|
|
22
|
+
response.headers[trace_header_name] = request.scope.get(TRACEPARENT_KEY, "")
|
|
23
|
+
return response
|
|
24
|
+
else:
|
|
25
|
+
err_response = await http_exception_handler(request, exc)
|
|
26
|
+
|
|
27
|
+
err_response.headers[trace_header_name] = request.scope.get(
|
|
28
|
+
TRACEPARENT_KEY, ""
|
|
29
|
+
)
|
|
30
|
+
return err_response
|
|
31
|
+
|
|
32
|
+
app.exception_handlers[HTTPException] = base_http_exception_handler
|
|
33
|
+
app.exception_handlers[RequestValidationError] = base_http_exception_handler
|
jararaca/observability/hooks.py
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from contextlib import contextmanager
|
|
2
3
|
from typing import Any, Generator, Literal
|
|
3
4
|
|
|
4
5
|
from jararaca.observability.decorators import (
|
|
5
6
|
AttributeMap,
|
|
7
|
+
AttributeValue,
|
|
6
8
|
TracingContextProvider,
|
|
9
|
+
TracingSpan,
|
|
10
|
+
TracingSpanContext,
|
|
7
11
|
get_tracing_ctx_provider,
|
|
8
12
|
)
|
|
9
13
|
|
|
10
14
|
|
|
11
15
|
@contextmanager
|
|
12
|
-
def
|
|
16
|
+
def start_span(
|
|
13
17
|
name: str,
|
|
14
18
|
attributes: AttributeMap | None = None,
|
|
15
19
|
) -> Generator[None, Any, None]:
|
|
16
20
|
|
|
17
21
|
if trace_context_provider := get_tracing_ctx_provider():
|
|
18
|
-
with trace_context_provider.
|
|
22
|
+
with trace_context_provider.start_span_context(
|
|
19
23
|
trace_name=name, context_attributes=attributes
|
|
20
24
|
):
|
|
21
25
|
yield
|
|
@@ -23,6 +27,19 @@ def spawn_trace(
|
|
|
23
27
|
yield
|
|
24
28
|
|
|
25
29
|
|
|
30
|
+
def spawn_trace(
|
|
31
|
+
name: str,
|
|
32
|
+
attributes: AttributeMap | None = None,
|
|
33
|
+
) -> None:
|
|
34
|
+
logging.warning(
|
|
35
|
+
"spawn_trace is deprecated, use start_span as context manager instead."
|
|
36
|
+
)
|
|
37
|
+
if trace_context_provider := get_tracing_ctx_provider():
|
|
38
|
+
trace_context_provider.start_span_context(
|
|
39
|
+
trace_name=name, context_attributes=attributes
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
26
43
|
def add_event(
|
|
27
44
|
name: str,
|
|
28
45
|
attributes: AttributeMap | None = None,
|
|
@@ -55,5 +72,37 @@ def record_exception(
|
|
|
55
72
|
)
|
|
56
73
|
|
|
57
74
|
|
|
75
|
+
def set_span_attribute(
|
|
76
|
+
key: str,
|
|
77
|
+
value: AttributeValue,
|
|
78
|
+
) -> None:
|
|
79
|
+
|
|
80
|
+
if trace_context_provider := get_tracing_ctx_provider():
|
|
81
|
+
trace_context_provider.set_span_attribute(
|
|
82
|
+
key=key,
|
|
83
|
+
value=value,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
58
87
|
def get_tracing_provider() -> TracingContextProvider | None:
|
|
59
88
|
return get_tracing_ctx_provider()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_current_span_context() -> TracingSpanContext | None:
|
|
92
|
+
|
|
93
|
+
if trace_context_provider := get_tracing_ctx_provider():
|
|
94
|
+
return trace_context_provider.get_current_span_context()
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_current_span() -> TracingSpan | None:
|
|
99
|
+
|
|
100
|
+
if trace_context_provider := get_tracing_ctx_provider():
|
|
101
|
+
return trace_context_provider.get_current_span()
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def add_span_link(span_context: TracingSpanContext) -> None:
|
|
106
|
+
|
|
107
|
+
if trace_context_provider := get_tracing_ctx_provider():
|
|
108
|
+
trace_context_provider.add_link(span_context=span_context)
|
|
@@ -34,23 +34,39 @@ from jararaca.microservice import (
|
|
|
34
34
|
Microservice,
|
|
35
35
|
use_app_transaction_context,
|
|
36
36
|
)
|
|
37
|
+
from jararaca.observability.constants import TRACEPARENT_KEY
|
|
37
38
|
from jararaca.observability.decorators import (
|
|
38
39
|
AttributeMap,
|
|
40
|
+
AttributeValue,
|
|
39
41
|
TracingContextProvider,
|
|
40
42
|
TracingContextProviderFactory,
|
|
43
|
+
TracingSpan,
|
|
44
|
+
TracingSpanContext,
|
|
41
45
|
)
|
|
42
46
|
from jararaca.observability.interceptor import ObservabilityProvider
|
|
43
47
|
|
|
44
48
|
tracer: trace.Tracer = trace.get_tracer(__name__)
|
|
45
49
|
|
|
46
50
|
|
|
51
|
+
class OtelTracingSpan(TracingSpan):
|
|
52
|
+
|
|
53
|
+
def __init__(self, span: trace.Span) -> None:
|
|
54
|
+
self.span = span
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class OtelTracingSpanContext(TracingSpanContext):
|
|
58
|
+
|
|
59
|
+
def __init__(self, span_context: trace.SpanContext) -> None:
|
|
60
|
+
self.span_context = span_context
|
|
61
|
+
|
|
62
|
+
|
|
47
63
|
class OtelTracingContextProvider(TracingContextProvider):
|
|
48
64
|
|
|
49
65
|
def __init__(self, app_context: AppTransactionContext) -> None:
|
|
50
66
|
self.app_context = app_context
|
|
51
67
|
|
|
52
68
|
@contextmanager
|
|
53
|
-
def
|
|
69
|
+
def start_span_context(
|
|
54
70
|
self,
|
|
55
71
|
trace_name: str,
|
|
56
72
|
context_attributes: AttributeMap | None,
|
|
@@ -82,6 +98,27 @@ class OtelTracingContextProvider(TracingContextProvider):
|
|
|
82
98
|
span = trace.get_current_span()
|
|
83
99
|
span.record_exception(exception, attributes=attributes, escaped=escaped)
|
|
84
100
|
|
|
101
|
+
def set_span_attribute(self, key: str, value: AttributeValue) -> None:
|
|
102
|
+
span = trace.get_current_span()
|
|
103
|
+
span.set_attribute(key, value)
|
|
104
|
+
|
|
105
|
+
def update_span_name(self, new_name: str) -> None:
|
|
106
|
+
span = trace.get_current_span()
|
|
107
|
+
|
|
108
|
+
span.update_name(new_name)
|
|
109
|
+
|
|
110
|
+
def add_link(self, span_context: TracingSpanContext) -> None:
|
|
111
|
+
if not isinstance(span_context, OtelTracingSpanContext):
|
|
112
|
+
return
|
|
113
|
+
span = trace.get_current_span()
|
|
114
|
+
span.add_link(span_context.span_context)
|
|
115
|
+
|
|
116
|
+
def get_current_span(self) -> TracingSpan | None:
|
|
117
|
+
return OtelTracingSpan(trace.get_current_span())
|
|
118
|
+
|
|
119
|
+
def get_current_span_context(self) -> TracingSpanContext | None:
|
|
120
|
+
return OtelTracingSpanContext(trace.get_current_span().get_span_context())
|
|
121
|
+
|
|
85
122
|
|
|
86
123
|
class OtelTracingContextProviderFactory(TracingContextProviderFactory):
|
|
87
124
|
|
|
@@ -185,10 +222,15 @@ class OtelTracingContextProviderFactory(TracingContextProviderFactory):
|
|
|
185
222
|
},
|
|
186
223
|
) as root_span:
|
|
187
224
|
cx = root_span.get_span_context()
|
|
225
|
+
span_traceparent_id = hex(cx.trace_id)[2:].rjust(32, "0")
|
|
188
226
|
if app_tx_ctx.transaction_data.context_type == "http":
|
|
189
|
-
app_tx_ctx.transaction_data.
|
|
190
|
-
|
|
191
|
-
)
|
|
227
|
+
app_tx_ctx.transaction_data.request.scope[TRACEPARENT_KEY] = (
|
|
228
|
+
span_traceparent_id
|
|
229
|
+
)
|
|
230
|
+
elif app_tx_ctx.transaction_data.context_type == "websocket":
|
|
231
|
+
app_tx_ctx.transaction_data.websocket.scope[TRACEPARENT_KEY] = (
|
|
232
|
+
span_traceparent_id
|
|
233
|
+
)
|
|
192
234
|
tracing_headers: ImplicitHeaders = {}
|
|
193
235
|
TraceContextTextMapPropagator().inject(tracing_headers)
|
|
194
236
|
W3CBaggagePropagator().inject(tracing_headers)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
2
2
|
README.md,sha256=YmCngjU8llW0l7L3tuXkkfr8qH7V9aBMgfp2jEzeiKg,3517
|
|
3
|
-
pyproject.toml,sha256=
|
|
4
|
-
jararaca/__init__.py,sha256=
|
|
3
|
+
pyproject.toml,sha256=onnmUnr1FXl1m5F5BLHvwPeJjoQrCzetXPaqxh7F2Ao,2739
|
|
4
|
+
jararaca/__init__.py,sha256=LH6u63yz8UTABwH4EMSrOprxw6Szn0nQWJB5A9U4VjY,24259
|
|
5
5
|
jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
|
|
6
6
|
jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
|
|
7
7
|
jararaca/broker_backend/mapper.py,sha256=vTsi7sWpNvlga1PWPFg0rCJ5joJ0cdzykkIc2Tuvenc,696
|
|
@@ -26,11 +26,13 @@ jararaca/messagebus/message.py,sha256=U6cyd2XknX8mtm0333slz5fanky2PFLWCmokAO56vv
|
|
|
26
26
|
jararaca/messagebus/publisher.py,sha256=JTkxdKbvxvDWT8nK8PVEyyX061vYYbKQMxRHXrZtcEY,2173
|
|
27
27
|
jararaca/messagebus/worker.py,sha256=DiKDUhcU4rEjjA_3KqCmnN3X5yyokZq_-SbLryjS_PM,69237
|
|
28
28
|
jararaca/microservice.py,sha256=DW4RVeqgrx4J-dAg17sbzTn_sLXuvV1UOQFde2fpqds,11471
|
|
29
|
-
jararaca/observability/
|
|
30
|
-
jararaca/observability/
|
|
29
|
+
jararaca/observability/constants.py,sha256=quhqXBjDWVrr8Vr3tglgYo7zsQyz_y-z_dtqfUzYaa8,63
|
|
30
|
+
jararaca/observability/decorators.py,sha256=1mxIhBduikOYayq-cW9Pq1hbTzztUkjx0uzKJSSMEU4,6511
|
|
31
|
+
jararaca/observability/fastapi_exception_handler.py,sha256=jSLhuR5Og3vRnIoZucRA5jPnvR6DEsM1ax7tQuEo5rc,1264
|
|
32
|
+
jararaca/observability/hooks.py,sha256=RRv5q57bRurOUR4AIZpl1K07j9tSduj6LrBNc4xwfRs,2778
|
|
31
33
|
jararaca/observability/interceptor.py,sha256=U4ZLM0f8j6Q7gMUKKnA85bnvD-Qa0ii79Qa_X8KsXAQ,1498
|
|
32
34
|
jararaca/observability/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
-
jararaca/observability/providers/otel.py,sha256=
|
|
35
|
+
jararaca/observability/providers/otel.py,sha256=08G1-dHzckKo9DQiteJl8KUukH_5tL31b2YrTDEnuDA,12262
|
|
34
36
|
jararaca/persistence/base.py,sha256=xnGUbsLNz3gO-9iJt-Sn5NY13Yc9-misP8wLwQuGGoM,1024
|
|
35
37
|
jararaca/persistence/exports.py,sha256=Ghx4yoFaB4QVTb9WxrFYgmcSATXMNvrOvT8ybPNKXCA,62
|
|
36
38
|
jararaca/persistence/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -76,8 +78,8 @@ jararaca/tools/typescript/interface_parser.py,sha256=VBx-TYQPjAiHLiYgzGdRl_p4xDb
|
|
|
76
78
|
jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
79
|
jararaca/utils/rabbitmq_utils.py,sha256=ytdAFUyv-OBkaVnxezuJaJoLrmN7giZgtKeet_IsMBs,10918
|
|
78
80
|
jararaca/utils/retry.py,sha256=DzPX_fXUvTqej6BQ8Mt2dvLo9nNlTBm7Kx2pFZ26P2Q,4668
|
|
79
|
-
jararaca-0.3.
|
|
80
|
-
jararaca-0.3.
|
|
81
|
-
jararaca-0.3.
|
|
82
|
-
jararaca-0.3.
|
|
83
|
-
jararaca-0.3.
|
|
81
|
+
jararaca-0.3.29.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
82
|
+
jararaca-0.3.29.dist-info/METADATA,sha256=SF-nYBMhJ-gK7OxaQ3Y75sVExlh7vCcyldV5hWT1NBg,5149
|
|
83
|
+
jararaca-0.3.29.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
84
|
+
jararaca-0.3.29.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
|
|
85
|
+
jararaca-0.3.29.dist-info/RECORD,,
|
pyproject.toml
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|