microsoft-agents-a365-observability-core 0.2.1.dev35__tar.gz → 0.2.1.dev36__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.
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/PKG-INFO +1 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/__init__.py +5 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/config.py +39 -12
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/__init__.py +2 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py +0 -20
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriched_span.py +10 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/enriching_span_processor.py +30 -0
- microsoft_agents_a365_observability_core-0.2.1.dev36/microsoft_agents_a365/observability/core/exporters/spectra_exporter_options.py +56 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/PKG-INFO +1 -1
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/SOURCES.txt +1 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/README.md +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/agent_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/constants.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execute_tool_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/execution_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/exporters/utils.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_call_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_operation_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/inference_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/invoke_agent_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/middleware/baggage_builder.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/agent_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/caller_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/operation_source.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/models/response.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/opentelemetry_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/request.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/source_metadata.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/spans_scopes/output_scope.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tenant_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_call_details.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/tool_type.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/__init__.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/span_processor.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/trace_processor/util.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365/observability/core/utils.py +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/dependency_links.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/requires.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/microsoft_agents_a365_observability_core.egg-info/top_level.txt +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/pyproject.toml +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.cfg +0 -0
- {microsoft_agents_a365_observability_core-0.2.1.dev35 → microsoft_agents_a365_observability_core-0.2.1.dev36}/setup.py +0 -0
|
@@ -12,12 +12,14 @@ from .config import (
|
|
|
12
12
|
)
|
|
13
13
|
from .execute_tool_scope import ExecuteToolScope
|
|
14
14
|
from .execution_type import ExecutionType
|
|
15
|
+
from .exporters.agent365_exporter_options import Agent365ExporterOptions
|
|
15
16
|
from .exporters.enriched_span import EnrichedReadableSpan
|
|
16
17
|
from .exporters.enriching_span_processor import (
|
|
17
18
|
get_span_enricher,
|
|
18
19
|
register_span_enricher,
|
|
19
20
|
unregister_span_enricher,
|
|
20
21
|
)
|
|
22
|
+
from .exporters.spectra_exporter_options import SpectraExporterOptions
|
|
21
23
|
from .inference_call_details import InferenceCallDetails, ServiceEndpoint
|
|
22
24
|
from .inference_operation_type import InferenceOperationType
|
|
23
25
|
from .inference_scope import InferenceScope
|
|
@@ -38,6 +40,9 @@ __all__ = [
|
|
|
38
40
|
"is_configured",
|
|
39
41
|
"get_tracer",
|
|
40
42
|
"get_tracer_provider",
|
|
43
|
+
# Exporter options
|
|
44
|
+
"Agent365ExporterOptions",
|
|
45
|
+
"SpectraExporterOptions",
|
|
41
46
|
# Span enrichment
|
|
42
47
|
"register_span_enricher",
|
|
43
48
|
"unregister_span_enricher",
|
|
@@ -8,6 +8,9 @@ from collections.abc import Callable
|
|
|
8
8
|
from typing import Any, Optional
|
|
9
9
|
|
|
10
10
|
from opentelemetry import trace
|
|
11
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
|
|
12
|
+
OTLPSpanExporter as GrpcOTLPSpanExporter,
|
|
13
|
+
)
|
|
11
14
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
12
15
|
from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, Resource
|
|
13
16
|
from opentelemetry.sdk.trace import TracerProvider
|
|
@@ -18,6 +21,7 @@ from .exporters.agent365_exporter_options import Agent365ExporterOptions
|
|
|
18
21
|
from .exporters.enriching_span_processor import (
|
|
19
22
|
_EnrichingBatchSpanProcessor,
|
|
20
23
|
)
|
|
24
|
+
from .exporters.spectra_exporter_options import SpectraExporterOptions
|
|
21
25
|
from .exporters.utils import is_agent365_exporter_enabled
|
|
22
26
|
from .trace_processor.span_processor import SpanProcessor
|
|
23
27
|
|
|
@@ -58,7 +62,7 @@ class TelemetryManager:
|
|
|
58
62
|
logger_name: str = DEFAULT_LOGGER_NAME,
|
|
59
63
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
60
64
|
cluster_category: str = "prod",
|
|
61
|
-
exporter_options:
|
|
65
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
62
66
|
suppress_invoke_agent_input: bool = False,
|
|
63
67
|
**kwargs: Any,
|
|
64
68
|
) -> bool:
|
|
@@ -72,9 +76,10 @@ class TelemetryManager:
|
|
|
72
76
|
Use exporter_options instead.
|
|
73
77
|
:param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
|
|
74
78
|
Use exporter_options instead.
|
|
75
|
-
:param exporter_options: Agent365ExporterOptions
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
:param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
|
|
80
|
+
export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
|
|
81
|
+
to construct Agent365ExporterOptions from legacy parameters.
|
|
82
|
+
:param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
|
|
78
83
|
:return: True if configuration succeeded, False otherwise.
|
|
79
84
|
"""
|
|
80
85
|
try:
|
|
@@ -100,7 +105,7 @@ class TelemetryManager:
|
|
|
100
105
|
logger_name: str,
|
|
101
106
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
102
107
|
cluster_category: str = "prod",
|
|
103
|
-
exporter_options:
|
|
108
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
104
109
|
suppress_invoke_agent_input: bool = False,
|
|
105
110
|
**kwargs: Any,
|
|
106
111
|
) -> bool:
|
|
@@ -156,25 +161,43 @@ class TelemetryManager:
|
|
|
156
161
|
"max_export_batch_size": exporter_options.max_export_batch_size,
|
|
157
162
|
}
|
|
158
163
|
|
|
159
|
-
|
|
164
|
+
# Type-based exporter dispatch
|
|
165
|
+
if isinstance(exporter_options, SpectraExporterOptions):
|
|
166
|
+
# Spectra path — OTLP exporter to sidecar
|
|
167
|
+
# ENABLE_A365_OBSERVABILITY_EXPORTER is intentionally ignored.
|
|
168
|
+
if exporter_options.protocol == "grpc":
|
|
169
|
+
exporter = GrpcOTLPSpanExporter(
|
|
170
|
+
endpoint=exporter_options.endpoint,
|
|
171
|
+
insecure=exporter_options.insecure,
|
|
172
|
+
)
|
|
173
|
+
else:
|
|
174
|
+
exporter = OTLPSpanExporter(
|
|
175
|
+
endpoint=exporter_options.endpoint,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
elif is_agent365_exporter_enabled() and exporter_options.token_resolver is not None:
|
|
160
179
|
exporter = _Agent365Exporter(
|
|
161
180
|
token_resolver=exporter_options.token_resolver,
|
|
162
181
|
cluster_category=exporter_options.cluster_category,
|
|
163
182
|
use_s2s_endpoint=exporter_options.use_s2s_endpoint,
|
|
164
|
-
suppress_invoke_agent_input=suppress_invoke_agent_input,
|
|
165
183
|
)
|
|
166
184
|
|
|
167
185
|
else:
|
|
168
186
|
exporter = ConsoleSpanExporter()
|
|
169
187
|
self._logger.warning(
|
|
170
|
-
"is_agent365_exporter_enabled() not enabled or token_resolver not set.
|
|
188
|
+
"is_agent365_exporter_enabled() not enabled or token_resolver not set."
|
|
189
|
+
" Falling back to console exporter."
|
|
171
190
|
)
|
|
172
191
|
|
|
173
192
|
# Add span processors
|
|
174
193
|
|
|
175
194
|
# Create _EnrichingBatchSpanProcessor with optimized settings
|
|
176
195
|
# This allows extensions to enrich spans before export
|
|
177
|
-
batch_processor = _EnrichingBatchSpanProcessor(
|
|
196
|
+
batch_processor = _EnrichingBatchSpanProcessor(
|
|
197
|
+
exporter,
|
|
198
|
+
suppress_invoke_agent_input=suppress_invoke_agent_input,
|
|
199
|
+
**batch_processor_kwargs,
|
|
200
|
+
)
|
|
178
201
|
agent_processor = SpanProcessor()
|
|
179
202
|
|
|
180
203
|
tracer_provider.add_span_processor(batch_processor)
|
|
@@ -248,7 +271,8 @@ def configure(
|
|
|
248
271
|
logger_name: str = DEFAULT_LOGGER_NAME,
|
|
249
272
|
token_resolver: Callable[[str, str], str | None] | None = None,
|
|
250
273
|
cluster_category: str = "prod",
|
|
251
|
-
exporter_options:
|
|
274
|
+
exporter_options: Agent365ExporterOptions | SpectraExporterOptions | None = None,
|
|
275
|
+
suppress_invoke_agent_input: bool = False,
|
|
252
276
|
**kwargs: Any,
|
|
253
277
|
) -> bool:
|
|
254
278
|
"""
|
|
@@ -261,8 +285,10 @@ def configure(
|
|
|
261
285
|
Use exporter_options instead.
|
|
262
286
|
:param cluster_category: (Deprecated) Environment / cluster category (e.g. "prod").
|
|
263
287
|
Use exporter_options instead.
|
|
264
|
-
:param exporter_options: Agent365ExporterOptions
|
|
265
|
-
|
|
288
|
+
:param exporter_options: Exporter configuration. Pass Agent365ExporterOptions for A365 API
|
|
289
|
+
export, SpectraExporterOptions for Spectra Collector sidecar export, or None (default)
|
|
290
|
+
to construct Agent365ExporterOptions from legacy parameters.
|
|
291
|
+
:param suppress_invoke_agent_input: If True, suppress input messages for InvokeAgent spans.
|
|
266
292
|
:return: True if configuration succeeded, False otherwise.
|
|
267
293
|
"""
|
|
268
294
|
return _telemetry_manager.configure(
|
|
@@ -272,6 +298,7 @@ def configure(
|
|
|
272
298
|
token_resolver,
|
|
273
299
|
cluster_category,
|
|
274
300
|
exporter_options,
|
|
301
|
+
suppress_invoke_agent_input,
|
|
275
302
|
**kwargs,
|
|
276
303
|
)
|
|
277
304
|
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
# Licensed under the MIT License.
|
|
3
3
|
|
|
4
4
|
from .agent365_exporter_options import Agent365ExporterOptions
|
|
5
|
+
from .spectra_exporter_options import SpectraExporterOptions
|
|
5
6
|
|
|
6
7
|
# Agent365Exporter is not exported intentionally.
|
|
7
8
|
# It should only be used internally by the observability core module.
|
|
8
|
-
__all__ = ["Agent365ExporterOptions"]
|
|
9
|
+
__all__ = ["Agent365ExporterOptions", "SpectraExporterOptions"]
|
|
@@ -17,11 +17,6 @@ from opentelemetry.sdk.trace import ReadableSpan
|
|
|
17
17
|
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
|
18
18
|
from opentelemetry.trace import StatusCode
|
|
19
19
|
|
|
20
|
-
from ..constants import (
|
|
21
|
-
GEN_AI_INPUT_MESSAGES_KEY,
|
|
22
|
-
GEN_AI_OPERATION_NAME_KEY,
|
|
23
|
-
INVOKE_AGENT_OPERATION_NAME,
|
|
24
|
-
)
|
|
25
20
|
from .utils import (
|
|
26
21
|
build_export_url,
|
|
27
22
|
get_validated_domain_override,
|
|
@@ -59,7 +54,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
59
54
|
token_resolver: Callable[[str, str], str | None],
|
|
60
55
|
cluster_category: str = "prod",
|
|
61
56
|
use_s2s_endpoint: bool = False,
|
|
62
|
-
suppress_invoke_agent_input: bool = False,
|
|
63
57
|
):
|
|
64
58
|
if token_resolver is None:
|
|
65
59
|
raise ValueError("token_resolver must be provided.")
|
|
@@ -69,7 +63,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
69
63
|
self._token_resolver = token_resolver
|
|
70
64
|
self._cluster_category = cluster_category
|
|
71
65
|
self._use_s2s_endpoint = use_s2s_endpoint
|
|
72
|
-
self._suppress_invoke_agent_input = suppress_invoke_agent_input
|
|
73
66
|
# Read domain override once at initialization
|
|
74
67
|
self._domain_override = get_validated_domain_override()
|
|
75
68
|
|
|
@@ -270,19 +263,6 @@ class _Agent365Exporter(SpanExporter):
|
|
|
270
263
|
# attributes
|
|
271
264
|
attrs = dict(sp.attributes or {})
|
|
272
265
|
|
|
273
|
-
# Suppress input messages if configured and current span is an InvokeAgent span
|
|
274
|
-
if self._suppress_invoke_agent_input:
|
|
275
|
-
# Check if current span is an InvokeAgent span by:
|
|
276
|
-
# 1. Span name starts with "invoke_agent"
|
|
277
|
-
# 2. Has attribute gen_ai.operation.name set to INVOKE_AGENT_OPERATION_NAME
|
|
278
|
-
operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
|
|
279
|
-
if (
|
|
280
|
-
sp.name.startswith(INVOKE_AGENT_OPERATION_NAME)
|
|
281
|
-
and operation_name == INVOKE_AGENT_OPERATION_NAME
|
|
282
|
-
):
|
|
283
|
-
# Remove input messages attribute
|
|
284
|
-
attrs.pop(GEN_AI_INPUT_MESSAGES_KEY, None)
|
|
285
|
-
|
|
286
266
|
# events
|
|
287
267
|
events = []
|
|
288
268
|
for ev in sp.events:
|
|
@@ -19,22 +19,31 @@ class EnrichedReadableSpan(ReadableSpan):
|
|
|
19
19
|
the original span.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
def __init__(
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
span: ReadableSpan,
|
|
25
|
+
extra_attributes: dict,
|
|
26
|
+
excluded_attribute_keys: set[str] | None = None,
|
|
27
|
+
):
|
|
23
28
|
"""
|
|
24
29
|
Initialize the enriched span wrapper.
|
|
25
30
|
|
|
26
31
|
Args:
|
|
27
32
|
span: The original ReadableSpan to wrap.
|
|
28
33
|
extra_attributes: Additional attributes to merge with the original.
|
|
34
|
+
excluded_attribute_keys: Attribute keys to remove after merging.
|
|
29
35
|
"""
|
|
30
36
|
self._span = span
|
|
31
37
|
self._extra_attributes = extra_attributes
|
|
38
|
+
self._excluded_attribute_keys = excluded_attribute_keys or set()
|
|
32
39
|
|
|
33
40
|
@property
|
|
34
41
|
def attributes(self) -> types.Attributes:
|
|
35
42
|
"""Return merged attributes from original span and extra attributes."""
|
|
36
43
|
original = dict(self._span.attributes or {})
|
|
37
44
|
original.update(self._extra_attributes)
|
|
45
|
+
for key in self._excluded_attribute_keys:
|
|
46
|
+
original.pop(key, None)
|
|
38
47
|
return original
|
|
39
48
|
|
|
40
49
|
@property
|
|
@@ -10,6 +10,13 @@ from collections.abc import Callable
|
|
|
10
10
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
11
11
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
12
12
|
|
|
13
|
+
from ..constants import (
|
|
14
|
+
GEN_AI_INPUT_MESSAGES_KEY,
|
|
15
|
+
GEN_AI_OPERATION_NAME_KEY,
|
|
16
|
+
INVOKE_AGENT_OPERATION_NAME,
|
|
17
|
+
)
|
|
18
|
+
from .enriched_span import EnrichedReadableSpan
|
|
19
|
+
|
|
13
20
|
logger = logging.getLogger(__name__)
|
|
14
21
|
|
|
15
22
|
# Single span enricher - only one platform instrumentor should be active at a time
|
|
@@ -65,6 +72,15 @@ def get_span_enricher() -> Callable[[ReadableSpan], ReadableSpan] | None:
|
|
|
65
72
|
class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
|
|
66
73
|
"""BatchSpanProcessor that applies the registered enricher before batching."""
|
|
67
74
|
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
*args: object,
|
|
78
|
+
suppress_invoke_agent_input: bool = False,
|
|
79
|
+
**kwargs: object,
|
|
80
|
+
):
|
|
81
|
+
super().__init__(*args, **kwargs)
|
|
82
|
+
self._suppress_invoke_agent_input = suppress_invoke_agent_input
|
|
83
|
+
|
|
68
84
|
def on_end(self, span: ReadableSpan) -> None:
|
|
69
85
|
"""Apply the span enricher and pass to parent for batching.
|
|
70
86
|
|
|
@@ -83,4 +99,18 @@ class _EnrichingBatchSpanProcessor(BatchSpanProcessor):
|
|
|
83
99
|
enricher.__name__,
|
|
84
100
|
)
|
|
85
101
|
|
|
102
|
+
# Apply input message suppression for InvokeAgent spans
|
|
103
|
+
if self._suppress_invoke_agent_input:
|
|
104
|
+
attrs = enriched_span.attributes or {}
|
|
105
|
+
operation_name = attrs.get(GEN_AI_OPERATION_NAME_KEY)
|
|
106
|
+
if (
|
|
107
|
+
enriched_span.name.startswith(INVOKE_AGENT_OPERATION_NAME)
|
|
108
|
+
and operation_name == INVOKE_AGENT_OPERATION_NAME
|
|
109
|
+
):
|
|
110
|
+
enriched_span = EnrichedReadableSpan(
|
|
111
|
+
enriched_span,
|
|
112
|
+
extra_attributes={},
|
|
113
|
+
excluded_attribute_keys={GEN_AI_INPUT_MESSAGES_KEY},
|
|
114
|
+
)
|
|
115
|
+
|
|
86
116
|
super().on_end(enriched_span)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SpectraExporterOptions:
|
|
8
|
+
"""
|
|
9
|
+
Configuration for exporting traces to a Spectra Collector sidecar via OTLP.
|
|
10
|
+
|
|
11
|
+
Spectra Collector is deployed as a Kubernetes sidecar that accepts
|
|
12
|
+
standard OTLP telemetry on localhost. Defaults are tuned for this
|
|
13
|
+
deployment topology — most consumers should not need to override them.
|
|
14
|
+
|
|
15
|
+
Note: Batch processor fields (max_queue_size, scheduled_delay_ms, etc.)
|
|
16
|
+
are duplicated from Agent365ExporterOptions intentionally — these two
|
|
17
|
+
options classes have no shared base class per design decision C4.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
_DEFAULT_GRPC_ENDPOINT = "http://localhost:4317"
|
|
21
|
+
_DEFAULT_HTTP_ENDPOINT = "http://localhost:4318"
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
endpoint: str | None = None,
|
|
26
|
+
protocol: Literal["grpc", "http"] = "grpc",
|
|
27
|
+
insecure: bool = True,
|
|
28
|
+
max_queue_size: int = 2048,
|
|
29
|
+
scheduled_delay_ms: int = 5000,
|
|
30
|
+
exporter_timeout_ms: int = 30000,
|
|
31
|
+
max_export_batch_size: int = 512,
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Args:
|
|
35
|
+
endpoint: Spectra sidecar OTLP endpoint. Defaults to
|
|
36
|
+
http://localhost:4317 for gRPC or http://localhost:4318 for HTTP.
|
|
37
|
+
protocol: OTLP protocol — "grpc" or "http". Default: grpc.
|
|
38
|
+
insecure: Use insecure (no TLS) connection. Default: True (localhost sidecar).
|
|
39
|
+
max_queue_size: Batch processor queue size. Default: 2048.
|
|
40
|
+
scheduled_delay_ms: Export interval in milliseconds. Default: 5000.
|
|
41
|
+
exporter_timeout_ms: Export timeout in milliseconds. Default: 30000.
|
|
42
|
+
max_export_batch_size: Max spans per export batch. Default: 512.
|
|
43
|
+
"""
|
|
44
|
+
if protocol not in ("grpc", "http"):
|
|
45
|
+
raise ValueError(f"protocol must be 'grpc' or 'http', got '{protocol}'")
|
|
46
|
+
if endpoint is None:
|
|
47
|
+
endpoint = (
|
|
48
|
+
self._DEFAULT_GRPC_ENDPOINT if protocol == "grpc" else self._DEFAULT_HTTP_ENDPOINT
|
|
49
|
+
)
|
|
50
|
+
self.endpoint = endpoint
|
|
51
|
+
self.protocol = protocol
|
|
52
|
+
self.insecure = insecure
|
|
53
|
+
self.max_queue_size = max_queue_size
|
|
54
|
+
self.scheduled_delay_ms = scheduled_delay_ms
|
|
55
|
+
self.exporter_timeout_ms = exporter_timeout_ms
|
|
56
|
+
self.max_export_batch_size = max_export_batch_size
|
|
@@ -24,6 +24,7 @@ microsoft_agents_a365/observability/core/exporters/agent365_exporter.py
|
|
|
24
24
|
microsoft_agents_a365/observability/core/exporters/agent365_exporter_options.py
|
|
25
25
|
microsoft_agents_a365/observability/core/exporters/enriched_span.py
|
|
26
26
|
microsoft_agents_a365/observability/core/exporters/enriching_span_processor.py
|
|
27
|
+
microsoft_agents_a365/observability/core/exporters/spectra_exporter_options.py
|
|
27
28
|
microsoft_agents_a365/observability/core/exporters/utils.py
|
|
28
29
|
microsoft_agents_a365/observability/core/middleware/__init__.py
|
|
29
30
|
microsoft_agents_a365/observability/core/middleware/baggage_builder.py
|
|
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
|
|
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
|
|
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
|