open-telemetry / open-telemetry/opentelemetry-python-contrib

Database API instrumentation customize operation name

Open
#3,714 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

feature-request
Dominant language
Python
Stars
1.1k
Forks
1.1k
Avg merge
4d 15h
Merged PRs (30d)
16

Description

What problem do you want to solve?

Currently, the span name produced by the dbapi instrumentation is constructed by skipping any potential leading comment and returning the first word of the query text. In my particular case, this often results in names such as "declare" or "select", and I have to check the actual db.statement in the span to find out what kind of query it actually was. As an out-of-the-box solution without any special configuration, this is good enough, but I would like to be able to refine the name if my query actually allows me to do so.

Describe the solution you'd like

I see two possible solutions:

Allow customization of the get_operation_name function
Introduce a hook parameter in the opentelemetry.instrumentation.dbapi.trace_integration function, with the same parameter spec as the current get_operation_name function, allowing you to customize the span name. Exposing the current implementation would also allow you to use it as a fallback method in your own hook.

Example usage:

import pyodbc
from opentelemetry.instrumentation.dbapi import CursorTracer, trace_integration
from opentelemetry.instrumentation.dbapi import get_operation_name  # pre-existing implementation

def my_operation_name(cursor: Any, args: tuple[Any, ...]) -> str:
    # Custom logic to produce span name
    # For example, look for well-known formatted comment in query text
    if (...):
        ...

    return get_operation_name(cursor, args)  # fall back to default implementation

trace_integration(pyodbc, 'Connection', 'odbc', get_operation_name=my_operation_name)
trace_integration(pyodbc, 'connect', 'odbc', get_operation_name=my_operation_name)

Span hook
The first proposed solution would only allow customization of the span name. Taking inspiration from the opentelemetry.instrumentation.fastapi package and its server_request_hook, you can take this concept further and allow customization of the whole span via a hook function.

import pyodbc
from opentelemetry.instrumentation.dbapi import CursorTracer, trace_integration
from opentelemetry.trace import Span

def my_span_hook(span: Span, cursor: Any, args: tuple[Any, ...]) -> None:
    # Customize the span as needed, not just name, but also attributes
    span.update_name('Custom operation')

trace_integration(pyodbc, 'Connection', 'odbc', span_hook=my_span_hook)
trace_integration(pyodbc, 'connect', 'odbc', span_hook=my_span_hook)
Describe alternatives you've considered

I did some experiments monkey patching the CursorTracer.get_operation_name method, similar to how the first proposal would function. While this does work, it relies on internal implementation detail and is likely to break with any update.

Additional Context

No response

Would you like to implement a fix?

None

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with opentelemetry.instrumentation.dbapi.trace_integration and CursorTracer, then inspect the existing get_operation_name behavior. Compare the proposed operation-name hook with FastAPI’s server_request_hook and decide which API is appropriate. Done means the supported Connection and connect instrumentation paths can customize the span name or span through a documented hook, with behavior verified for both forms.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
databases
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.