@@ -158,7 +158,7 @@ def client_resposne_hook(span, future):
158158from logging import getLogger
159159from time import time_ns
160160from timeit import default_timer
161- from typing import Collection
161+ from typing import Collection , Dict
162162
163163import tornado .web
164164import wrapt
@@ -179,6 +179,7 @@ def client_resposne_hook(span, future):
179179 unwrap ,
180180)
181181from opentelemetry .metrics import get_meter
182+ from opentelemetry .metrics ._internal .instrument import Histogram
182183from opentelemetry .propagators import textmap
183184from opentelemetry .semconv .trace import SpanAttributes
184185from opentelemetry .trace .status import Status , StatusCode
@@ -200,6 +201,12 @@ def client_resposne_hook(span, future):
200201_OTEL_PATCHED_KEY = "_otel_patched_key"
201202
202203
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+
203210_excluded_urls = get_excluded_urls ("TORNADO" )
204211_traced_request_attrs = get_traced_request_attrs ("TORNADO" )
205212response_propagation_setter = FuncSetter (tornado .web .RequestHandler .add_header )
@@ -233,31 +240,12 @@ def _instrument(self, **kwargs):
233240 process lifetime.
234241 """
235242 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 )
237244
238245 meter_provider = kwargs .get ("meter_provider" )
239246 meter = get_meter (__name__ , __version__ , meter_provider )
240247
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 )
261249
262250 client_duration_histogram = meter .create_histogram (
263251 name = "http.client.duration" ,
@@ -281,7 +269,9 @@ def _instrument(self, **kwargs):
281269
282270 def handler_init (init , handler , args , kwargs ):
283271 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+ ):
285275 self .patched_handlers .append (cls )
286276 return init (* args , ** kwargs )
287277
@@ -293,7 +283,7 @@ def handler_init(init, handler, args, kwargs):
293283 "AsyncHTTPClient.fetch" ,
294284 partial (
295285 fetch_async ,
296- self . tracer ,
286+ tracer ,
297287 client_request_hook ,
298288 client_response_hook ,
299289 client_duration_histogram ,
@@ -310,14 +300,49 @@ def _uninstrument(self, **kwargs):
310300 self .patched_handlers = []
311301
312302
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 ):
314331 if getattr (cls , _OTEL_PATCHED_KEY , False ):
315332 return False
316333
317334 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+ )
321346 return True
322347
323348
@@ -337,38 +362,41 @@ def _wrap(cls, method_name, wrapper):
337362 wrapt .apply_patch (cls , method_name , wrapper )
338363
339364
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+
342370 request = handler .request
343371 if _excluded_urls .url_disabled (request .uri ):
344372 return func (* args , ** kwargs )
345373
346- _record_prepare_metrics (instrumentation , handler )
374+ _record_prepare_metrics (server_histograms , handler )
347375
348- ctx = _start_span (instrumentation . tracer , handler )
376+ ctx = _start_span (tracer , handler )
349377 if request_hook :
350378 request_hook (ctx .span , handler )
351379 return func (* args , ** kwargs )
352380
353381
354- def _on_finish (instrumentation , func , handler , args , kwargs ):
382+ def _on_finish (tracer , server_histograms , func , handler , args , kwargs ):
355383 response = func (* args , ** kwargs )
356384
357- _record_on_finish_metrics (instrumentation , handler )
385+ _record_on_finish_metrics (server_histograms , handler )
358386
359- _finish_span (instrumentation . tracer , handler )
387+ _finish_span (tracer , handler )
360388
361389 return response
362390
363391
364- def _log_exception (instrumentation , func , handler , args , kwargs ):
392+ def _log_exception (tracer , server_histograms , func , handler , args , kwargs ):
365393 error = None
366394 if len (args ) == 3 :
367395 error = args [1 ]
368396
369- _record_on_finish_metrics (instrumentation , handler , error )
397+ _record_on_finish_metrics (server_histograms , handler , error )
370398
371- _finish_span (instrumentation , handler , error )
399+ _finish_span (tracer , handler , error )
372400 return func (* args , ** kwargs )
373401
374402
@@ -521,43 +549,45 @@ def _finish_span(tracer, handler, error=None):
521549 delattr (handler , _HANDLER_CONTEXT_KEY )
522550
523551
524- def _record_prepare_metrics (instrumentation , handler ):
552+ def _record_prepare_metrics (server_histograms , handler ):
525553 request_size = len (handler .request .body )
526554 metric_attributes = _create_metric_attributes (handler )
527555
528- instrumentation . request_size_histogram .record (
556+ server_histograms [ _SERVER_REQUEST_SIZE_HISTOGRAM ] .record (
529557 request_size , attributes = metric_attributes
530558 )
531559
532560 active_requests_attributes = _create_active_requests_attributes (
533561 handler .request
534562 )
535- instrumentation . active_requests_histogram .add (
563+ server_histograms [ _SERVER_ACTIVE_REQUESTS_HISTOGRAM ] .add (
536564 1 , attributes = active_requests_attributes
537565 )
538566
539567
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+ )
542572
543573 response_size = int (handler ._headers .get ("Content-Length" , 0 ))
544574 metric_attributes = _create_metric_attributes (handler )
545575
546576 if isinstance (error , tornado .web .HTTPError ):
547577 metric_attributes [SpanAttributes .HTTP_STATUS_CODE ] = error .status_code
548578
549- instrumentation . response_size_histogram .record (
579+ server_histograms [ _SERVER_RESPONSE_SIZE_HISTOGRAM ] .record (
550580 response_size , attributes = metric_attributes
551581 )
552582
553- instrumentation . duration_histogram .record (
583+ server_histograms [ _SERVER_DURATION_HISTOGRAM ] .record (
554584 elapsed_time , attributes = metric_attributes
555585 )
556586
557587 active_requests_attributes = _create_active_requests_attributes (
558588 handler .request
559589 )
560- instrumentation . active_requests_histogram .add (
590+ server_histograms [ _SERVER_ACTIVE_REQUESTS_HISTOGRAM ] .add (
561591 - 1 , attributes = active_requests_attributes
562592 )
563593
0 commit comments