haiway 0.19.3__py3-none-any.whl → 0.19.4__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.
- haiway/helpers/observability.py +7 -3
- haiway/opentelemetry/observability.py +46 -46
- {haiway-0.19.3.dist-info → haiway-0.19.4.dist-info}/METADATA +1 -1
- {haiway-0.19.3.dist-info → haiway-0.19.4.dist-info}/RECORD +6 -6
- {haiway-0.19.3.dist-info → haiway-0.19.4.dist-info}/WHEEL +0 -0
- {haiway-0.19.3.dist-info → haiway-0.19.4.dist-info}/licenses/LICENSE +0 -0
haiway/helpers/observability.py
CHANGED
@@ -218,9 +218,13 @@ def LoggerObservability( # noqa: C901, PLR0915
|
|
218
218
|
)
|
219
219
|
|
220
220
|
# try complete parent scopes
|
221
|
-
|
222
|
-
|
223
|
-
|
221
|
+
if scope != root_scope:
|
222
|
+
parent_id: str = scope.parent_id
|
223
|
+
while scopes[parent_id].try_complete():
|
224
|
+
if scopes[parent_id].identifier == root_scope:
|
225
|
+
break
|
226
|
+
|
227
|
+
parent_id = scopes[parent_id].identifier.parent_id
|
224
228
|
|
225
229
|
# check for root completion
|
226
230
|
if scopes[root_scope.scope_id].completed:
|
@@ -1,17 +1,17 @@
|
|
1
1
|
import os
|
2
2
|
from collections.abc import Mapping
|
3
|
-
from typing import Any, Self, cast, final
|
3
|
+
from typing import Any, ClassVar, Self, cast, final
|
4
4
|
|
5
5
|
from opentelemetry import metrics, trace
|
6
6
|
from opentelemetry._logs import get_logger, set_logger_provider
|
7
7
|
from opentelemetry._logs._internal import Logger
|
8
8
|
from opentelemetry._logs.severity import SeverityNumber
|
9
|
-
from opentelemetry.context import Context
|
9
|
+
from opentelemetry.context import Context, attach, detach, get_current
|
10
10
|
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
|
11
11
|
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
|
12
12
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
13
13
|
from opentelemetry.metrics._internal import Meter
|
14
|
-
from opentelemetry.metrics._internal.instrument import Counter
|
14
|
+
from opentelemetry.metrics._internal.instrument import Counter
|
15
15
|
from opentelemetry.sdk._logs import LoggerProvider
|
16
16
|
from opentelemetry.sdk._logs._internal import LogRecord
|
17
17
|
from opentelemetry.sdk._logs._internal.export import (
|
@@ -21,10 +21,7 @@ from opentelemetry.sdk._logs._internal.export import (
|
|
21
21
|
)
|
22
22
|
from opentelemetry.sdk.metrics import MeterProvider as SdkMeterProvider
|
23
23
|
from opentelemetry.sdk.metrics._internal.export import MetricExporter
|
24
|
-
from opentelemetry.sdk.metrics.export import
|
25
|
-
ConsoleMetricExporter,
|
26
|
-
PeriodicExportingMetricReader,
|
27
|
-
)
|
24
|
+
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
|
28
25
|
from opentelemetry.sdk.resources import Resource
|
29
26
|
from opentelemetry.sdk.trace import TracerProvider
|
30
27
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter, SpanExporter
|
@@ -44,8 +41,8 @@ class ScopeStore:
|
|
44
41
|
"_completed",
|
45
42
|
"_counters",
|
46
43
|
"_exited",
|
47
|
-
"
|
48
|
-
"
|
44
|
+
"_token",
|
45
|
+
"context",
|
49
46
|
"identifier",
|
50
47
|
"logger",
|
51
48
|
"meter",
|
@@ -57,6 +54,7 @@ class ScopeStore:
|
|
57
54
|
self,
|
58
55
|
identifier: ScopeIdentifier,
|
59
56
|
/,
|
57
|
+
context: Context,
|
60
58
|
span: Span,
|
61
59
|
meter: Meter,
|
62
60
|
logger: Logger,
|
@@ -64,13 +62,16 @@ class ScopeStore:
|
|
64
62
|
self.identifier: ScopeIdentifier = identifier
|
65
63
|
self.nested: list[ScopeStore] = []
|
66
64
|
self._counters: dict[str, Counter] = {}
|
67
|
-
self._histograms: dict[str, Histogram] = {}
|
68
65
|
self._exited: bool = False
|
69
66
|
self._completed: bool = False
|
70
67
|
self.span: Span = span
|
71
|
-
self._span_context: SpanContext = span.get_span_context()
|
72
68
|
self.meter: Meter = meter
|
73
69
|
self.logger: Logger = logger
|
70
|
+
self.context: Context = trace.set_span_in_context(
|
71
|
+
span,
|
72
|
+
context,
|
73
|
+
)
|
74
|
+
self._token: Any = attach(self.context)
|
74
75
|
|
75
76
|
@property
|
76
77
|
def exited(self) -> bool:
|
@@ -96,6 +97,8 @@ class ScopeStore:
|
|
96
97
|
|
97
98
|
self._completed = True
|
98
99
|
self.span.end()
|
100
|
+
|
101
|
+
detach(self._token)
|
99
102
|
return True # successfully completed
|
100
103
|
|
101
104
|
def record_log(
|
@@ -104,11 +107,12 @@ class ScopeStore:
|
|
104
107
|
/,
|
105
108
|
level: ObservabilityLevel,
|
106
109
|
) -> None:
|
110
|
+
span_context: SpanContext = self.span.get_span_context()
|
107
111
|
self.logger.emit(
|
108
112
|
LogRecord(
|
109
|
-
span_id=
|
110
|
-
trace_id=
|
111
|
-
trace_flags=
|
113
|
+
span_id=span_context.span_id,
|
114
|
+
trace_id=span_context.trace_id,
|
115
|
+
trace_flags=span_context.trace_flags,
|
112
116
|
body=message,
|
113
117
|
severity_text=level.name,
|
114
118
|
severity_number=SEVERITY_MAPPING[level],
|
@@ -174,14 +178,15 @@ class ScopeStore:
|
|
174
178
|
},
|
175
179
|
)
|
176
180
|
|
177
|
-
def
|
181
|
+
def record_attributes(
|
178
182
|
self,
|
179
|
-
|
183
|
+
attributes: Mapping[str, ObservabilityAttribute],
|
180
184
|
/,
|
181
|
-
*,
|
182
|
-
value: ObservabilityAttribute,
|
183
185
|
) -> None:
|
184
|
-
|
186
|
+
for name, value in attributes.items():
|
187
|
+
if value is None or value is MISSING:
|
188
|
+
continue
|
189
|
+
|
185
190
|
self.span.set_attribute(
|
186
191
|
name,
|
187
192
|
value=cast(Any, value),
|
@@ -190,6 +195,9 @@ class ScopeStore:
|
|
190
195
|
|
191
196
|
@final
|
192
197
|
class OpenTelemetry:
|
198
|
+
service: ClassVar[str]
|
199
|
+
environment: ClassVar[str]
|
200
|
+
|
193
201
|
@classmethod
|
194
202
|
def configure(
|
195
203
|
cls,
|
@@ -199,9 +207,11 @@ class OpenTelemetry:
|
|
199
207
|
environment: str,
|
200
208
|
otlp_endpoint: str | None = None,
|
201
209
|
insecure: bool = True,
|
202
|
-
export_interval_millis: int =
|
210
|
+
export_interval_millis: int = 5000,
|
203
211
|
attributes: Mapping[str, Any] | None = None,
|
204
212
|
) -> type[Self]:
|
213
|
+
cls.service = service
|
214
|
+
cls.environment = environment
|
205
215
|
# Create shared resource for both metrics and traces
|
206
216
|
resource: Resource = Resource.create(
|
207
217
|
{
|
@@ -274,7 +284,7 @@ class OpenTelemetry:
|
|
274
284
|
cls,
|
275
285
|
level: ObservabilityLevel = ObservabilityLevel.INFO,
|
276
286
|
) -> Observability:
|
277
|
-
tracer: Tracer
|
287
|
+
tracer: Tracer = trace.get_tracer(cls.service)
|
278
288
|
meter: Meter | None = None
|
279
289
|
root_scope: ScopeIdentifier | None = None
|
280
290
|
scopes: dict[str, ScopeStore] = {}
|
@@ -355,17 +365,12 @@ class OpenTelemetry:
|
|
355
365
|
if not attributes:
|
356
366
|
return
|
357
367
|
|
358
|
-
|
359
|
-
scopes[scope.scope_id].record_attribute(
|
360
|
-
attribute,
|
361
|
-
value=value,
|
362
|
-
)
|
368
|
+
scopes[scope.scope_id].record_attributes(attributes)
|
363
369
|
|
364
370
|
def scope_entering[Metric: State](
|
365
371
|
scope: ScopeIdentifier,
|
366
372
|
/,
|
367
373
|
) -> None:
|
368
|
-
nonlocal tracer
|
369
374
|
assert scope.scope_id not in scopes # nosec: B101
|
370
375
|
|
371
376
|
nonlocal root_scope
|
@@ -373,17 +378,14 @@ class OpenTelemetry:
|
|
373
378
|
|
374
379
|
scope_store: ScopeStore
|
375
380
|
if root_scope is None:
|
376
|
-
tracer = trace.get_tracer(scope.trace_id)
|
377
381
|
meter = metrics.get_meter(scope.trace_id)
|
382
|
+
context: Context = get_current()
|
378
383
|
scope_store = ScopeStore(
|
379
384
|
scope,
|
385
|
+
context=context,
|
380
386
|
span=tracer.start_span(
|
381
387
|
name=scope.label,
|
382
|
-
context=
|
383
|
-
trace_id=scope.trace_id,
|
384
|
-
scope_id=scope.scope_id,
|
385
|
-
parent_id=scope.parent_id,
|
386
|
-
),
|
388
|
+
context=context,
|
387
389
|
attributes={
|
388
390
|
"context.trace_id": scope.trace_id,
|
389
391
|
"context.scope_id": scope.scope_id,
|
@@ -396,21 +398,13 @@ class OpenTelemetry:
|
|
396
398
|
root_scope = scope
|
397
399
|
|
398
400
|
else:
|
399
|
-
assert tracer is not None # nosec: B101
|
400
401
|
assert meter is not None # nosec: B101
|
401
|
-
|
402
402
|
scope_store = ScopeStore(
|
403
403
|
scope,
|
404
|
+
context=scopes[scope.parent_id].context,
|
404
405
|
span=tracer.start_span(
|
405
406
|
name=scope.label,
|
406
|
-
context=
|
407
|
-
scopes[scope.parent_id].span,
|
408
|
-
Context(
|
409
|
-
trace_id=scope.trace_id,
|
410
|
-
scope_id=scope.scope_id,
|
411
|
-
parent_id=scope.parent_id,
|
412
|
-
),
|
413
|
-
),
|
407
|
+
context=scopes[scope.parent_id].context,
|
414
408
|
attributes={
|
415
409
|
"context.trace_id": scope.trace_id,
|
416
410
|
"context.scope_id": scope.scope_id,
|
@@ -432,6 +426,7 @@ class OpenTelemetry:
|
|
432
426
|
) -> None:
|
433
427
|
nonlocal root_scope
|
434
428
|
nonlocal scopes
|
429
|
+
nonlocal meter
|
435
430
|
assert root_scope is not None # nosec: B101
|
436
431
|
assert scope.scope_id in scopes # nosec: B101
|
437
432
|
|
@@ -446,14 +441,19 @@ class OpenTelemetry:
|
|
446
441
|
return # not completed yet or already completed
|
447
442
|
|
448
443
|
# try complete parent scopes
|
449
|
-
|
450
|
-
|
451
|
-
|
444
|
+
if scope != root_scope:
|
445
|
+
parent_id: str = scope.parent_id
|
446
|
+
while scopes[parent_id].try_complete():
|
447
|
+
if scopes[parent_id].identifier == root_scope:
|
448
|
+
break
|
449
|
+
|
450
|
+
parent_id = scopes[parent_id].identifier.parent_id
|
452
451
|
|
453
452
|
# check for root completion
|
454
453
|
if scopes[root_scope.scope_id].completed:
|
455
454
|
# finished root - cleanup state
|
456
455
|
root_scope = None
|
456
|
+
meter = None
|
457
457
|
scopes = {}
|
458
458
|
|
459
459
|
return Observability(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: haiway
|
3
|
-
Version: 0.19.
|
3
|
+
Version: 0.19.4
|
4
4
|
Summary: Framework for dependency injection and state management within structured concurrency model.
|
5
5
|
Project-URL: Homepage, https://miquido.com
|
6
6
|
Project-URL: Repository, https://github.com/miquido/haiway.git
|
@@ -11,13 +11,13 @@ haiway/context/types.py,sha256=WulPvpqUbI1vYyny-s2NItldDnk3zh1O-n_hGibFZRY,142
|
|
11
11
|
haiway/helpers/__init__.py,sha256=dYqwWSBk8ss9XyXEF6YHZNPrCwU8VDM4nKtcz1tsvZI,583
|
12
12
|
haiway/helpers/asynchrony.py,sha256=k_A0yCWUKSFfzYZ8WvqK4wqTMljv6ykMivmERrDLHIU,6266
|
13
13
|
haiway/helpers/caching.py,sha256=N60FBFfSoOdSUI6S49l47G6T1j-y9tc3qhU5msSRdPM,13221
|
14
|
-
haiway/helpers/observability.py,sha256=
|
14
|
+
haiway/helpers/observability.py,sha256=hahA7jgGj5TH6mYBm3bKVwI22Fseuh-IX6X487gueaU,7977
|
15
15
|
haiway/helpers/retries.py,sha256=unssUKBDOENvquh6R4Ud65TuSKl4mTHgZ5N_b7mAYa4,7533
|
16
16
|
haiway/helpers/throttling.py,sha256=U6HJvSzffw47730VeiXxXSW4VVxpDx48k0oIAOpL-O4,4115
|
17
17
|
haiway/helpers/timeouted.py,sha256=_M8diuD_GN49pl5KQA5fMKn4iUHsUuhkDSatAwWXiK8,3331
|
18
18
|
haiway/helpers/tracing.py,sha256=6724MnXDqVcdWiQh0ggZRC3s5ZZSp6LEtLh3uze8SS0,4264
|
19
19
|
haiway/opentelemetry/__init__.py,sha256=TV-1C14mDAtcHhFZ29ActFQdrGH6x5KuGV9w-JlKYJg,91
|
20
|
-
haiway/opentelemetry/observability.py,sha256=
|
20
|
+
haiway/opentelemetry/observability.py,sha256=_VIhPRk8zfpww5YB-Tvct9R-J7oge-tTs20Zlj_0Dto,15245
|
21
21
|
haiway/state/__init__.py,sha256=AaMqlMhO4zKS_XNevy3A7BHh5PxmguA-Sk_FnaNDY1Q,355
|
22
22
|
haiway/state/attributes.py,sha256=p6jUBzg62bOl0zAYTCa7NIllsaNY2Kt68IooQ9tb-y8,23311
|
23
23
|
haiway/state/path.py,sha256=-IpbUpF2QHWg3hEITkWYHJ6ZPoRVixu-SOSuWk-bbBY,21318
|
@@ -39,7 +39,7 @@ haiway/utils/mimic.py,sha256=L5AS4WEL2aPMZAQZlvLvRzHl0cipI7ivky60_eL4iwY,1822
|
|
39
39
|
haiway/utils/noop.py,sha256=f54PSLHGEwCQNYXQHkPAW5NDE-tk5yjzkNL1pZj0TJQ,344
|
40
40
|
haiway/utils/queue.py,sha256=YTvCn3wgSwLJiLqolMx44sa3304Xkv3tJG77gvfWnZs,4114
|
41
41
|
haiway/utils/stream.py,sha256=Mjhy2S-ZDR1g_NsgS_nuBA8AgVbhrGXKvG3wjJ5mCJQ,2826
|
42
|
-
haiway-0.19.
|
43
|
-
haiway-0.19.
|
44
|
-
haiway-0.19.
|
45
|
-
haiway-0.19.
|
42
|
+
haiway-0.19.4.dist-info/METADATA,sha256=viaL8Y3MD5WkZAsNCAUtVEOaH6enHIX-FPXtTstoIhc,4527
|
43
|
+
haiway-0.19.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
44
|
+
haiway-0.19.4.dist-info/licenses/LICENSE,sha256=3phcpHVNBP8jsi77gOO0E7rgKeDeu99Pi7DSnK9YHoQ,1069
|
45
|
+
haiway-0.19.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|