Skip to content

Commit 9a15857

Browse files
Linting and logging
1 parent 57eba52 commit 9a15857

2 files changed

Lines changed: 46 additions & 10 deletions

File tree

src/sap_cloud_sdk/core/telemetry/auto_instrument.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ def _set_baggage_processor():
124124
def _set_propagated_attributes_processor():
125125
provider = trace.get_tracer_provider()
126126
if not isinstance(provider, TracerProvider):
127-
logger.warning("Unknown TracerProvider type. Skipping PropagatedAttributesSpanProcessor")
127+
logger.warning(
128+
"Unknown TracerProvider type. Skipping PropagatedAttributesSpanProcessor"
129+
)
128130
return
129131

130132
provider.add_span_processor(PropagatedAttributesSpanProcessor())

tests/core/integration/telemetry/test_telemetry_bdd.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Step definitions for telemetry.feature."""
22

3+
import logging
34
import os
45

56
from langchain_core.messages import HumanMessage
@@ -16,6 +17,8 @@
1617
)
1718
from ._agent import build_langgraph_agent
1819

20+
log = logging.getLogger(__name__)
21+
1922
# --- scenario bindings ---
2023

2124

@@ -99,22 +102,22 @@ def set_baggage(key, value):
99102
def invoke_agent_full(provider, name, cid, memory_exporter, span_store):
100103
with invoke_agent_span(provider=provider, agent_name=name, conversation_id=cid):
101104
pass
102-
span_store["last"] = _find_span(memory_exporter, f"invoke_agent {name}")
105+
span_store["last"] = _require_span(memory_exporter, f"invoke_agent {name}")
103106

104107

105108
@when("I invoke an agent that raises an exception")
106109
def invoke_agent_with_error(memory_exporter, span_store):
107110
with pytest.raises(RuntimeError):
108111
with invoke_agent_span(provider="test", agent_name="error-agent"):
109112
raise RuntimeError("deliberate test error")
110-
span_store["last"] = _find_span(memory_exporter, "invoke_agent error-agent")
113+
span_store["last"] = _require_span(memory_exporter, "invoke_agent error-agent")
111114

112115

113116
@when(parsers.parse('I invoke an agent with provider "{provider}" and name "{name}"'))
114117
def invoke_agent_named(provider, name, memory_exporter, span_store):
115118
with invoke_agent_span(provider=provider, agent_name=name):
116119
pass
117-
span_store["last"] = _find_span(memory_exporter, f"invoke_agent {name}")
120+
span_store["last"] = _require_span(memory_exporter, f"invoke_agent {name}")
118121

119122

120123
def _llm_call():
@@ -134,7 +137,9 @@ def _llm_call():
134137
def invoke_agent_wrapping_llm(memory_exporter, transforming_exporter, span_store):
135138
with invoke_agent_span(provider="sap-aicore", agent_name="llm-agent"):
136139
_llm_call()
137-
span_store["all_local_spans"] = transforming_exporter.get_finished_spans()
140+
spans = transforming_exporter.get_finished_spans()
141+
_log_spans(spans)
142+
span_store["all_local_spans"] = spans
138143

139144

140145
@when("I invoke an agent that calls an LLM then executes a tool")
@@ -143,7 +148,9 @@ def invoke_agent_llm_then_tool(memory_exporter, transforming_exporter, span_stor
143148
_llm_call()
144149
with execute_tool_span(tool_name="search", tool_type="function"):
145150
pass
146-
span_store["all_local_spans"] = transforming_exporter.get_finished_spans()
151+
spans = transforming_exporter.get_finished_spans()
152+
_log_spans(spans)
153+
span_store["all_local_spans"] = spans
147154

148155

149156
@when("I invoke an agent with propagate=True wrapping a real LLM call")
@@ -155,7 +162,9 @@ def invoke_agent_propagate_to_llm(memory_exporter, transforming_exporter, span_s
155162
propagate=True,
156163
):
157164
_llm_call()
158-
span_store["all_local_spans"] = transforming_exporter.get_finished_spans()
165+
spans = transforming_exporter.get_finished_spans()
166+
_log_spans(spans)
167+
span_store["all_local_spans"] = spans
159168

160169

161170
@when("I invoke an agent with propagate=False wrapping a real LLM call")
@@ -167,14 +176,18 @@ def invoke_agent_no_propagate_to_llm(memory_exporter, transforming_exporter, spa
167176
propagate=False,
168177
):
169178
_llm_call()
170-
span_store["all_local_spans"] = transforming_exporter.get_finished_spans()
179+
spans = transforming_exporter.get_finished_spans()
180+
_log_spans(spans)
181+
span_store["all_local_spans"] = spans
171182

172183

173184
@when("I invoke an agent wrapping a direct LLM call with baggage")
174185
def invoke_agent_wrapping_llm_with_baggage(memory_exporter, transforming_exporter, span_store):
175186
with invoke_agent_span(provider="sap-aicore", agent_name="baggage-llm-agent"):
176187
_llm_call()
177-
span_store["all_local_spans"] = transforming_exporter.get_finished_spans()
188+
spans = transforming_exporter.get_finished_spans()
189+
_log_spans(spans)
190+
span_store["all_local_spans"] = spans
178191

179192

180193
@when(parsers.parse('I run a LangGraph agent with provider "{provider}" and name "{name}"'))
@@ -184,8 +197,9 @@ def run_langgraph_agent(provider, name, transforming_exporter, span_store):
184197
span_store["root_span_id"] = root_span.get_span_context().span_id
185198
agent.invoke({"messages": [HumanMessage(content="Say hello in one word.")]})
186199
all_spans = transforming_exporter.get_finished_spans()
200+
_log_spans(all_spans)
187201
span_store["all_spans"] = all_spans
188-
span_store["last"] = _find_span_in(all_spans, f"invoke_agent {name}")
202+
span_store["last"] = _require_span_in(all_spans, f"invoke_agent {name}")
189203

190204

191205
# --- then steps ---
@@ -357,10 +371,30 @@ def _find_span(exporter: InMemorySpanExporter, name: str) -> ReadableSpan | None
357371
return _find_span_in(exporter.get_finished_spans(), name)
358372

359373

374+
def _require_span(exporter: InMemorySpanExporter, name: str) -> ReadableSpan:
375+
spans = exporter.get_finished_spans()
376+
return _require_span_in(spans, name)
377+
378+
360379
def _find_span_in(spans: list[ReadableSpan], name: str) -> ReadableSpan | None:
361380
return next((s for s in spans if s.name == name), None)
362381

363382

383+
def _require_span_in(spans: list[ReadableSpan], name: str) -> ReadableSpan:
384+
span = _find_span_in(spans, name)
385+
assert span is not None, (
386+
f"No span named '{name}' found.\n"
387+
f"Recorded spans: {[s.name for s in spans]}"
388+
)
389+
return span
390+
391+
392+
def _log_spans(spans: list[ReadableSpan]) -> None:
393+
log.info("Collected %d span(s):", len(spans))
394+
for s in spans:
395+
log.info(" [%s] attrs=%s", s.name, dict(s.attributes or {}))
396+
397+
364398
def _get_descendants(all_spans: list[ReadableSpan], root_span_id: int) -> list[ReadableSpan]:
365399
return [
366400
s for s in all_spans

0 commit comments

Comments
 (0)