Package: signalfx-instrumentation-dbapi
This package enables distributed tracing inPython Database API 2.0compatible-clients
viaThe OpenTracing Project.  Once a production system contends with real concurrency or splits
into many services, crucial (and formerly easy) tasks become difficult: user-facing latency optimization,
root-cause analysis of backend errors, communication about distinct pieces of a now-distributed system,
etc. Distributed tracing follows a request on its journey from inception to completion from mobile/browser
all the way to the microservices.As core services and libraries adopt OpenTracing, the application builder is no longer burdened with
the task of adding basic tracing instrumentation to their own code. In this way, developers can build
their applications with the tools they prefer and benefit from built-in tracing instrumentation.
OpenTracing implementations exist for major distributed tracing systems and can be bound or swapped
with a one-line configuration change.If you want to learn more about the underlying Python API, visit the Pythonsource code.InstallationRun the following command:$ pip install signalfx-instrumentation-dbapiUsageThis DB API extension allows the tracing of database queries using the OpenTracing API. All that it
requires is for aConnectionTracingtracer to be initialized using an instance of an OpenTracing 2.0-compatible
tracer and a DB APIConnectionobject. You can either trace all commands sent to your database, or
use aCursorto trace individual requests.InitializeConnectionTracingwraps theConnectionandTracerinstances that are supported by the Python
DB API and OpenTracing, respectively. To create aConnectionTracingobject, you can either pass in a
tracer object directly or default to theopentracing.tracerglobal tracer:fromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection,opentracing_tracer)orfromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientimportopentracingopentracing.tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection)For expanded usage with Psycopg connection factories, aPsycopgConnectionTracingclass is also available.  This
is necessary for directly using extensions and extras functions on traced connections.  Its non-default usage requires a
lambda proxy or closure to account for the expected tracing arguments, while using the global tracer and default allow
it to be passed directly:fromdbapi_opentracingimportPsycopgConnectionTracingimportopentracingimportpsycopg2opentracing_tracer=## some OpenTracing tracer implementationmy_tags=dict(some='tag')tracing=psycopg2.connect(...,connection_factory=lambdadsn:PsycopgConnectionTracing(dsn,tracer=opentracing_tracer,span_tags=my_tags))# or to use all defaultsopentracing.tracer=opentracing_tracertracing=psycopg2.connect(...,connection_factory=PsycopgConnectionTracing)ConnectionTracing ConfigurationAlong with optionally providing an OpenTracing 2.0-compatible tracer,ConnectionTracingalso accepts aspan_tagsnamed argument and several traced method disabling flags:trace_execute,trace_executemany,trace_callproc,trace_commit, andtrace_rollbackto specify the command types you’d like not to trace
(all areTrueby default).fromdbapi_opentracingimportConnectionTracingfromopentracing.extimporttagsimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection,opentracing_tracer,# span_tags will be used for all generated spansspan_tags={'Custom':'Tag',tags.DATABASE_TYPE:'PostgreSQL',tags.DATABASE_INSTANCE='myDatabase'},trace_callproc=False,trace_commit=False)# Note that the default OpenTracing 'db.type' tag will have 'sql' as a value.# If a more specific type is desired, you can set it with the span_tags dictionary argument as shown.Trace All Cursor Commandsfromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection,opentracing_tracer,span_tags={'Custom':'Tag'})# span_tags will be used for all generated spans# Please note that the default OpenTracing 'db.type' tag will have 'sql' as a value.# If a more specific type is desired, you can set it with the span_tags dictionary argumentwithtracing.cursor()ascursor:cursor.execute('SELECT * FROM TABLE')vals=cursor.fetchall()cursor.executemany('INSERT INTO TABLE VALUES (%s,%s)',[('one','two'),('three','four')])cursor.callproc('MyStoredProcedure')tracing.commit()Trace Specific Cursor Command Typesfromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection,opentracing_tracer,span_tags={'Custom':'Tag'})# span_tags will be used for all generated spans# Provide False values for optional trace_execute, trace_executemany, and/or trace_callproc named argumentswithtracing.cursor(trace_executemany=False,trace_callproc=False)ascursor:# Traced querycursor.execute('SELECT * FROM TABLE')vals=cursor.fetchall()# Untraced commandcursor.executemany('INSERT INTO TABLE VALUES (%s,%s)',[('one','two'),('three','four')])# Untraced commandcursor.callproc('MyStoredProcedure')tracing.commit()Trace All Connection Commands (implicitcommit()androllback())fromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)tracing=ConnectionTracing(connection,opentracing_tracer)withtracingascursor:# If DB API client supports Connection as context managercursor.execute('SELECT * FROM TABLE')vals=cursor.fetchall()cursor.executemany('INSERT INTO TABLE VALUES (%s,%s)',[('one','two'),('three','four')])cursor.callproc('MyStoredProcedure')Trace Specific Connection Command Typesfromdbapi_opentracingimportConnectionTracingimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)# Provide False values for optional trace_execute, trace_executemany, trace_callproc, trace_commit,# and/or trace_rollback named argumentstracing=ConnectionTracing(connection,opentracing_tracer,trace_execute=False,trace_commit=False)withtracingascursor:# If DB API client supports Connection as context manager# Untraced querycursor.execute('SELECT * FROM TABLE')vals=cursor.fetchall()# Traced commandcursor.executemany('INSERT INTO TABLE VALUES (%s,%s)',[('one','two'),('three','four')])# Traced commandcursor.callproc('MyStoredProcedure')# Implicit commit() is not traced because of named argument valueTrace Individual Commands Without Named Argumentsfromdbapi_opentracingimportCursorimportdb_api_compatible_clientopentracing_tracer=## some OpenTracing tracer implementationconnection=db_api_compatible_client.connect(...)withconnection.cursor()ascursor:# Traced queryCursor(cursor,opentracing_tracer).execute('SELECT * FROM TABLE_ONE')# Traced query using opentracing.tracer defaultCursor(cursor).execute('SELECT * FROM TABLE_TWO')# Traced query with custom tagsCursor(cursor,span_tags={'Query':'Tag','Another':'Tag'}).execute('SELECT * FROM TABLE_THREE')# Untraced command by using unmodified cursor instancecursor.executemany('INSERT INTO TABLE VALUES (%s,%s)',[('one','two'),('three','four')])Further InformationIf you’re interested in learning more about the OpenTracing standard, please visitopentracing.ioorjoin the mailing list. If you would like to implement OpenTracing
in your project and need help, feel free to send us a note atcommunity@opentracing.io.