46
46
failed_hook (Callable) -
47
47
a function with extra user-defined logic to be performed after the query returns with a failed response
48
48
this function signature is: def failed_hook(span: Span, event: CommandFailedEvent) -> None
49
+ capture_statement (bool) - an optional value to enable capturing the database statement that is being executed
49
50
50
51
for example:
51
52
@@ -81,6 +82,9 @@ def failed_hook(span, event):
81
82
from opentelemetry import context
82
83
from opentelemetry .instrumentation .instrumentor import BaseInstrumentor
83
84
from opentelemetry .instrumentation .pymongo .package import _instruments
85
+ from opentelemetry .instrumentation .pymongo .utils import (
86
+ COMMAND_TO_ATTRIBUTE_MAPPING ,
87
+ )
84
88
from opentelemetry .instrumentation .pymongo .version import __version__
85
89
from opentelemetry .instrumentation .utils import _SUPPRESS_INSTRUMENTATION_KEY
86
90
from opentelemetry .semconv .trace import DbSystemValues , SpanAttributes
@@ -106,30 +110,29 @@ def __init__(
106
110
request_hook : RequestHookT = dummy_callback ,
107
111
response_hook : ResponseHookT = dummy_callback ,
108
112
failed_hook : FailedHookT = dummy_callback ,
113
+ capture_statement : bool = False ,
109
114
):
110
115
self ._tracer = tracer
111
116
self ._span_dict = {}
112
117
self .is_enabled = True
113
118
self .start_hook = request_hook
114
119
self .success_hook = response_hook
115
120
self .failed_hook = failed_hook
121
+ self .capture_statement = capture_statement
116
122
117
123
def started (self , event : monitoring .CommandStartedEvent ):
118
124
"""Method to handle a pymongo CommandStartedEvent"""
119
125
if not self .is_enabled or context .get_value (
120
126
_SUPPRESS_INSTRUMENTATION_KEY
121
127
):
122
128
return
123
- command = event .command .get (event .command_name , "" )
124
- name = event .database_name
125
- name += "." + event .command_name
126
- statement = event .command_name
127
- if command :
128
- statement += " " + str (command )
129
+ command_name = event .command_name
130
+ span_name = f"{ event .database_name } .{ command_name } "
131
+ statement = self ._get_statement_by_command_name (command_name , event )
129
132
collection = event .command .get (event .command_name )
130
133
131
134
try :
132
- span = self ._tracer .start_span (name , kind = SpanKind .CLIENT )
135
+ span = self ._tracer .start_span (span_name , kind = SpanKind .CLIENT )
133
136
if span .is_recording ():
134
137
span .set_attribute (
135
138
SpanAttributes .DB_SYSTEM , DbSystemValues .MONGODB .value
@@ -196,6 +199,14 @@ def failed(self, event: monitoring.CommandFailedEvent):
196
199
def _pop_span (self , event ):
197
200
return self ._span_dict .pop (_get_span_dict_key (event ), None )
198
201
202
+ def _get_statement_by_command_name (self , command_name , event ):
203
+ statement = command_name
204
+ command_attribute = COMMAND_TO_ATTRIBUTE_MAPPING .get (command_name )
205
+ command = event .command .get (command_attribute )
206
+ if command and self .capture_statement :
207
+ statement += " " + str (command )
208
+ return statement
209
+
199
210
200
211
def _get_span_dict_key (event ):
201
212
if event .connection_id is not None :
@@ -228,6 +239,7 @@ def _instrument(self, **kwargs):
228
239
request_hook = kwargs .get ("request_hook" , dummy_callback )
229
240
response_hook = kwargs .get ("response_hook" , dummy_callback )
230
241
failed_hook = kwargs .get ("failed_hook" , dummy_callback )
242
+ capture_statement = kwargs .get ("capture_statement" )
231
243
# Create and register a CommandTracer only the first time
232
244
if self ._commandtracer_instance is None :
233
245
tracer = get_tracer (__name__ , __version__ , tracer_provider )
@@ -237,6 +249,7 @@ def _instrument(self, **kwargs):
237
249
request_hook = request_hook ,
238
250
response_hook = response_hook ,
239
251
failed_hook = failed_hook ,
252
+ capture_statement = capture_statement ,
240
253
)
241
254
monitoring .register (self ._commandtracer_instance )
242
255
# If already created, just enable it
0 commit comments