MySQL Server added OpenTelemetry support in MySQL Enterprise Edition version 8.1.0, which is a commercial product. OpenTelemetry tracing support was added in Connector/Python 8.1.0.
OpenTelemetry is an observability framework and toolkit designed to create and manage telemetry data such as traces, metrics, and logs. Visit What is OpenTelemetry? for an explanation of what OpenTelemetry offers.
Connector/Python only supports tracing, so this guide does not include information about metric and log signals.
Install the OpenTelemetry API, SDK, and OTLP Exporter packages
on the system along with Connector/Python. Optionally use the
[telemetry]
shortcut when installing the
mysql-connector-python
pip package to pull in
specific OpenTelemetry versions as defined by the connector.
Manual installation:
pip install opentelemetry-api
pip install opentelemetry-sdk
pip install opentelemetry-exporter-otlp-proto-http
pip install mysql-connector-python
Or pass in [telemetry] when installing Connector/Python to perform the same actions except it installs a specific and tested OpenTelemetry version, which for Connector/Python 9.0.0 is OpenTelemetry v1.18.0:
pip install mysql-connector-python[telemetry]
Connector/Python 8.1.0 through 8.4.0 included an [opentelemetry] option that installed a bundled version of the OpenTelemetry SDK/API libraries. Doing so in those versions was not recommended.
For instrumenting an application, Connector/Python utilizes the official OpenTelemetry SDK to initialize OpenTelemetry, and the official OpenTelemetry API to instrument the application's code. This emits telemetry from the application and from utilized libraries that include instrumentation.
An application can be instrumented as demonstrated by this generic example:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("app"):
my_app()
To better understand and get started using OpenTelemetry tracing for Python, see the official OpenTelemetry Python Instrumentation guide.
Connector/Python includes a MySQL instrumentor to instrument MySQL connections. This instrumentor provides an API and usage similar to OpenTelemetry's own MySQL package named opentelemetry-instrumentation-mysql.
An exception is raised if a system does not support OpenTelemetry when attempting to use the instrumentor.
An example that utilizes the system's OpenTelemetry SDK/API and implements tracing with MySQL Connector/Python:
import os
import mysql.connector
# An instrumentor that comes with mysql-connector-python
from mysql.connector.opentelemetry.instrumentation import (
MySQLInstrumentor as OracleMySQLInstrumentor,
)
# Loading SDK from the system
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
config = {
"host": "127.0.0.1",
"user": "root",
"password": os.environ.get("password"),
"use_pure": True,
"port": 3306,
"database": "test",
}
# Global instrumentation: all connection objects returned by
# mysql.connector.connect will be instrumented.
OracleMySQLInstrumentor().instrument()
with tracer.start_as_current_span("client_app"):
with mysql.connector.connect(**config) as cnx:
with cnx.cursor() as cur:
cur.execute("SELECT @@version")
_ = cur.fetchall()
A trace generated by the Connector/Python instrumentor contains one connection span, and zero or more query spans as described in the rest of this section.
Connection Span
Time from connection initialization to the moment the connection ends. The span is named
connection
.If the application does not provide a span, the connection span generated is a ROOT span, originating in the connector.
If the application does provide a span, the query span generated is a CHILD span, originating in the connector.
Query Span
Time from when an SQL statement is requested (on the connector side) to the moment the connector finishes processing the server's reply to this statement.
A query span is created for each query request sent to the server. If the application does not provide a span, the query span generated is a ROOT span, originating in the connector.
If the application does provide a span, the query span generated is a CHILD span, originating in the connector.
The query span is linked to the existing connection span of the connection the query was executed.
Query attributes with prepared statements is supported as of MySQL Enterprise Edition 8.3.0.
Query spans for the connection object is supported as of Connector/Python 8.3.0, which includes methods such as commit(), rollback(), and cmd_change_user().
Context Propagation
By default, the trace context of the span in progress (if any) is propagated to the MySQL server.
Propagation has no effect when the MySQL server either disabled or does not support OpenTelemetry (the trace context is ignored by the server), however, when connecting to a server with OpenTelemetry enabled and configured, the server processes the propagated traces and creates parent-child relationships between the spans from the connector and those from the server. In other words, this provides trace continuity.
Context propagation with prepared statements is supported as of MySQL Enterprise Edition 8.3.0.
-
The trace context is propagated for statements with query attributes defined in the MySQL client/server protocol, such as COM_QUERY.
The trace context is not propagated for statements without query attributes defined in the MySQL client/server protocol, statements such as COM_PING.
-
Trace context propagation is done via query attributes where a new attribute named "traceparent" is defined. Its value is based on the current span context. For details on how this value is computed, read the traceparent header W3C specification.
If the "traceparent" query attribute is manually set for a query, then it is not be overwritten by the connector; it's assumed that it provides OTel context intended to forward to the server.
The boolean connection property named
otel_context_propagation
is
True
by default. Setting it to
False
disables context propagation.
Since otel_context_propagation
is a connection
property that can be changed after a connection is established
(a connection object is created), setting such property to
False
does not have an effect over the spans
generated during the connection phase. In other words, spans
generated during the connection phase are always propagated
since otel_context_propagation
is
True
by default.
This implementation is distinct from the implementation provided
through the MySQL client library (or the related
telemetry_client
client-side plugin).