@@ -69,27 +69,8 @@ def func():
69
69
asyncio metric types
70
70
---------------------
71
71
72
- * asyncio.futures.duration (ms) - Duration of the future
73
- * asyncio.futures.exceptions (count) - Number of exceptions raised by the future
74
- * asyncio.futures.cancelled (count) - Number of futures cancelled
75
- * asyncio.futures.created (count) - Number of futures created
76
- * asyncio.futures.active (count) - Number of futures active
77
- * asyncio.futures.finished (count) - Number of futures finished
78
- * asyncio.futures.timeouts (count) - Number of futures timed out
79
-
80
- * asyncio.coroutine.duration (ms) - Duration of the coroutine
81
- * asyncio.coroutine.exceptions (count) - Number of exceptions raised by the coroutine
82
- * asyncio.coroutine.created (count) - Number of coroutines created
83
- * asyncio.coroutine.active (count) - Number of coroutines active
84
- * asyncio.coroutine.finished (count) - Number of coroutines finished
85
- * asyncio.coroutine.timeouts (count) - Number of coroutines timed out
86
- * asyncio.coroutine.cancelled (count) - Number of coroutines cancelled
87
-
88
- * asyncio.to_thread.duration (ms) - Duration of the to_thread
89
- * asyncio.to_thread.exceptions (count) - Number of exceptions raised by the to_thread
90
- * asyncio.to_thread.created (count) - Number of to_thread created
91
- * asyncio.to_thread.active (count) - Number of to_thread active
92
- * asyncio.to_thread.finished (count) - Number of to_thread finished
72
+ * asyncio.process.duration (seconds) - Duration of asyncio process
73
+ * asyncio.process.count (count) - Number of asyncio process
93
74
94
75
95
76
API
@@ -103,30 +84,6 @@ def func():
103
84
104
85
from wrapt import wrap_function_wrapper as _wrap
105
86
106
- # pylint: disable=no-name-in-module
107
- from opentelemetry .instrumentation .asyncio .metrics import (
108
- ASYNCIO_COROUTINE_ACTIVE ,
109
- ASYNCIO_COROUTINE_CANCELLED ,
110
- ASYNCIO_COROUTINE_CREATED ,
111
- ASYNCIO_COROUTINE_DURATION ,
112
- ASYNCIO_COROUTINE_EXCEPTIONS ,
113
- ASYNCIO_COROUTINE_FINISHED ,
114
- ASYNCIO_COROUTINE_NAME ,
115
- ASYNCIO_COROUTINE_TIMEOUTS ,
116
- ASYNCIO_EXCEPTIONS_NAME ,
117
- ASYNCIO_FUTURES_ACTIVE ,
118
- ASYNCIO_FUTURES_CANCELLED ,
119
- ASYNCIO_FUTURES_CREATED ,
120
- ASYNCIO_FUTURES_DURATION ,
121
- ASYNCIO_FUTURES_EXCEPTIONS ,
122
- ASYNCIO_FUTURES_FINISHED ,
123
- ASYNCIO_FUTURES_TIMEOUTS ,
124
- ASYNCIO_TO_THREAD_ACTIVE ,
125
- ASYNCIO_TO_THREAD_CREATED ,
126
- ASYNCIO_TO_THREAD_DURATION ,
127
- ASYNCIO_TO_THREAD_EXCEPTIONS ,
128
- ASYNCIO_TO_THREAD_FINISHED ,
129
- )
130
87
from opentelemetry .instrumentation .asyncio .package import _instruments
131
88
from opentelemetry .instrumentation .asyncio .utils import (
132
89
get_coros_to_trace ,
@@ -161,27 +118,8 @@ class AsyncioInstrumentor(BaseInstrumentor):
161
118
162
119
def __init__ (self ):
163
120
super ().__init__ ()
164
- self .to_thread_duration_metric = None
165
- self .to_thread_exception_metric = None
166
- self .to_thread_active_metric = None
167
- self .to_thread_created_metric = None
168
- self .to_thread_finished_metric = None
169
-
170
- self .coro_duration_metric = None
171
- self .coro_exception_metric = None
172
- self .coro_cancelled_metric = None
173
- self .coro_active_metric = None
174
- self .coro_created_metric = None
175
- self .coro_finished_metric = None
176
- self .coro_timeout_metric = None
177
-
178
- self .future_duration_metric = None
179
- self .future_exception_metric = None
180
- self .future_cancelled_metric = None
181
- self .future_active_metric = None
182
- self .future_created_metric = None
183
- self .future_finished_metric = None
184
- self .future_timeout_metric = None
121
+ self .process_duration_metric = None
122
+ self .process_counts_metric = None
185
123
186
124
self ._tracer = None
187
125
self ._meter = None
@@ -203,9 +141,16 @@ def _instrument(self, **kwargs):
203
141
self ._future_active_enabled = get_future_trace_enabled ()
204
142
self ._to_thread_name_to_trace = get_to_thread_to_trace ()
205
143
206
- self .create_coro_metric ()
207
- self .create_future_metric ()
208
- self .create_to_thread_metric ()
144
+ self .process_duration_metric = self ._meter .create_histogram (
145
+ name = "asyncio.process.duration" ,
146
+ description = "Duration of asyncio process" ,
147
+ unit = "seconds" ,
148
+ )
149
+ self .process_counts_metric = self ._meter .create_up_down_counter (
150
+ name = "asyncio.process.count" ,
151
+ description = "Number of asyncio process" ,
152
+ unit = "1" ,
153
+ )
209
154
210
155
for method in self .methods_with_coroutine :
211
156
self .instrument_method_with_coroutine (method )
@@ -295,28 +240,26 @@ def wrap_taskgroup_create_task(method, instance, args, kwargs):
295
240
def trace_to_thread (self , func ):
296
241
"""Trace a function."""
297
242
start = default_timer ()
298
- self .to_thread_created_metric .add (1 )
299
- self .to_thread_active_metric .add (1 )
300
243
span = (
301
244
self ._tracer .start_span (
302
245
f"{ ASYNCIO_PREFIX } to_thread_func-" + func .__name__
303
246
)
304
247
if func .__name__ in self ._to_thread_name_to_trace
305
248
else None
306
249
)
250
+ attr = {"type" : "to_thread" , "name" : func .__name__ }
251
+ duration_attr = attr .copy ()
307
252
exception = None
308
253
try :
254
+ attr ["state" ] = "finished"
309
255
return func
310
- except Exception as exc :
311
- exception_attr = {ASYNCIO_EXCEPTIONS_NAME : exc .__class__ .__name__ }
312
- exception = exc
313
- self .to_thread_exception_metric .add (1 , exception_attr )
256
+ except Exception :
257
+ attr ["state" ] = "exception"
314
258
raise
315
259
finally :
316
260
duration = max (round ((default_timer () - start ) * 1000 ), 0 )
317
- self .to_thread_duration_metric .record (duration )
318
- self .to_thread_finished_metric .add (1 )
319
- self .to_thread_active_metric .add (- 1 )
261
+ self .process_duration_metric .record (duration , duration_attr )
262
+ self .process_counts_metric .add (1 , attr )
320
263
if span :
321
264
if span .is_recording () and exception :
322
265
span .set_status (Status (StatusCode .ERROR ))
@@ -336,42 +279,34 @@ def trace_item(self, coro_or_future):
336
279
337
280
async def trace_coroutine (self , coro ):
338
281
start = default_timer ()
339
- coro_attr = {
340
- ASYNCIO_COROUTINE_NAME : coro .__name__ ,
282
+ attr = {
283
+ "type" : "coroutine" ,
284
+ "name" : coro .__name__ ,
341
285
}
342
- self .coro_created_metric .add (1 , coro_attr )
343
- self .coro_active_metric .add (1 , coro_attr )
344
-
286
+ duration_attr = attr .copy ()
345
287
span = (
346
288
self ._tracer .start_span (f"{ ASYNCIO_PREFIX } coro-" + coro .__name__ )
347
289
if coro .__name__ in self ._coros_name_to_trace
348
290
else None
349
291
)
350
-
351
292
exception = None
352
293
try :
294
+ attr ["state" ] = "finished"
353
295
return await coro
354
296
# CancelledError is raised when a coroutine is cancelled
355
297
# before it has a chance to run. We don't want to record
356
298
# this as an error.
357
299
except asyncio .CancelledError :
358
- self .coro_cancelled_metric .add (1 , coro_attr )
359
- except asyncio .TimeoutError :
360
- self .coro_timeout_metric .add (1 , coro_attr )
361
- raise
300
+ attr ["state" ] = "cancelled"
362
301
except Exception as exc :
363
302
exception = exc
364
- coro_exception_attr = coro_attr .copy ()
365
- coro_exception_attr [
366
- ASYNCIO_EXCEPTIONS_NAME
367
- ] = exc .__class__ .__name__
368
- self .coro_exception_metric .add (1 , coro_exception_attr )
303
+ state = determine_state (exception )
304
+ attr ["state" ] = state
369
305
raise
370
306
finally :
371
- duration = max (round ((default_timer () - start ) * 1000 ), 0 )
372
- self .coro_duration_metric .record (duration , coro_attr )
373
- self .coro_finished_metric .add (1 , coro_attr )
374
- self .coro_active_metric .add (- 1 , coro_attr )
307
+ duration = max (round (default_timer () - start ), 0 )
308
+ self .process_duration_metric .record (duration , duration_attr )
309
+ self .process_counts_metric .add (1 , attr )
375
310
376
311
if span :
377
312
if span .is_recording () and exception :
@@ -381,30 +316,23 @@ async def trace_coroutine(self, coro):
381
316
382
317
def trace_future (self , future ):
383
318
start = default_timer ()
384
- self .future_created_metric .add (1 )
385
- self .future_active_metric .add (1 )
386
319
span = (
387
320
self ._tracer .start_span (f"{ ASYNCIO_PREFIX } future" )
388
321
if self ._future_active_enabled
389
322
else None
390
323
)
391
324
392
325
def callback (f ):
326
+ duration = max (round (default_timer () - start ), 0 )
393
327
exception = f .exception ()
394
- if isinstance (exception , asyncio .CancelledError ):
395
- self .future_cancelled_metric .add (1 )
396
- elif isinstance (exception , asyncio .TimeoutError ):
397
- self .future_timeout_metric .add (1 )
398
- elif exception :
399
- exception_attr = {
400
- ASYNCIO_EXCEPTIONS_NAME : exception .__class__ .__name__
401
- }
402
- self .future_exception_metric .add (1 , exception_attr )
403
-
404
- duration = max (round ((default_timer () - start ) * 1000 ), 0 )
405
- self .future_duration_metric .record (duration )
406
- self .future_finished_metric .add (1 )
407
- self .future_active_metric .add (- 1 )
328
+ attr = {
329
+ "type" : "future" ,
330
+ }
331
+ duration_attr = attr .copy ()
332
+ state = determine_state (exception )
333
+ attr ["state" ] = state
334
+ self .process_counts_metric .add (1 , attr )
335
+ self .process_duration_metric .record (duration , duration_attr )
408
336
if span :
409
337
if span .is_recording () and exception :
410
338
span .set_status (Status (StatusCode .ERROR ))
@@ -414,106 +342,15 @@ def callback(f):
414
342
future .add_done_callback (callback )
415
343
return future
416
344
417
- def create_coro_metric (self ):
418
- self .coro_duration_metric = self ._meter .create_histogram (
419
- name = ASYNCIO_COROUTINE_DURATION ,
420
- description = "Duration of asyncio coroutine" ,
421
- unit = "ms" ,
422
- )
423
- self .coro_exception_metric = self ._meter .create_counter (
424
- name = ASYNCIO_COROUTINE_EXCEPTIONS ,
425
- description = "Number of exceptions in asyncio coroutine" ,
426
- unit = "1" ,
427
- )
428
- self .coro_cancelled_metric = self ._meter .create_counter (
429
- name = ASYNCIO_COROUTINE_CANCELLED ,
430
- description = "Number of asyncio coroutine cancelled" ,
431
- unit = "1" ,
432
- )
433
- self .coro_active_metric = self ._meter .create_up_down_counter (
434
- name = ASYNCIO_COROUTINE_ACTIVE ,
435
- description = "Number of asyncio coroutine active" ,
436
- unit = "1" ,
437
- )
438
- self .coro_created_metric = self ._meter .create_counter (
439
- name = ASYNCIO_COROUTINE_CREATED ,
440
- description = "Number of asyncio coroutine created" ,
441
- unit = "1" ,
442
- )
443
- self .coro_finished_metric = self ._meter .create_counter (
444
- name = ASYNCIO_COROUTINE_FINISHED ,
445
- description = "Number of asyncio coroutine finished" ,
446
- unit = "1" ,
447
- )
448
- self .coro_timeout_metric = self ._meter .create_counter (
449
- name = ASYNCIO_COROUTINE_TIMEOUTS ,
450
- description = "Number of asyncio coroutine timeouts" ,
451
- unit = "1" ,
452
- )
453
-
454
- def create_future_metric (self ):
455
- self .future_duration_metric = self ._meter .create_histogram (
456
- name = ASYNCIO_FUTURES_DURATION ,
457
- description = "Duration of asyncio future" ,
458
- unit = "ms" ,
459
- )
460
- self .future_exception_metric = self ._meter .create_counter (
461
- name = ASYNCIO_FUTURES_EXCEPTIONS ,
462
- description = "Number of exceptions in asyncio future" ,
463
- unit = "1" ,
464
- )
465
- self .future_cancelled_metric = self ._meter .create_counter (
466
- name = ASYNCIO_FUTURES_CANCELLED ,
467
- description = "Number of asyncio future cancelled" ,
468
- unit = "1" ,
469
- )
470
- self .future_created_metric = self ._meter .create_counter (
471
- name = ASYNCIO_FUTURES_CREATED ,
472
- description = "Number of asyncio future created" ,
473
- unit = "1" ,
474
- )
475
- self .future_active_metric = self ._meter .create_up_down_counter (
476
- name = ASYNCIO_FUTURES_ACTIVE ,
477
- description = "Number of asyncio future active" ,
478
- unit = "1" ,
479
- )
480
- self .future_finished_metric = self ._meter .create_counter (
481
- name = ASYNCIO_FUTURES_FINISHED ,
482
- description = "Number of asyncio future finished" ,
483
- unit = "1" ,
484
- )
485
- self .future_timeout_metric = self ._meter .create_counter (
486
- name = ASYNCIO_FUTURES_TIMEOUTS ,
487
- description = "Number of asyncio future timeouts" ,
488
- unit = "1" ,
489
- )
490
345
491
- def create_to_thread_metric (self ):
492
- self .to_thread_duration_metric = self ._meter .create_histogram (
493
- name = ASYNCIO_TO_THREAD_DURATION ,
494
- description = "Duration of asyncio function" ,
495
- unit = "ms" ,
496
- )
497
- self .to_thread_exception_metric = self ._meter .create_counter (
498
- name = ASYNCIO_TO_THREAD_EXCEPTIONS ,
499
- description = "Number of exceptions in asyncio function" ,
500
- unit = "1" ,
501
- )
502
- self .to_thread_created_metric = self ._meter .create_counter (
503
- name = ASYNCIO_TO_THREAD_CREATED ,
504
- description = "Number of asyncio function created" ,
505
- unit = "1" ,
506
- )
507
- self .to_thread_active_metric = self ._meter .create_up_down_counter (
508
- name = ASYNCIO_TO_THREAD_ACTIVE ,
509
- description = "Number of asyncio function active" ,
510
- unit = "1" ,
511
- )
512
- self .to_thread_finished_metric = self ._meter .create_counter (
513
- name = ASYNCIO_TO_THREAD_FINISHED ,
514
- description = "Number of asyncio function finished" ,
515
- unit = "1" ,
516
- )
346
+ def determine_state (exception ):
347
+ if isinstance (exception , asyncio .CancelledError ):
348
+ return "cancelled"
349
+ if isinstance (exception , asyncio .TimeoutError ):
350
+ return "timeout"
351
+ if exception :
352
+ return "exception"
353
+ return "finished"
517
354
518
355
519
356
def uninstrument_taskgroup_create_task ():
0 commit comments