Skip to content

Commit fd2cd94

Browse files
committed
fix(maf): prevent metric inflation and context breaks
1 parent be4f7d3 commit fd2cd94

7 files changed

Lines changed: 319 additions & 408 deletions

File tree

instrumentation-loongsuite/loongsuite-instrumentation-microsoft-agent-framework/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Avoid enriching non-MAF spans that use overlapping GenAI operation names.
1313
- Preserve parent-child context for legacy Microsoft Agent Framework streaming
1414
agent spans.
15+
- Stop exporting process-cumulative GenAI ObservableGauges and use Microsoft
16+
Agent Framework's native metric instruments instead.
17+
- Keep non-streaming MAF spans current for nested work and scope Robin provider
18+
suppression to the active LLM call when that optional integration is present.
1519

1620
## Version 0.7.0 (2026-07-03)
1721

instrumentation-loongsuite/loongsuite-instrumentation-microsoft-agent-framework/README.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ through ``opentelemetry-util-genai`` before spans are ended:
1515
recording. This ensures exporter snapshots include
1616
``gen_ai.span.kind``, ``gen_ai.operation.name``, normalized provider names,
1717
token usage, finish reasons, and streaming TTFT where MAF exposes enough
18-
data.
18+
data. Non-streaming spans remain current for the wrapped call, and nested
19+
Robin provider instrumentation is suppressed when its optional context key
20+
is available.
1921
* ``MAFSemanticProcessor`` remains as a compatibility layer for MAF workflow,
20-
MCP, private-prefix attribute normalization, and the in-process ARMS gauges.
21-
Successful spans keep the OpenTelemetry default ``UNSET`` status; failed
22-
spans keep MAF's ``ERROR`` status.
22+
MCP, and private-prefix attribute normalization. Metrics come from MAF's
23+
native counter and histogram instruments; this package does not export
24+
process-cumulative ObservableGauges. Successful spans keep the OpenTelemetry
25+
default ``UNSET`` status; failed spans keep MAF's ``ERROR`` status.
2326
* ``react_step_patch`` (opt-in via ``ARMS_MAF_REACT_STEP_ENABLED=true``)
2427
wraps ``FunctionInvocationLayer.get_response`` so that each LLM round-trip
2528
inside the ReAct loop emits one ``react step`` span via
@@ -56,6 +59,4 @@ Env Default Description
5659
``ARMS_MAF_INSTRUMENTATION_ENABLED`` ``true`` Master switch; ``false`` disables instrumentation.
5760
``ARMS_MAF_SENSITIVE_DATA_ENABLED`` ``false`` Capture inputs/outputs (linked to MAF's sensitive-data option).
5861
``ARMS_MAF_REACT_STEP_ENABLED`` ``false`` Emit ``react step`` spans for non-streaming ReAct tool loops.
59-
``ARMS_MAF_METRICS_ENABLED`` ``true`` Aggregate ARMS GenAI gauges in-process.
60-
``ARMS_MAF_SLOW_THRESHOLD_MS`` ``1000`` Slow-call threshold in ms.
6162
====================================== ========== ==============================================================

instrumentation-loongsuite/loongsuite-instrumentation-microsoft-agent-framework/src/opentelemetry/instrumentation/microsoft_agent_framework/__init__.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
with ``force=True`` so a sticky user-disable does not block us), bridges MAF's
1919
native span helpers through ``opentelemetry-util-genai`` finish helpers, and
2020
registers :class:`~.span_processor.MAFSemanticProcessor` for workflow/MCP
21-
normalization plus metrics aggregation.
21+
normalization. Microsoft Agent Framework's native counter and histogram
22+
instruments remain the metric source.
2223
2324
The optional ReAct step patch (``ARMS_MAF_REACT_STEP_ENABLED=true``) wraps the
2425
``FunctionInvocationLayer.get_response`` ReAct loop with
@@ -42,9 +43,7 @@
4243
from opentelemetry.trace import get_tracer_provider
4344

4445
from .config import (
45-
get_slow_threshold_ms,
4646
is_instrumentation_enabled,
47-
is_metrics_enabled,
4847
is_react_step_enabled,
4948
is_sensitive_data_enabled,
5049
)
@@ -116,20 +115,19 @@ def _instrument(self, **kwargs: Any) -> None:
116115
# invocation finish helpers. This keeps MAF's span lifetime and
117116
# streaming cleanup behavior, but writes AGENT/LLM/TOOL semantic
118117
# attributes before span.end() creates the exporter snapshot.
119-
apply_util_genai_bridge()
118+
apply_util_genai_bridge(
119+
tracer_provider=tracer_provider,
120+
meter_provider=meter_provider,
121+
)
120122

121123
# 3) Register the semantic SpanProcessor. MAF uses the standard OTel
122124
# TracerProvider (it does not have its own multi-processor), so
123125
# ``add_span_processor`` is the right hook.
124-
processor = MAFSemanticProcessor(
125-
meter_provider=meter_provider,
126-
slow_threshold_ms=get_slow_threshold_ms(),
127-
metrics_enabled=is_metrics_enabled(default=True),
128-
capture_sensitive_data=sensitive,
129-
)
126+
processor = MAFSemanticProcessor(capture_sensitive_data=sensitive)
130127
try:
131128
tracer_provider.add_span_processor(processor)
132129
except Exception as exc:
130+
revert_util_genai_bridge()
133131
logger.warning("add_span_processor failed: %s", exc)
134132
raise
135133

0 commit comments

Comments
 (0)