Skip to content

Commit 43526d6

Browse files
committed
add a simple unit test
1 parent 40e6c48 commit 43526d6

File tree

4 files changed

+87
-20
lines changed

4 files changed

+87
-20
lines changed

util/opentelemetry-util-genai/src/opentelemetry/util/genai/api.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
from uuid import UUID
1919

2020
from opentelemetry._events import get_event_logger
21-
from opentelemetry._logs import get_logger
2221
from opentelemetry.metrics import get_meter
2322
from opentelemetry.semconv.schemas import Schemas
2423
from opentelemetry.trace import get_tracer
2524

2625
from .data import ChatGeneration, Error, Message
2726
from .exporters import SpanMetricEventExporter, SpanMetricExporter
2827
from .types import LLMInvocation
28+
29+
# TODO: Get the tool version for emitting spans, use GenAI Utils for now
2930
from .version import __version__
3031

3132

@@ -60,20 +61,11 @@ def __init__(self, exporter_type_full: bool = True, **kwargs):
6061
schema_url=Schemas.V1_28_0.value,
6162
)
6263

63-
logger_provider = kwargs.get("logger_provider")
64-
self._logger = get_logger(
65-
__name__,
66-
__version__,
67-
logger_provider=logger_provider,
68-
schema_url=Schemas.V1_28_0.value,
69-
)
70-
7164
self._exporter = (
7265
SpanMetricEventExporter(
7366
tracer=self._tracer,
7467
meter=self._meter,
7568
event_logger=self._event_logger,
76-
logger=self._event_logger,
7769
)
7870
if exporter_type_full
7971
else SpanMetricExporter(tracer=self._tracer, meter=self._meter)
@@ -97,7 +89,7 @@ def start_llm(
9789
)
9890
with self._lock:
9991
self._llm_registry[invocation.run_id] = invocation
100-
self._exporter.init_llm(invocation)
92+
self._exporter.init(invocation)
10193

10294
def stop_llm(
10395
self,
@@ -110,7 +102,7 @@ def stop_llm(
110102
invocation.end_time = time.time()
111103
invocation.chat_generations = chat_generations
112104
invocation.attributes.update(attributes)
113-
self._exporter.export_llm(invocation)
105+
self._exporter.export(invocation)
114106
return invocation
115107

116108
def fail_llm(
@@ -119,8 +111,8 @@ def fail_llm(
119111
with self._lock:
120112
invocation = self._llm_registry.pop(run_id)
121113
invocation.end_time = time.time()
122-
invocation.attributes.update(attributes)
123-
self._exporter.error_llm(error, invocation)
114+
invocation.attributes.update(**attributes)
115+
self._exporter.error(error, invocation)
124116
return invocation
125117

126118

util/opentelemetry-util-genai/src/opentelemetry/util/genai/data.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ class Message:
66
content: str
77
type: str
88
name: str
9-
tool_call_id: str
109

1110

1211
@dataclass

util/opentelemetry-util-genai/src/opentelemetry/util/genai/exporters.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,9 @@ def _end_span(self, run_id: UUID):
179179
state = self.spans[run_id]
180180
for child_id in state.children:
181181
child_state = self.spans.get(child_id)
182-
if child_state and child_state.span._end_time is None:
182+
if child_state:
183183
child_state.span.end()
184-
if state.span._end_time is None:
185-
state.span.end()
184+
state.span.end()
186185

187186
def init(self, invocation: LLMInvocation):
188187
if (
@@ -481,9 +480,8 @@ def export(self, invocation: LLMInvocation):
481480

482481
for index, message in enumerate(invocation.messages):
483482
content = message.content
484-
message_type = message.type
485483
span.set_attribute(f"gen_ai.prompt.{index}.content", content)
486-
span.set_attribute(f"gen_ai.prompt.{index}.role", message_type)
484+
span.set_attribute(f"gen_ai.prompt.{index}.role", message.type)
487485

488486
for index, chat_generation in enumerate(
489487
invocation.chat_generations
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from uuid import uuid4
2+
3+
import pytest
4+
5+
from opentelemetry import trace
6+
from opentelemetry.sdk.trace import TracerProvider
7+
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
8+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
9+
InMemorySpanExporter,
10+
)
11+
from opentelemetry.util.genai.api import (
12+
llm_start,
13+
llm_stop,
14+
)
15+
from opentelemetry.util.genai.types import (
16+
ChatGeneration,
17+
Message,
18+
)
19+
20+
21+
@pytest.fixture
22+
def telemetry_setup():
23+
"""Set up telemetry providers for testing"""
24+
# Set up in-memory span exporter to capture spans
25+
memory_exporter = InMemorySpanExporter()
26+
tracer_provider = TracerProvider()
27+
tracer_provider.add_span_processor(SimpleSpanProcessor(memory_exporter))
28+
29+
# Set the tracer provider
30+
trace.set_tracer_provider(tracer_provider)
31+
32+
yield memory_exporter
33+
34+
# Cleanup
35+
memory_exporter.clear()
36+
# Reset to default tracer provider
37+
trace.set_tracer_provider(trace.NoOpTracerProvider())
38+
39+
40+
def test_llm_start_and_stop_creates_span(telemetry_setup):
41+
memory_exporter = telemetry_setup
42+
43+
run_id = uuid4()
44+
message = Message(content="hello world", type="Human", name="message name")
45+
chat_generation = ChatGeneration(content="hello back", type="AI")
46+
47+
# Start and stop LLM invocation
48+
llm_start(
49+
[message], run_id=run_id, custom_attr="value", system="test-system"
50+
)
51+
invocation = llm_stop(
52+
run_id, chat_generations=[chat_generation], extra="info"
53+
)
54+
55+
# Get the spans that were created
56+
spans = memory_exporter.get_finished_spans()
57+
58+
# Verify span was created
59+
assert len(spans) == 1
60+
span = spans[0]
61+
62+
# Verify span properties
63+
assert span.name == "test-system.chat"
64+
assert span.kind == trace.SpanKind.CLIENT
65+
66+
# Verify span attributes
67+
assert span.attributes.get("gen_ai.operation.name") == "chat"
68+
assert span.attributes.get("gen_ai.system") == "test-system"
69+
# Add more attribute checks as needed
70+
71+
# Verify span timing
72+
assert span.start_time > 0
73+
assert span.end_time > span.start_time
74+
75+
# Verify invocation data
76+
assert invocation.run_id == run_id
77+
assert invocation.attributes.get("custom_attr") == "value"
78+
assert invocation.attributes.get("extra") == "info"

0 commit comments

Comments
 (0)