Skip to content

SqliteSpanExporter drops a span's status and events, so an exception that ended a run is lost (2.11.0)聽#7484

Description

@nboukraa

馃敶 Required Information

Describe the Bug:
SqliteSpanExporter (telemetry/sqlite_span_exporter.py), the exporter that "exports spans to a local SQLite database" for local development, does not store a span's status or its events. OpenTelemetry keeps an exception in both: start_as_current_span sets the status to ERROR with the exception's description, and records an exception event with its type, message and stack trace. ADK does the same in trace_tool_call and node_tracing. The spans table has no column for either, and _row_to_readable_span rebuilds each span without them. So a run that fails leaves spans that read back as if nothing went wrong: status UNSET, no events. The error that stopped the run, the main thing a local trace is kept for, is lost.

Steps to Reproduce:

  1. pip install "google-adk==2.11.0" (opentelemetry-sdk 1.42.1)
  2. Run the script below. It needs no key or network.
  3. It ends a span with an exception, exports it with SqliteSpanExporter, and reads it back with get_all_spans_for_session.

Expected Behavior:
The span reads back with status ERROR, its description, and the exception event (type, message, stack trace).

Observed Behavior:

columns: ['span_id', 'trace_id', 'parent_span_id', 'name', 'start_time_unix_nano', 'end_time_unix_nano', 'session_id', 'invocation_id', 'attributes_json']
status read back: UNSET
events read back: []

The table on main is the same.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.11.0
  • Desktop OS: Linux
  • Python Version (python -V): 3.11.13

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: not relevant (any span)

馃煛 Optional Information

Regression: Not known.

Minimal Reproduction Code:

"""SqliteSpanExporter drops a span's status and events (exceptions)."""

import sqlite3
import tempfile
from pathlib import Path

from google.adk.telemetry.sqlite_span_exporter import SqliteSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor

db = str(Path(tempfile.mkdtemp()) / "spans.db")
exporter = SqliteSpanExporter(db_path=db)
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
tracer = provider.get_tracer("repro")

try:
    with tracer.start_as_current_span(
        "call_llm", attributes={"gcp.vertex.agent.session_id": "s1"}
    ):
        raise ValueError("model: claude-sonnet-9-9 not found")
except ValueError:
    pass

columns = [r[1] for r in sqlite3.connect(db).execute("PRAGMA table_info(spans)")]
print("columns:", columns)
(span,) = exporter.get_all_spans_for_session("s1")
print("status read back:", span.status.status_code.name)
print("events read back:", list(span.events))

Possible fix: add status_code, status_description and events_json columns (with ALTER TABLE ... ADD COLUMN for an existing file), write them in export, and restore them in _row_to_readable_span.

How often has this issue occurred?: Always (100%).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions