Python trace context in queries
Adding trace context to application queries provides the ability to correlate the queries from a traced transaction, and if sampled, the queries to the transaction trace detail. Trace context in queries is disabled by default. Trace context can be included automatically using the Python Library configuration.
About trace context in queries
The Python Library can automatically add the trace context to queries generated by the Python database framework modules that conform with Python's dbapi
interface. The Supported ORM frameworks and database drivers table details which object relational mapping (ORM) frameworks and database drivers are supported. Each query statement has a standard SQL comment added that uses the format /*db_driver=<driver_name>,traceparent='00-<Trace_ID>-<Span_ID>-<Trace_Flags>'*/
. Other key value pairs may be included, depending on the client-side ORM framework, database driver, and upstream service code and frameworks involved in making the query.
For example, a query made by an instrumented Flask service upon receiving an HTTP request may also include controller=<controller_name>
and db_framework=<db_framework_name>
in addition to the standard SQL comment that is added.
The context information is propagated to the database server, where the traceparent
field is used by our platform to correlate the observed query to any resulting trace detail. On the database server, the commented statement can also help identify client-side code execution that generated the query. For example, a query comment for a MySQL database can be viewed in the general query logs if server logs are enabled. See general query logs in the MySQL 8.0 Reference Manual.
Results
Automatic insertion would produce a query statement message similar to this one.
2023-06-19T22:44:34.817229Z 10 Query SELECT city.id, city.name, city.countrycode, city.district, city.population FROM city WHERE city.id = 1818 /*controller='my_cool_view_function',db_driver='mysqldb',db_framework='sqlalchemy%3A0.39b0',framework='flask%3A2.2.5',route='/manual/',traceparent='00-a9914fe1718b2470dd29185b4d46746e-40a575bfd839229a-01'*/
Supported ORM frameworks and database drivers
ORM framework | Database driver | Support |
---|---|---|
SQLAlchemy |
mysqlclient |
|
mysql-connector-python |
|
|
pymysql |
|
|
psycopg2 |
|
|
Django ORM |
mysqlclient (default) |
|
mysql-connector-python |
|
|
psycopg2 |
|
|
none |
mysql-connector-python |
|
Enable automated trace context insertion
To enable trace context insertion in the Python Library configuration using the OTEL_SQLCOMMENTER_ENABLED
system environment variable, see Trace context in queries.
When using Python Library for instrumentation, only OTEL_SQLCOMMENTER_ENABLED
should be used to enable trace context insertion through the custom distro. OpenTelemetry instrumentors that have been initialized separately do not insert trace context or export traces to the platform.
Customization of trace context insertion
To customize the values inserted with trace context in the Python library configuration using the OTEL_SQLCOMMENTER_OPTIONS
system environment variable, see Customize trace context in queries.
The sqlcommenter options available are defined by some OpenTelemetry instrumentation libraries. All values are Boolean. They are true
by default if OTEL_SQLCOMMENTER_ENABLED
is true
. For more information, see Flask instrumentation, SqlAlchemy instrumentation, and psycopg2 instrumentation.
Django instrumentation is an exception to configuration with OTEL_SQLCOMMENTER_OPTIONS
. It must be customized using the application's settings.py
file.
Prepared query statements
SolarWinds recommends not using the Python Library with OTEL_SQLCOMMENTER_ENABLED
when using prepared statements.
For example, if you use the mysql-connector-python
database driver's cursor
class to directly perform queries with parameterized statements (such as request_id
), every query would be unique. As a result, the database server would prepare a statement for every execution, using up system resources.
The scripts are not supported under any SolarWinds support program or service. The scripts are provided AS IS without warranty of any kind. SolarWinds further disclaims all warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The risk arising out of the use or performance of the scripts and documentation stays with you. In no event shall SolarWinds or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the scripts or documentation.