@@ -158,7 +158,7 @@ def client_resposne_hook(span, future):
158
158
from logging import getLogger
159
159
from time import time_ns
160
160
from timeit import default_timer
161
- from typing import Collection
161
+ from typing import Collection , Dict
162
162
163
163
import tornado .web
164
164
import wrapt
@@ -179,6 +179,7 @@ def client_resposne_hook(span, future):
179
179
unwrap ,
180
180
)
181
181
from opentelemetry .metrics import get_meter
182
+ from opentelemetry .metrics ._internal .instrument import Histogram
182
183
from opentelemetry .propagators import textmap
183
184
from opentelemetry .semconv .trace import SpanAttributes
184
185
from opentelemetry .trace .status import Status , StatusCode
@@ -200,6 +201,12 @@ def client_resposne_hook(span, future):
200
201
_OTEL_PATCHED_KEY = "_otel_patched_key"
201
202
202
203
204
+ _START_TIME = "start_time"
205
+ _SERVER_DURATION_HISTOGRAM = "http.server.duration"
206
+ _SERVER_REQUEST_SIZE_HISTOGRAM = "http.server.request.size"
207
+ _SERVER_RESPONSE_SIZE_HISTOGRAM = "http.server.response.size"
208
+ _SERVER_ACTIVE_REQUESTS_HISTOGRAM = "http.server.active_requests"
209
+
203
210
_excluded_urls = get_excluded_urls ("TORNADO" )
204
211
_traced_request_attrs = get_traced_request_attrs ("TORNADO" )
205
212
response_propagation_setter = FuncSetter (tornado .web .RequestHandler .add_header )
@@ -233,31 +240,12 @@ def _instrument(self, **kwargs):
233
240
process lifetime.
234
241
"""
235
242
tracer_provider = kwargs .get ("tracer_provider" )
236
- self . tracer = trace .get_tracer (__name__ , __version__ , tracer_provider )
243
+ tracer = trace .get_tracer (__name__ , __version__ , tracer_provider )
237
244
238
245
meter_provider = kwargs .get ("meter_provider" )
239
246
meter = get_meter (__name__ , __version__ , meter_provider )
240
247
241
- self .duration_histogram = meter .create_histogram (
242
- name = "http.server.duration" ,
243
- unit = "ms" ,
244
- description = "measures the duration outbound HTTP requests" ,
245
- )
246
- self .request_size_histogram = meter .create_histogram (
247
- name = "http.server.request.size" ,
248
- unit = "By" ,
249
- description = "measures the size of HTTP request messages (compressed)" ,
250
- )
251
- self .response_size_histogram = meter .create_histogram (
252
- name = "http.server.response.size" ,
253
- unit = "By" ,
254
- description = "measures the size of HTTP response messages (compressed)" ,
255
- )
256
- self .active_requests_histogram = meter .create_up_down_counter (
257
- name = "http.server.active_requests" ,
258
- unit = "requests" ,
259
- description = "measures the number of concurrent HTTP requests that are currently in-flight" ,
260
- )
248
+ server_histograms = _create_server_histograms (meter )
261
249
262
250
client_duration_histogram = meter .create_histogram (
263
251
name = "http.client.duration" ,
@@ -281,7 +269,9 @@ def _instrument(self, **kwargs):
281
269
282
270
def handler_init (init , handler , args , kwargs ):
283
271
cls = handler .__class__
284
- if patch_handler_class (self , cls , server_request_hook ):
272
+ if patch_handler_class (
273
+ tracer , server_histograms , cls , server_request_hook
274
+ ):
285
275
self .patched_handlers .append (cls )
286
276
return init (* args , ** kwargs )
287
277
@@ -293,7 +283,7 @@ def handler_init(init, handler, args, kwargs):
293
283
"AsyncHTTPClient.fetch" ,
294
284
partial (
295
285
fetch_async ,
296
- self . tracer ,
286
+ tracer ,
297
287
client_request_hook ,
298
288
client_response_hook ,
299
289
client_duration_histogram ,
@@ -310,14 +300,49 @@ def _uninstrument(self, **kwargs):
310
300
self .patched_handlers = []
311
301
312
302
313
- def patch_handler_class (instrumentation , cls , request_hook = None ):
303
+ def _create_server_histograms (meter ) -> Dict [str , Histogram ]:
304
+ histograms = {
305
+ _SERVER_DURATION_HISTOGRAM : meter .create_histogram (
306
+ name = "http.server.duration" ,
307
+ unit = "ms" ,
308
+ description = "measures the duration outbound HTTP requests" ,
309
+ ),
310
+ _SERVER_REQUEST_SIZE_HISTOGRAM : meter .create_histogram (
311
+ name = "http.server.request.size" ,
312
+ unit = "By" ,
313
+ description = "measures the size of HTTP request messages (compressed)" ,
314
+ ),
315
+ _SERVER_RESPONSE_SIZE_HISTOGRAM : meter .create_histogram (
316
+ name = "http.server.response.size" ,
317
+ unit = "By" ,
318
+ description = "measures the size of HTTP response messages (compressed)" ,
319
+ ),
320
+ _SERVER_ACTIVE_REQUESTS_HISTOGRAM : meter .create_up_down_counter (
321
+ name = "http.server.active_requests" ,
322
+ unit = "requests" ,
323
+ description = "measures the number of concurrent HTTP requests that are currently in-flight" ,
324
+ ),
325
+ }
326
+
327
+ return histograms
328
+
329
+
330
+ def patch_handler_class (tracer , server_histograms , cls , request_hook = None ):
314
331
if getattr (cls , _OTEL_PATCHED_KEY , False ):
315
332
return False
316
333
317
334
setattr (cls , _OTEL_PATCHED_KEY , True )
318
- _wrap (cls , "prepare" , partial (_prepare , instrumentation , request_hook ))
319
- _wrap (cls , "on_finish" , partial (_on_finish , instrumentation ))
320
- _wrap (cls , "log_exception" , partial (_log_exception , instrumentation ))
335
+ _wrap (
336
+ cls ,
337
+ "prepare" ,
338
+ partial (_prepare , tracer , server_histograms , request_hook ),
339
+ )
340
+ _wrap (cls , "on_finish" , partial (_on_finish , tracer , server_histograms ))
341
+ _wrap (
342
+ cls ,
343
+ "log_exception" ,
344
+ partial (_log_exception , tracer , server_histograms ),
345
+ )
321
346
return True
322
347
323
348
@@ -337,38 +362,41 @@ def _wrap(cls, method_name, wrapper):
337
362
wrapt .apply_patch (cls , method_name , wrapper )
338
363
339
364
340
- def _prepare (instrumentation , request_hook , func , handler , args , kwargs ):
341
- instrumentation .start_time = default_timer ()
365
+ def _prepare (
366
+ tracer , server_histograms , request_hook , func , handler , args , kwargs
367
+ ):
368
+ server_histograms [_START_TIME ] = default_timer ()
369
+
342
370
request = handler .request
343
371
if _excluded_urls .url_disabled (request .uri ):
344
372
return func (* args , ** kwargs )
345
373
346
- _record_prepare_metrics (instrumentation , handler )
374
+ _record_prepare_metrics (server_histograms , handler )
347
375
348
- ctx = _start_span (instrumentation . tracer , handler )
376
+ ctx = _start_span (tracer , handler )
349
377
if request_hook :
350
378
request_hook (ctx .span , handler )
351
379
return func (* args , ** kwargs )
352
380
353
381
354
- def _on_finish (instrumentation , func , handler , args , kwargs ):
382
+ def _on_finish (tracer , server_histograms , func , handler , args , kwargs ):
355
383
response = func (* args , ** kwargs )
356
384
357
- _record_on_finish_metrics (instrumentation , handler )
385
+ _record_on_finish_metrics (server_histograms , handler )
358
386
359
- _finish_span (instrumentation . tracer , handler )
387
+ _finish_span (tracer , handler )
360
388
361
389
return response
362
390
363
391
364
- def _log_exception (instrumentation , func , handler , args , kwargs ):
392
+ def _log_exception (tracer , server_histograms , func , handler , args , kwargs ):
365
393
error = None
366
394
if len (args ) == 3 :
367
395
error = args [1 ]
368
396
369
- _record_on_finish_metrics (instrumentation , handler , error )
397
+ _record_on_finish_metrics (server_histograms , handler , error )
370
398
371
- _finish_span (instrumentation , handler , error )
399
+ _finish_span (tracer , handler , error )
372
400
return func (* args , ** kwargs )
373
401
374
402
@@ -521,43 +549,45 @@ def _finish_span(tracer, handler, error=None):
521
549
delattr (handler , _HANDLER_CONTEXT_KEY )
522
550
523
551
524
- def _record_prepare_metrics (instrumentation , handler ):
552
+ def _record_prepare_metrics (server_histograms , handler ):
525
553
request_size = len (handler .request .body )
526
554
metric_attributes = _create_metric_attributes (handler )
527
555
528
- instrumentation . request_size_histogram .record (
556
+ server_histograms [ _SERVER_REQUEST_SIZE_HISTOGRAM ] .record (
529
557
request_size , attributes = metric_attributes
530
558
)
531
559
532
560
active_requests_attributes = _create_active_requests_attributes (
533
561
handler .request
534
562
)
535
- instrumentation . active_requests_histogram .add (
563
+ server_histograms [ _SERVER_ACTIVE_REQUESTS_HISTOGRAM ] .add (
536
564
1 , attributes = active_requests_attributes
537
565
)
538
566
539
567
540
- def _record_on_finish_metrics (instrumentation , handler , error = None ):
541
- elapsed_time = round ((default_timer () - instrumentation .start_time ) * 1000 )
568
+ def _record_on_finish_metrics (server_histograms , handler , error = None ):
569
+ elapsed_time = round (
570
+ (default_timer () - server_histograms [_START_TIME ]) * 1000
571
+ )
542
572
543
573
response_size = int (handler ._headers .get ("Content-Length" , 0 ))
544
574
metric_attributes = _create_metric_attributes (handler )
545
575
546
576
if isinstance (error , tornado .web .HTTPError ):
547
577
metric_attributes [SpanAttributes .HTTP_STATUS_CODE ] = error .status_code
548
578
549
- instrumentation . response_size_histogram .record (
579
+ server_histograms [ _SERVER_RESPONSE_SIZE_HISTOGRAM ] .record (
550
580
response_size , attributes = metric_attributes
551
581
)
552
582
553
- instrumentation . duration_histogram .record (
583
+ server_histograms [ _SERVER_DURATION_HISTOGRAM ] .record (
554
584
elapsed_time , attributes = metric_attributes
555
585
)
556
586
557
587
active_requests_attributes = _create_active_requests_attributes (
558
588
handler .request
559
589
)
560
- instrumentation . active_requests_histogram .add (
590
+ server_histograms [ _SERVER_ACTIVE_REQUESTS_HISTOGRAM ] .add (
561
591
- 1 , attributes = active_requests_attributes
562
592
)
563
593
0 commit comments