warpzone-sdk 15.0.0.dev3__tar.gz → 15.0.0.dev5__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.
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/PKG-INFO +1 -1
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/pyproject.toml +1 -1
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/monitor.py +14 -28
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/monitor/logs.py +12 -2
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/monitor/traces.py +24 -11
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/README.md +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/blobstorage/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/blobstorage/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/db/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/db/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/data_types.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/generated_columns.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/lock_client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/schema.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/slicing.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/store.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/table.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/enums/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/enums/topicenum.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/checks.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/functionize.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/integrations.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/process.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/dependencies.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/outputs.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/triggers.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/signature.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/types.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/healthchecks/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/healthchecks/model.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/monitor/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/data/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/data/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/events/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/events/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/events/triggers.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/base_client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/table_config.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/client.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/entities.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/helpers.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/testing/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/testing/assertions.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/testing/data.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/testing/matchers.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tools/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tools/copy.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/transform/__init__.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/transform/data.py +0 -0
- {warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/transform/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: warpzone-sdk
|
|
3
|
-
Version: 15.0.0.
|
|
3
|
+
Version: 15.0.0.dev5
|
|
4
4
|
Summary: The main objective of this package is to centralize logic used to interact with Azure Functions, Azure Service Bus and Azure Table Storage
|
|
5
5
|
Author: Team Enigma
|
|
6
6
|
Author-email: enigma@energinet.dk
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "warpzone-sdk"
|
|
3
|
-
version = "15.0.0.
|
|
3
|
+
version = "15.0.0.dev5"
|
|
4
4
|
description = "The main objective of this package is to centralize logic used to interact with Azure Functions, Azure Service Bus and Azure Table Storage"
|
|
5
5
|
authors = [{ name = "Team Enigma", email = "enigma@energinet.dk" }]
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -7,41 +7,29 @@ from azure.monitor.opentelemetry import configure_azure_monitor
|
|
|
7
7
|
from opentelemetry import trace
|
|
8
8
|
|
|
9
9
|
from warpzone.function.types import SingleArgumentCallable
|
|
10
|
-
from warpzone.monitor import
|
|
10
|
+
from warpzone.monitor import traces
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _ensure_monitor_configured():
|
|
17
|
-
"""Configure Azure Monitor lazily on first use to ensure proper trace context."""
|
|
18
|
-
global _monitor_configured
|
|
19
|
-
if not _monitor_configured:
|
|
20
|
-
configure_azure_monitor()
|
|
21
|
-
|
|
22
|
-
# Apply trace filtering to suppress all Azure SDK traces except Service Bus
|
|
23
|
-
tracer_provider = trace.get_tracer_provider()
|
|
24
|
-
if hasattr(tracer_provider, "_active_span_processor"):
|
|
25
|
-
# Wrap the existing span processor with our filter
|
|
26
|
-
original_processor = tracer_provider._active_span_processor
|
|
27
|
-
filtered_processor = traces.AzureSDKTraceFilter(original_processor)
|
|
28
|
-
tracer_provider._active_span_processor = filtered_processor
|
|
29
|
-
|
|
30
|
-
_monitor_configured = True
|
|
12
|
+
# Configure Azure Monitor at import to ensure proper telemetry setup.
|
|
13
|
+
# The trace context is set per-invocation in run_in_trace_context to ensure
|
|
14
|
+
# proper operation ID correlation for each function execution.
|
|
15
|
+
configure_azure_monitor()
|
|
31
16
|
|
|
17
|
+
# Apply trace filtering to suppress all Azure SDK traces except Service Bus
|
|
18
|
+
tracer_provider = trace.get_tracer_provider()
|
|
19
|
+
if hasattr(tracer_provider, "_active_span_processor"):
|
|
20
|
+
# Wrap the existing span processor with our filter
|
|
21
|
+
original_processor = tracer_provider._active_span_processor
|
|
22
|
+
filtered_processor = traces.AzureSDKTraceFilter(original_processor)
|
|
23
|
+
tracer_provider._active_span_processor = filtered_processor
|
|
32
24
|
|
|
33
25
|
SUBJECT_IDENTIFIER = "<Subject>"
|
|
34
26
|
|
|
35
|
-
tracer = traces.get_tracer(__name__)
|
|
36
|
-
logger = logs.get_logger(__name__)
|
|
37
|
-
|
|
38
27
|
|
|
39
28
|
@contextmanager
|
|
40
29
|
def run_in_trace_context(context: func.Context):
|
|
41
30
|
trace_context = context.trace_context
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
):
|
|
31
|
+
span_name = context.function_name or "azure_function"
|
|
32
|
+
with traces.set_trace_context(trace_context.trace_parent, span_name=span_name):
|
|
45
33
|
yield
|
|
46
34
|
|
|
47
35
|
|
|
@@ -65,13 +53,11 @@ def monitor(main: SingleArgumentCallable) -> Callable:
|
|
|
65
53
|
"""
|
|
66
54
|
|
|
67
55
|
async def wrapper_async(arg, context: func.Context):
|
|
68
|
-
_ensure_monitor_configured()
|
|
69
56
|
with run_in_trace_context(context):
|
|
70
57
|
result = await main(arg)
|
|
71
58
|
return result
|
|
72
59
|
|
|
73
60
|
def wrapper(arg, context: func.Context):
|
|
74
|
-
_ensure_monitor_configured()
|
|
75
61
|
with run_in_trace_context(context):
|
|
76
62
|
result = main(arg)
|
|
77
63
|
return result
|
|
@@ -17,8 +17,18 @@ logging.getLogger("azure.monitor.opentelemetry.exporter").setLevel(logging.WARNI
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def get_logger(name: str):
|
|
20
|
-
|
|
20
|
+
"""Get a logger instance.
|
|
21
|
+
|
|
22
|
+
The logger will automatically use the current OpenTelemetry trace context
|
|
23
|
+
for correlation in Application Insights. The trace context is set by the
|
|
24
|
+
monitor decorator's run_in_trace_context context manager.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
name: Logger name, typically __name__
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
A configured logger instance
|
|
31
|
+
"""
|
|
21
32
|
logger = logging.getLogger(name)
|
|
22
33
|
logger.setLevel(logging.INFO)
|
|
23
|
-
|
|
24
34
|
return logger
|
|
@@ -31,8 +31,15 @@ class AzureSDKTraceFilter(SpanProcessor):
|
|
|
31
31
|
|
|
32
32
|
def on_end(self, span: ReadableSpan) -> None:
|
|
33
33
|
"""Called when a span is ended. Filter based on span attributes."""
|
|
34
|
+
# Safely get span name, handling None or mock objects
|
|
35
|
+
span_name = getattr(span, "name", None)
|
|
36
|
+
if span_name is None or not isinstance(span_name, str):
|
|
37
|
+
# Pass through spans without valid names (e.g., in test mocks)
|
|
38
|
+
self.wrapped_processor.on_end(span)
|
|
39
|
+
return
|
|
40
|
+
|
|
34
41
|
# Check if service bus span - always allow
|
|
35
|
-
if "servicebus.message" in
|
|
42
|
+
if "servicebus.message" in span_name.lower():
|
|
36
43
|
self.wrapped_processor.on_end(span)
|
|
37
44
|
return
|
|
38
45
|
|
|
@@ -56,21 +63,27 @@ class AzureSDKTraceFilter(SpanProcessor):
|
|
|
56
63
|
|
|
57
64
|
|
|
58
65
|
@contextmanager
|
|
59
|
-
def set_trace_context(trace_parent: str,
|
|
60
|
-
"""Context manager for setting the trace context
|
|
66
|
+
def set_trace_context(trace_parent: str, span_name: str = "function_execution"):
|
|
67
|
+
"""Context manager for setting the trace context with a recording span.
|
|
68
|
+
|
|
69
|
+
Creates a child span of the propagated trace context. This is necessary
|
|
70
|
+
because the LoggingHandler requires a recording span to properly correlate
|
|
71
|
+
logs with the trace. A NonRecordingSpan (which is what TraceContextTextMapPropagator
|
|
72
|
+
creates) may not be correctly handled during log batching/export.
|
|
61
73
|
|
|
62
74
|
Args:
|
|
63
|
-
trace_parent (str): Trace parent ID
|
|
64
|
-
|
|
75
|
+
trace_parent (str): Trace parent ID from the incoming request
|
|
76
|
+
span_name (str): Name for the span. Defaults to "function_execution".
|
|
65
77
|
"""
|
|
66
|
-
carrier = {"traceparent": trace_parent
|
|
78
|
+
carrier = {"traceparent": trace_parent}
|
|
67
79
|
ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
# Start a recording span as a child of the propagated context.
|
|
82
|
+
# This ensures logs are properly correlated with the trace.
|
|
83
|
+
tracer = trace.get_tracer(__name__)
|
|
84
|
+
with trace.use_span(trace.get_current_span(ctx), end_on_exit=False):
|
|
85
|
+
with tracer.start_as_current_span(span_name):
|
|
86
|
+
yield
|
|
74
87
|
|
|
75
88
|
|
|
76
89
|
def get_tracer(name: str):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/deltastorage/generated_columns.py
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
|
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/__init__.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/dependencies.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/outputs.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/function/processors/triggers.py
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
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/events/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/servicebus/events/triggers.py
RENAMED
|
File without changes
|
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/base_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/db/table_config.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/__init__.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/client.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/entities.py
RENAMED
|
File without changes
|
{warpzone_sdk-15.0.0.dev3 → warpzone_sdk-15.0.0.dev5}/warpzone/tablestorage/tables/helpers.py
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
|