Skip to content

OtelEventHandler#

dbally.audit.OtelEventHandler #

OtelEventHandler(provider: Optional[TracerProvider] = None, record_inputs: bool = True, record_outputs: bool = True)

Bases: EventHandler[SpanHandler, SpanHandler]

This handler emits OpenTelemetry spans for recorded events.

Initialize OtelEventHandler. By default, it will try to use globaly configured TracerProvider. Pass it explicitly if you want custom implementation, or you do not use OTel auto-instrumentation.

To comply with the OTel Semantic Conventions recording of inputs and outputs can be disabled.

PARAMETER DESCRIPTION
provider

Optional tracer provider. By default global provider is used.

TYPE: Optional[TracerProvider] DEFAULT: None

record_inputs

if true (default) all inputs are recorded as span attributes. Depending on usecase it maybe turned off, to save resources and improve performance.

TYPE: bool DEFAULT: True

record_outputs

if true (default) all outputs are recorded as span attributes. Depending on usecase it maybe turned off, to save resources and improve performance.

TYPE: bool DEFAULT: True

Source code in src/dbally/audit/event_handlers/otel_event_handler.py
def __init__(
    self, provider: Optional[TracerProvider] = None, record_inputs: bool = True, record_outputs: bool = True
) -> None:
    """
    Initialize OtelEventHandler. By default, it will try to use globaly configured TracerProvider. Pass it
    explicitly if you want custom implementation, or you do not use OTel auto-instrumentation.

    To comply with the
    [OTel Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/llm-spans/#configuration)
    recording of inputs and outputs can be disabled.

    Args:
        provider: Optional tracer provider. By default global provider is used.
        record_inputs: if true (default) all inputs are recorded as span attributes. Depending on usecase it maybe
                       turned off, to save resources and improve performance.
        record_outputs: if true (default) all outputs are recorded as span attributes. Depending on usecase it
                        maybe turned off, to save resources and improve performance.
    """
    self.record_inputs = record_inputs
    self.record_outputs = record_outputs
    if provider is None:
        self.tracer = trace.get_tracer(TRACER_NAME)
    else:
        self.tracer = provider.get_tracer(TRACER_NAME)

record_inputs instance-attribute #

record_inputs = record_inputs

record_outputs instance-attribute #

record_outputs = record_outputs

tracer instance-attribute #

tracer = get_tracer(TRACER_NAME)

request_start async #

request_start(user_request: RequestStart) -> SpanHandler

Initializes new OTel Span as a parent.

PARAMETER DESCRIPTION
user_request

The start of the request.

TYPE: RequestStart

RETURNS DESCRIPTION
SpanHandler

span object as a parent for all subsequent events for this request

Source code in src/dbally/audit/event_handlers/otel_event_handler.py
async def request_start(self, user_request: RequestStart) -> SpanHandler:
    """
    Initializes new OTel Span as a parent.

    Args:
        user_request: The start of the request.

    Returns:
        span object as a parent for all subsequent events for this request
    """
    with self.tracer.start_as_current_span("request", end_on_exit=False, kind=SpanKind.SERVER) as span:
        return (
            self._handle_span(span)
            .set("db-ally.user.collection", user_request.collection_name)
            .set_input("db-ally.user.question", user_request.question)
        )

event_start async #

event_start(event: Event, request_context: SpanHandler) -> SpanHandler

Starts a new event in a system as a span. Uses request span as a parent.

PARAMETER DESCRIPTION
event

Event to register

TYPE: Event

request_context

Parent span for this event

TYPE: SpanHandler

RETURNS DESCRIPTION
SpanHandler

span object capturing start of execution for this event

RAISES DESCRIPTION
ValueError

it is thrown when unknown event type is passed as argument

Source code in src/dbally/audit/event_handlers/otel_event_handler.py
async def event_start(self, event: Event, request_context: SpanHandler) -> SpanHandler:
    """
    Starts a new event in a system as a span. Uses request span as a parent.

    Args:
        event: Event to register
        request_context: Parent span for this event

    Returns:
        span object capturing start of execution for this event

    Raises:
        ValueError: it is thrown when unknown event type is passed as argument
    """
    if isinstance(event, LLMEvent):
        with self._new_child_span(request_context, "llm") as span:
            return (
                self._handle_span(span)
                .set("db-ally.llm.type", event.type)
                .set_input("db-ally.llm.prompts", json.dumps(event.prompt))
            )

    if isinstance(event, SimilarityEvent):
        with self._new_child_span(request_context, "similarity") as span:
            return (
                self._handle_span(span)
                .set("db-ally.similarity.store", event.store)
                .set("db-ally.similarity.fetcher", event.fetcher)
                .set_input("db-ally.similarity.input", event.input_value)
            )
    if isinstance(event, FallbackEvent):
        with self._new_child_span(request_context, "fallback") as span:
            return self._handle_span(span).set("db-ally.error_description", event.error_description)

    raise ValueError(f"Unsupported event: {type(event)}")

event_end async #

event_end(event: Optional[Event], request_context: SpanHandler, event_context: SpanHandler) -> None

Finalizes execution of the event, ending a span for this event.

PARAMETER DESCRIPTION
event

optional event information

TYPE: Optional[Event]

request_context

parent span

TYPE: SpanHandler

event_context

event span

TYPE: SpanHandler

Source code in src/dbally/audit/event_handlers/otel_event_handler.py
async def event_end(self, event: Optional[Event], request_context: SpanHandler, event_context: SpanHandler) -> None:
    """
    Finalizes execution of the event, ending a span for this event.

    Args:
        event: optional event information
        request_context: parent span
        event_context: event span
    """

    if isinstance(event, LLMEvent):
        event_context.set("db-ally.llm.response-tokes", event.completion_tokens).set_output(
            "db-ally.llm.response", event.response
        )

    if isinstance(event, SimilarityEvent) and self.record_outputs:
        event_context.set("db-ally.similarity.output", event.output_value)

    event_context.end_succesfully()

request_end async #

request_end(output: RequestEnd, request_context: SpanHandler) -> None

Finalizes entire request, ending the span for this request.

PARAMETER DESCRIPTION
output

output generated for this request

TYPE: RequestEnd

request_context

span to be closed

TYPE: SpanHandler

Source code in src/dbally/audit/event_handlers/otel_event_handler.py
async def request_end(self, output: RequestEnd, request_context: SpanHandler) -> None:
    """
    Finalizes entire request, ending the span for this request.

    Args:
        output: output generated for this request
        request_context: span to be closed
    """
    request_context.set_output("db-ally.result.textual", output.result.textual_response).set(
        "db-ally.result.execution-time", output.result.execution_time
    ).set("db-ally.result.execution-time-view", output.result.execution_time_view).set(
        "db-ally.result.view-name", output.result.view_name
    )

    for key, value in output.result.context.items():
        if key not in FORBIDDEN_CONTEXT_KEYS:
            request_context.set(f"db-ally.result.context.{key}", value, transform=_optional_str)

    request_context.end_succesfully()