mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-10-04 12:07:34 +00:00
fix(pr specific): passes pre-commit
This commit is contained in:
parent
4aa2dc110d
commit
2b7a765d02
20 changed files with 547 additions and 516 deletions
|
@ -41,17 +41,17 @@ class TestOTelTelemetryProviderInitialization:
|
|||
def test_initialization_with_valid_config(self, otel_config, monkeypatch):
|
||||
"""Test that provider initializes correctly with valid configuration."""
|
||||
monkeypatch.setenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4318")
|
||||
|
||||
|
||||
provider = OTelTelemetryProvider(config=otel_config)
|
||||
|
||||
|
||||
assert provider.config == otel_config
|
||||
|
||||
def test_initialization_sets_service_attributes(self, otel_config, monkeypatch):
|
||||
"""Test that service attributes are properly configured."""
|
||||
monkeypatch.setenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4318")
|
||||
|
||||
|
||||
provider = OTelTelemetryProvider(config=otel_config)
|
||||
|
||||
|
||||
assert provider.config.service_name == "test-service"
|
||||
assert provider.config.service_version == "1.0.0"
|
||||
assert provider.config.deployment_environment == "test"
|
||||
|
@ -65,9 +65,9 @@ class TestOTelTelemetryProviderInitialization:
|
|||
deployment_environment="test",
|
||||
span_processor="batch",
|
||||
)
|
||||
|
||||
|
||||
provider = OTelTelemetryProvider(config=config)
|
||||
|
||||
|
||||
assert provider.config.span_processor == "batch"
|
||||
|
||||
def test_warns_when_endpoints_missing(self, otel_config, monkeypatch, caplog):
|
||||
|
@ -76,9 +76,9 @@ class TestOTelTelemetryProviderInitialization:
|
|||
monkeypatch.delenv("OTEL_EXPORTER_OTLP_ENDPOINT", raising=False)
|
||||
monkeypatch.delenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", raising=False)
|
||||
monkeypatch.delenv("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT", raising=False)
|
||||
|
||||
|
||||
OTelTelemetryProvider(config=otel_config)
|
||||
|
||||
|
||||
# Check that warnings were logged
|
||||
assert any("Traces will not be exported" in record.message for record in caplog.records)
|
||||
assert any("Metrics will not be exported" in record.message for record in caplog.records)
|
||||
|
@ -90,44 +90,41 @@ class TestOTelTelemetryProviderTracerAPI:
|
|||
def test_get_tracer_returns_tracer(self, otel_provider):
|
||||
"""Test that get_tracer returns a valid Tracer instance."""
|
||||
tracer = otel_provider.get_tracer("test.module")
|
||||
|
||||
|
||||
assert tracer is not None
|
||||
assert isinstance(tracer, Tracer)
|
||||
|
||||
def test_get_tracer_with_version(self, otel_provider):
|
||||
"""Test that get_tracer works with version parameter."""
|
||||
tracer = otel_provider.get_tracer(
|
||||
instrumenting_module_name="test.module",
|
||||
instrumenting_library_version="1.0.0"
|
||||
instrumenting_module_name="test.module", instrumenting_library_version="1.0.0"
|
||||
)
|
||||
|
||||
|
||||
assert tracer is not None
|
||||
assert isinstance(tracer, Tracer)
|
||||
|
||||
def test_get_tracer_with_attributes(self, otel_provider):
|
||||
"""Test that get_tracer works with attributes."""
|
||||
tracer = otel_provider.get_tracer(
|
||||
instrumenting_module_name="test.module",
|
||||
attributes={"component": "test", "tier": "backend"}
|
||||
instrumenting_module_name="test.module", attributes={"component": "test", "tier": "backend"}
|
||||
)
|
||||
|
||||
|
||||
assert tracer is not None
|
||||
assert isinstance(tracer, Tracer)
|
||||
|
||||
def test_get_tracer_with_schema_url(self, otel_provider):
|
||||
"""Test that get_tracer works with schema URL."""
|
||||
tracer = otel_provider.get_tracer(
|
||||
instrumenting_module_name="test.module",
|
||||
schema_url="https://example.com/schema"
|
||||
instrumenting_module_name="test.module", schema_url="https://example.com/schema"
|
||||
)
|
||||
|
||||
|
||||
assert tracer is not None
|
||||
assert isinstance(tracer, Tracer)
|
||||
|
||||
def test_tracer_can_create_spans(self, otel_provider):
|
||||
"""Test that tracer can create spans."""
|
||||
tracer = otel_provider.get_tracer("test.module")
|
||||
|
||||
|
||||
with tracer.start_as_current_span("test.operation") as span:
|
||||
assert span is not None
|
||||
assert span.is_recording()
|
||||
|
@ -135,11 +132,8 @@ class TestOTelTelemetryProviderTracerAPI:
|
|||
def test_tracer_can_create_spans_with_attributes(self, otel_provider):
|
||||
"""Test that tracer can create spans with attributes."""
|
||||
tracer = otel_provider.get_tracer("test.module")
|
||||
|
||||
with tracer.start_as_current_span(
|
||||
"test.operation",
|
||||
attributes={"user.id": "123", "request.id": "abc"}
|
||||
) as span:
|
||||
|
||||
with tracer.start_as_current_span("test.operation", attributes={"user.id": "123", "request.id": "abc"}) as span:
|
||||
assert span is not None
|
||||
assert span.is_recording()
|
||||
|
||||
|
@ -147,7 +141,7 @@ class TestOTelTelemetryProviderTracerAPI:
|
|||
"""Test that multiple tracers can be created."""
|
||||
tracer1 = otel_provider.get_tracer("module.one")
|
||||
tracer2 = otel_provider.get_tracer("module.two")
|
||||
|
||||
|
||||
assert tracer1 is not None
|
||||
assert tracer2 is not None
|
||||
# Tracers with different names might be the same instance or different
|
||||
|
@ -164,50 +158,37 @@ class TestOTelTelemetryProviderMeterAPI:
|
|||
def test_get_meter_returns_meter(self, otel_provider):
|
||||
"""Test that get_meter returns a valid Meter instance."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
assert meter is not None
|
||||
assert isinstance(meter, Meter)
|
||||
|
||||
def test_get_meter_with_version(self, otel_provider):
|
||||
"""Test that get_meter works with version parameter."""
|
||||
meter = otel_provider.get_meter(
|
||||
name="test.meter",
|
||||
version="1.0.0"
|
||||
)
|
||||
|
||||
meter = otel_provider.get_meter(name="test.meter", version="1.0.0")
|
||||
|
||||
assert meter is not None
|
||||
assert isinstance(meter, Meter)
|
||||
|
||||
def test_get_meter_with_attributes(self, otel_provider):
|
||||
"""Test that get_meter works with attributes."""
|
||||
meter = otel_provider.get_meter(
|
||||
name="test.meter",
|
||||
attributes={"service": "test", "env": "dev"}
|
||||
)
|
||||
|
||||
meter = otel_provider.get_meter(name="test.meter", attributes={"service": "test", "env": "dev"})
|
||||
|
||||
assert meter is not None
|
||||
assert isinstance(meter, Meter)
|
||||
|
||||
def test_get_meter_with_schema_url(self, otel_provider):
|
||||
"""Test that get_meter works with schema URL."""
|
||||
meter = otel_provider.get_meter(
|
||||
name="test.meter",
|
||||
schema_url="https://example.com/schema"
|
||||
)
|
||||
|
||||
meter = otel_provider.get_meter(name="test.meter", schema_url="https://example.com/schema")
|
||||
|
||||
assert meter is not None
|
||||
assert isinstance(meter, Meter)
|
||||
|
||||
def test_meter_can_create_counter(self, otel_provider):
|
||||
"""Test that meter can create counters."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
counter = meter.create_counter(
|
||||
"test.requests.total",
|
||||
unit="requests",
|
||||
description="Total requests"
|
||||
)
|
||||
|
||||
|
||||
counter = meter.create_counter("test.requests.total", unit="requests", description="Total requests")
|
||||
|
||||
assert counter is not None
|
||||
# Test that counter can be used
|
||||
counter.add(1, {"endpoint": "/test"})
|
||||
|
@ -215,13 +196,9 @@ class TestOTelTelemetryProviderMeterAPI:
|
|||
def test_meter_can_create_histogram(self, otel_provider):
|
||||
"""Test that meter can create histograms."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
histogram = meter.create_histogram(
|
||||
"test.request.duration",
|
||||
unit="ms",
|
||||
description="Request duration"
|
||||
)
|
||||
|
||||
|
||||
histogram = meter.create_histogram("test.request.duration", unit="ms", description="Request duration")
|
||||
|
||||
assert histogram is not None
|
||||
# Test that histogram can be used
|
||||
histogram.record(42.5, {"method": "GET"})
|
||||
|
@ -229,13 +206,11 @@ class TestOTelTelemetryProviderMeterAPI:
|
|||
def test_meter_can_create_up_down_counter(self, otel_provider):
|
||||
"""Test that meter can create up/down counters."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
up_down_counter = meter.create_up_down_counter(
|
||||
"test.active.connections",
|
||||
unit="connections",
|
||||
description="Active connections"
|
||||
"test.active.connections", unit="connections", description="Active connections"
|
||||
)
|
||||
|
||||
|
||||
assert up_down_counter is not None
|
||||
# Test that up/down counter can be used
|
||||
up_down_counter.add(5)
|
||||
|
@ -244,31 +219,28 @@ class TestOTelTelemetryProviderMeterAPI:
|
|||
def test_meter_can_create_observable_gauge(self, otel_provider):
|
||||
"""Test that meter can create observable gauges."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
def gauge_callback(options):
|
||||
return [{"attributes": {"host": "localhost"}, "value": 42.0}]
|
||||
|
||||
|
||||
gauge = meter.create_observable_gauge(
|
||||
"test.memory.usage",
|
||||
callbacks=[gauge_callback],
|
||||
unit="bytes",
|
||||
description="Memory usage"
|
||||
"test.memory.usage", callbacks=[gauge_callback], unit="bytes", description="Memory usage"
|
||||
)
|
||||
|
||||
|
||||
assert gauge is not None
|
||||
|
||||
def test_multiple_instruments_from_same_meter(self, otel_provider):
|
||||
"""Test that a meter can create multiple instruments."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
counter = meter.create_counter("test.counter")
|
||||
histogram = meter.create_histogram("test.histogram")
|
||||
up_down_counter = meter.create_up_down_counter("test.gauge")
|
||||
|
||||
|
||||
assert counter is not None
|
||||
assert histogram is not None
|
||||
assert up_down_counter is not None
|
||||
|
||||
|
||||
# Verify they all work
|
||||
counter.add(1)
|
||||
histogram.record(10.0)
|
||||
|
@ -281,107 +253,101 @@ class TestOTelTelemetryProviderNativeUsage:
|
|||
def test_complete_tracing_workflow(self, otel_provider):
|
||||
"""Test a complete tracing workflow using native OTel API."""
|
||||
tracer = otel_provider.get_tracer("llama_stack.inference")
|
||||
|
||||
|
||||
# Create parent span
|
||||
with tracer.start_as_current_span("inference.request") as parent_span:
|
||||
parent_span.set_attribute("model", "llama-3.2-1b")
|
||||
parent_span.set_attribute("user", "test-user")
|
||||
|
||||
|
||||
# Create child span
|
||||
with tracer.start_as_current_span("model.load") as child_span:
|
||||
child_span.set_attribute("model.size", "1B")
|
||||
assert child_span.is_recording()
|
||||
|
||||
|
||||
# Create another child span
|
||||
with tracer.start_as_current_span("inference.execute") as child_span:
|
||||
child_span.set_attribute("tokens.input", 25)
|
||||
child_span.set_attribute("tokens.output", 150)
|
||||
assert child_span.is_recording()
|
||||
|
||||
|
||||
assert parent_span.is_recording()
|
||||
|
||||
def test_complete_metrics_workflow(self, otel_provider):
|
||||
"""Test a complete metrics workflow using native OTel API."""
|
||||
meter = otel_provider.get_meter("llama_stack.metrics")
|
||||
|
||||
|
||||
# Create various instruments
|
||||
request_counter = meter.create_counter(
|
||||
"llama.requests.total",
|
||||
unit="requests",
|
||||
description="Total requests"
|
||||
)
|
||||
|
||||
request_counter = meter.create_counter("llama.requests.total", unit="requests", description="Total requests")
|
||||
|
||||
latency_histogram = meter.create_histogram(
|
||||
"llama.inference.duration",
|
||||
unit="ms",
|
||||
description="Inference duration"
|
||||
"llama.inference.duration", unit="ms", description="Inference duration"
|
||||
)
|
||||
|
||||
|
||||
active_sessions = meter.create_up_down_counter(
|
||||
"llama.sessions.active",
|
||||
unit="sessions",
|
||||
description="Active sessions"
|
||||
"llama.sessions.active", unit="sessions", description="Active sessions"
|
||||
)
|
||||
|
||||
|
||||
# Use the instruments
|
||||
request_counter.add(1, {"endpoint": "/chat", "status": "success"})
|
||||
latency_histogram.record(123.45, {"model": "llama-3.2-1b"})
|
||||
active_sessions.add(1)
|
||||
active_sessions.add(-1)
|
||||
|
||||
|
||||
# No exceptions means success
|
||||
|
||||
def test_concurrent_tracer_usage(self, otel_provider):
|
||||
"""Test that multiple threads can use tracers concurrently."""
|
||||
|
||||
def create_spans(thread_id):
|
||||
tracer = otel_provider.get_tracer(f"test.module.{thread_id}")
|
||||
for i in range(10):
|
||||
with tracer.start_as_current_span(f"operation.{i}") as span:
|
||||
span.set_attribute("thread.id", thread_id)
|
||||
span.set_attribute("iteration", i)
|
||||
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
||||
futures = [executor.submit(create_spans, i) for i in range(10)]
|
||||
concurrent.futures.wait(futures)
|
||||
|
||||
|
||||
# If we get here without exceptions, thread safety is working
|
||||
|
||||
def test_concurrent_meter_usage(self, otel_provider):
|
||||
"""Test that multiple threads can use meters concurrently."""
|
||||
|
||||
def record_metrics(thread_id):
|
||||
meter = otel_provider.get_meter(f"test.meter.{thread_id}")
|
||||
counter = meter.create_counter(f"test.counter.{thread_id}")
|
||||
histogram = meter.create_histogram(f"test.histogram.{thread_id}")
|
||||
|
||||
|
||||
for i in range(10):
|
||||
counter.add(1, {"thread": str(thread_id)})
|
||||
histogram.record(float(i * 10), {"thread": str(thread_id)})
|
||||
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
|
||||
futures = [executor.submit(record_metrics, i) for i in range(10)]
|
||||
concurrent.futures.wait(futures)
|
||||
|
||||
|
||||
# If we get here without exceptions, thread safety is working
|
||||
|
||||
def test_mixed_tracing_and_metrics(self, otel_provider):
|
||||
"""Test using both tracing and metrics together."""
|
||||
tracer = otel_provider.get_tracer("test.module")
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
counter = meter.create_counter("operations.count")
|
||||
histogram = meter.create_histogram("operation.duration")
|
||||
|
||||
|
||||
# Trace an operation while recording metrics
|
||||
with tracer.start_as_current_span("test.operation") as span:
|
||||
counter.add(1)
|
||||
span.set_attribute("step", "start")
|
||||
|
||||
|
||||
histogram.record(50.0)
|
||||
span.set_attribute("step", "processing")
|
||||
|
||||
|
||||
counter.add(1)
|
||||
span.set_attribute("step", "complete")
|
||||
|
||||
|
||||
# No exceptions means success
|
||||
|
||||
|
||||
|
@ -391,14 +357,14 @@ class TestOTelTelemetryProviderFastAPIMiddleware:
|
|||
def test_fastapi_middleware(self, otel_provider):
|
||||
"""Test that fastapi_middleware can be called."""
|
||||
mock_app = MagicMock()
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
otel_provider.fastapi_middleware(mock_app)
|
||||
|
||||
def test_fastapi_middleware_is_idempotent(self, otel_provider):
|
||||
"""Test that calling fastapi_middleware multiple times is safe."""
|
||||
mock_app = MagicMock()
|
||||
|
||||
|
||||
# Should be able to call multiple times without error
|
||||
otel_provider.fastapi_middleware(mock_app)
|
||||
# Note: Second call might warn but shouldn't fail
|
||||
|
@ -411,27 +377,27 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
def test_tracer_with_empty_module_name(self, otel_provider):
|
||||
"""Test that get_tracer works with empty module name."""
|
||||
tracer = otel_provider.get_tracer("")
|
||||
|
||||
|
||||
assert tracer is not None
|
||||
assert isinstance(tracer, Tracer)
|
||||
|
||||
def test_meter_with_empty_name(self, otel_provider):
|
||||
"""Test that get_meter works with empty name."""
|
||||
meter = otel_provider.get_meter("")
|
||||
|
||||
|
||||
assert meter is not None
|
||||
assert isinstance(meter, Meter)
|
||||
|
||||
def test_meter_instruments_with_special_characters(self, otel_provider):
|
||||
"""Test that metric names with dots, underscores, and hyphens work."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
|
||||
|
||||
counter = meter.create_counter("test.counter_name-special")
|
||||
histogram = meter.create_histogram("test.histogram_name-special")
|
||||
|
||||
|
||||
assert counter is not None
|
||||
assert histogram is not None
|
||||
|
||||
|
||||
# Verify they can be used
|
||||
counter.add(1)
|
||||
histogram.record(10.0)
|
||||
|
@ -440,7 +406,7 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
"""Test that counters work with zero value."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
counter = meter.create_counter("test.counter")
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
counter.add(0.0)
|
||||
|
||||
|
@ -448,7 +414,7 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
"""Test that histograms accept negative values."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
histogram = meter.create_histogram("test.histogram")
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
histogram.record(-10.0)
|
||||
|
||||
|
@ -456,7 +422,7 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
"""Test that up/down counters work with negative values."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
up_down_counter = meter.create_up_down_counter("test.updown")
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
up_down_counter.add(-5.0)
|
||||
|
||||
|
@ -464,7 +430,7 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
"""Test that empty attributes dict is handled correctly."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
counter = meter.create_counter("test.counter")
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
counter.add(1.0, attributes={})
|
||||
|
||||
|
@ -472,7 +438,7 @@ class TestOTelTelemetryProviderEdgeCases:
|
|||
"""Test that None attributes are handled correctly."""
|
||||
meter = otel_provider.get_meter("test.meter")
|
||||
counter = meter.create_counter("test.counter")
|
||||
|
||||
|
||||
# Should not raise an exception
|
||||
counter.add(1.0, attributes=None)
|
||||
|
||||
|
@ -484,28 +450,28 @@ class TestOTelTelemetryProviderRealisticScenarios:
|
|||
"""Simulate telemetry for a complete inference request."""
|
||||
tracer = otel_provider.get_tracer("llama_stack.inference")
|
||||
meter = otel_provider.get_meter("llama_stack.metrics")
|
||||
|
||||
|
||||
# Create instruments
|
||||
request_counter = meter.create_counter("llama.requests.total")
|
||||
token_counter = meter.create_counter("llama.tokens.total")
|
||||
latency_histogram = meter.create_histogram("llama.request.duration_ms")
|
||||
in_flight_gauge = meter.create_up_down_counter("llama.requests.in_flight")
|
||||
|
||||
|
||||
# Simulate request
|
||||
with tracer.start_as_current_span("inference.request") as request_span:
|
||||
request_span.set_attribute("model.id", "llama-3.2-1b")
|
||||
request_span.set_attribute("user.id", "test-user")
|
||||
|
||||
|
||||
request_counter.add(1, {"model": "llama-3.2-1b"})
|
||||
in_flight_gauge.add(1)
|
||||
|
||||
|
||||
# Simulate token counting
|
||||
token_counter.add(25, {"type": "input", "model": "llama-3.2-1b"})
|
||||
token_counter.add(150, {"type": "output", "model": "llama-3.2-1b"})
|
||||
|
||||
|
||||
# Simulate latency
|
||||
latency_histogram.record(125.5, {"model": "llama-3.2-1b"})
|
||||
|
||||
|
||||
in_flight_gauge.add(-1)
|
||||
request_span.set_attribute("tokens.input", 25)
|
||||
request_span.set_attribute("tokens.output", 150)
|
||||
|
@ -514,36 +480,36 @@ class TestOTelTelemetryProviderRealisticScenarios:
|
|||
"""Simulate a multi-step workflow with nested spans."""
|
||||
tracer = otel_provider.get_tracer("llama_stack.workflow")
|
||||
meter = otel_provider.get_meter("llama_stack.workflow.metrics")
|
||||
|
||||
|
||||
step_counter = meter.create_counter("workflow.steps.completed")
|
||||
|
||||
|
||||
with tracer.start_as_current_span("workflow.execute") as root_span:
|
||||
root_span.set_attribute("workflow.id", "wf-123")
|
||||
|
||||
|
||||
# Step 1: Validate
|
||||
with tracer.start_as_current_span("step.validate") as span:
|
||||
span.set_attribute("validation.result", "pass")
|
||||
step_counter.add(1, {"step": "validate", "status": "success"})
|
||||
|
||||
|
||||
# Step 2: Process
|
||||
with tracer.start_as_current_span("step.process") as span:
|
||||
span.set_attribute("items.processed", 100)
|
||||
step_counter.add(1, {"step": "process", "status": "success"})
|
||||
|
||||
|
||||
# Step 3: Finalize
|
||||
with tracer.start_as_current_span("step.finalize") as span:
|
||||
span.set_attribute("output.size", 1024)
|
||||
step_counter.add(1, {"step": "finalize", "status": "success"})
|
||||
|
||||
|
||||
root_span.set_attribute("workflow.status", "completed")
|
||||
|
||||
def test_error_handling_with_telemetry(self, otel_provider):
|
||||
"""Test telemetry when errors occur."""
|
||||
tracer = otel_provider.get_tracer("llama_stack.errors")
|
||||
meter = otel_provider.get_meter("llama_stack.errors.metrics")
|
||||
|
||||
|
||||
error_counter = meter.create_counter("llama.errors.total")
|
||||
|
||||
|
||||
with tracer.start_as_current_span("operation.with.error") as span:
|
||||
try:
|
||||
span.set_attribute("step", "processing")
|
||||
|
@ -553,24 +519,24 @@ class TestOTelTelemetryProviderRealisticScenarios:
|
|||
span.record_exception(e)
|
||||
span.set_status(trace.Status(trace.StatusCode.ERROR, str(e)))
|
||||
error_counter.add(1, {"error.type": "ValueError"})
|
||||
|
||||
|
||||
# Should not raise - error was handled
|
||||
|
||||
def test_batch_operations_telemetry(self, otel_provider):
|
||||
"""Test telemetry for batch operations."""
|
||||
tracer = otel_provider.get_tracer("llama_stack.batch")
|
||||
meter = otel_provider.get_meter("llama_stack.batch.metrics")
|
||||
|
||||
|
||||
batch_counter = meter.create_counter("llama.batch.items.processed")
|
||||
batch_duration = meter.create_histogram("llama.batch.duration_ms")
|
||||
|
||||
|
||||
with tracer.start_as_current_span("batch.process") as batch_span:
|
||||
batch_span.set_attribute("batch.size", 100)
|
||||
|
||||
|
||||
for i in range(100):
|
||||
with tracer.start_as_current_span(f"item.{i}") as item_span:
|
||||
item_span.set_attribute("item.index", i)
|
||||
batch_counter.add(1, {"status": "success"})
|
||||
|
||||
|
||||
batch_duration.record(5000.0, {"batch.size": "100"})
|
||||
batch_span.set_attribute("batch.status", "completed")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue