Skip to main content
The start_galileo_span function provides a context manager for creating OpenTelemetry spans that are automatically enriched with Galileo-specific attributes. This enables seamless observability for custom spans within your application while maintaining compatibility with the broader OpenTelemetry ecosystem.

Prerequisites

Before using start_galileo_span, set up the tracer provider with the Galileo span processor:
Python
from opentelemetry.sdk.trace import TracerProvider
from galileo.otel import GalileoSpanProcessor, add_galileo_span_processor

tracer_provider = TracerProvider()
processor = GalileoSpanProcessor(
    project="your-project-name",      # Optional: falls back on env var
    logstream="your-logstream-name"   # Optional: falls back on env var
)
add_galileo_span_processor(tracer_provider, processor)
Requires the OpenTelemetry extra: pip install galileo[otel]

Environment Variables

VariableDescription
GALILEO_PROJECTDefault project name for trace export
GALILEO_LOG_STREAMDefault Log stream for trace organization

Basic Usage

Python
from galileo.otel import start_galileo_span
from galileo_core.schemas.logging.span import WorkflowSpan

galileo_span = WorkflowSpan(name="my-custom-operation")
with start_galileo_span(galileo_span) as span:
    # Your custom logic here
    span.set_attribute("custom.attribute", "value")
    result = perform_operation()

Tool Spans

Use ToolSpan for tool/function execution operations. This captures tool invocation details including the tool name, arguments, and results.
Python
from galileo.otel import start_galileo_span
from galileo_core.schemas.logging.span import ToolSpan

tool_span = ToolSpan(
    name="get_weather",
    input='{"location": "San Francisco", "unit": "celsius"}',
    tool_call_id="call_abc123"
)
with start_galileo_span(tool_span) as span:
    result = get_weather(location="San Francisco", unit="celsius")
    tool_span.output = '{"temperature": 18, "condition": "sunny"}'
When a ToolSpan is provided, the following attributes are set automatically:
AttributeValueDescription
gen_ai.operation.name"execute_tool"Indicates a tool execution operation
gen_ai.tool.nameTool nameName of the tool being executed
gen_ai.tool.call.argumentsStringTool input arguments
gen_ai.tool.call.resultStringTool output result
gen_ai.tool.call.idStringUnique identifier for the tool call (if provided)
gen_ai.input.messagesJSON arrayTool input formatted as message
gen_ai.output.messagesJSON arrayTool output formatted as message

Retriever Spans

Use RetrieverSpan for search and retrieval operations. This automatically captures query input and document output with the correct semantic attributes.
Python
from galileo.otel import start_galileo_span
from galileo_core.schemas.logging.span import RetrieverSpan
from galileo_core.schemas.shared.document import Document

retriever_span = RetrieverSpan(name="document-search", input="What is Galileo?")
with start_galileo_span(retriever_span) as span:
    documents = search_documents("What is Galileo?")
    retriever_span.output = [Document(content=doc) for doc in documents]
When a RetrieverSpan is provided, the following attributes are set automatically:
AttributeValueDescription
db.operation"search"Indicates a search/retrieval operation
gen_ai.input.messagesJSON arrayUser query formatted as input message
gen_ai.output.messagesJSON arrayRetrieved documents formatted as output

Workflow Spans

Use WorkflowSpan for higher-level orchestration units that coordinate multiple sub-operations, such as chains, pipelines, or multi-step processes.
Python
from galileo.otel import start_galileo_span
from galileo_core.schemas.logging.span import WorkflowSpan

workflow_span = WorkflowSpan(
    name="document-processing-pipeline",
    input="Summarize the quarterly report"
)
with start_galileo_span(workflow_span) as span:
    result = process_document("Summarize the quarterly report")
    workflow_span.output = "The quarterly report shows 15% revenue growth..."
When a WorkflowSpan is provided, the following attributes are set automatically:
AttributeValueDescription
gen_ai.input.messagesJSON arrayWorkflow input formatted as user message
gen_ai.output.messagesJSON arrayWorkflow output formatted as assistant message or document list

Supported Span Types

Span TypeAttributes SetDescription
WorkflowSpangen_ai.system, gen_ai.input.messages, gen_ai.output.messagesOrchestration span for pipelines and multi-step processes
ToolSpangen_ai.system, gen_ai.operation.name, gen_ai.tool.name, gen_ai.tool.call.*, gen_ai.input.messages, gen_ai.output.messagesTool execution span with invocation details
RetrieverSpangen_ai.system, db.operation, gen_ai.input.messages, gen_ai.output.messagesRetriever span with search operation details and document results

Function Signature

Python
@contextmanager
def start_galileo_span(galileo_span: Span) -> Generator[trace.Span, Any, None]
ParameterTypeRequiredDescription
galileo_spanSpanYesA Galileo span object containing the span name and optional metadata
Returns: A context manager yielding an OpenTelemetry Span object.

Execution Flow

When start_galileo_span is called, the following steps occur:
  1. The TracerProvider is retrieved (from the context variable or via trace.get_tracer_provider())
  2. A tracer named "galileo-tracer" is created
  3. An OpenTelemetry span is started using the galileo_span.name
  4. The span is yielded for your code to execute
  5. On exit, Galileo-specific attributes are set (e.g., gen_ai.system = "galileo-otel" and any span-type-specific attributes)

Complete Example

Python
from galileo.otel import (
    start_galileo_span,
    GalileoSpanProcessor,
    add_galileo_span_processor,
)
from galileo_core.schemas.logging.span import WorkflowSpan, RetrieverSpan
from galileo_core.schemas.shared.document import Document
from opentelemetry.sdk.trace import TracerProvider


def setup_tracing():
    """Initialize Galileo OpenTelemetry tracing."""
    tracer_provider = TracerProvider()
    processor = GalileoSpanProcessor(
        project="my-ai-application",
        logstream="production",
    )
    add_galileo_span_processor(tracer_provider, processor)
    return processor


def search_knowledge_base(query: str) -> list[str]:
    """Search with automatic span creation."""
    retriever_span = RetrieverSpan(name="knowledge-base-search", input=query)

    with start_galileo_span(retriever_span) as span:
        results = ["Result 1", "Result 2", "Result 3"]
        retriever_span.output = [Document(content=r) for r in results]

        # Add custom metrics
        span.set_attribute("search.result_count", len(results))
        return results


def main():
    processor = setup_tracing()

    # Create a parent span for the workflow
    workflow_span = WorkflowSpan(name="user-query-workflow")

    with start_galileo_span(workflow_span) as span:
        span.set_attribute("user.query", "What is machine learning?")

        # Nested retriever span
        results = search_knowledge_base("What is machine learning?")
        print(f"Found {len(results)} results")


if __name__ == "__main__":
    main()

Best Practices

  • Initialize TracerProvider early — Set up the GalileoSpanProcessor at application startup.
  • Use descriptive span names — Provide meaningful names in Span for better observability.
  • Choose the right span type — Use ToolSpan for function calls, RetrieverSpan for search operations, and WorkflowSpan for orchestration.
  • Add custom attributes — Use the yielded span to add operation-specific attributes.
  • Set span output before exiting — The output must be set before the context manager exits for proper attribute capture.
  • Nested spans are supported — Child spans inherit the parent context automatically through OpenTelemetry’s context propagation.