1+ from typing import Any
2+ from typing import Dict
13from weakref import WeakValueDictionary
24
5+ from ddtrace .span import Span
6+
37from .constants import CTX_KEY
48
59
6- def tags_from_context (context ):
10+ TAG_KEYS = frozenset (
11+ [
12+ ("compression" , "celery.compression" ),
13+ ("correlation_id" , "celery.correlation_id" ),
14+ ("countdown" , "celery.countdown" ),
15+ ("delivery_info" , "celery.delivery_info" ),
16+ ("eta" , "celery.eta" ),
17+ ("exchange" , "celery.exchange" ),
18+ ("expires" , "celery.expires" ),
19+ ("hostname" , "celery.hostname" ),
20+ ("id" , "celery.id" ),
21+ ("priority" , "celery.priority" ),
22+ ("queue" , "celery.queue" ),
23+ ("reply_to" , "celery.reply_to" ),
24+ ("retries" , "celery.retries" ),
25+ ("routing_key" , "celery.routing_key" ),
26+ ("serializer" , "celery.serializer" ),
27+ ("timelimit" , "celery.timelimit" ),
28+ # Celery 4.0 uses `origin` instead of `hostname`; this change preserves
29+ # the same name for the tag despite Celery version
30+ ("origin" , "celery.hostname" ),
31+ ("state" , "celery.state" ),
32+ ]
33+ )
34+
35+
36+ def set_tags_from_context (span , context ):
37+ # type: (Span, Dict[str, Any]) -> None
738 """Helper to extract meta values from a Celery Context"""
8- tag_keys = (
9- "compression" ,
10- "correlation_id" ,
11- "countdown" ,
12- "delivery_info" ,
13- "eta" ,
14- "exchange" ,
15- "expires" ,
16- "hostname" ,
17- "id" ,
18- "priority" ,
19- "queue" ,
20- "reply_to" ,
21- "retries" ,
22- "routing_key" ,
23- "serializer" ,
24- "timelimit" ,
25- "origin" ,
26- "state" ,
27- )
28-
29- tags = {}
30- for key in tag_keys :
39+
40+ for key , tag_name in TAG_KEYS :
3141 value = context .get (key )
3242
3343 # Skip this key if it is not set
3444 if value is None or value == "" :
3545 continue
3646
37- # Skip `timelimit` if it is not set (it's default/unset value is a
47+ # Skip `timelimit` if it is not set (its default/unset value is a
3848 # tuple or a list of `None` values
39- if key == "timelimit" and value in [( None , None ), [ None , None ]] :
49+ if key == "timelimit" and all ( _ is None for _ in value ) :
4050 continue
4151
42- # Skip `retries` if it's value is `0`
52+ # Skip `retries` if its value is `0`
4353 if key == "retries" and value == 0 :
4454 continue
4555
46- # Celery 4.0 uses `origin` instead of `hostname`; this change preserves
47- # the same name for the tag despite Celery version
48- if key == "origin" :
49- key = "hostname"
50-
51- # prefix the tag as 'celery'
52- tag_name = "celery.{}" .format (key )
53- tags [tag_name ] = value
54- return tags
56+ span .set_tag (tag_name , value )
5557
5658
5759def attach_span (task , task_id , span , is_publish = False ):
@@ -64,7 +66,7 @@ def attach_span(task, task_id, span, is_publish=False):
6466 task from within another task does not cause any conflicts.
6567
6668 This mostly happens when either a task fails and a retry policy is in place,
67- or when a task is manually retries (e.g. `task.retry()`), we end up trying
69+ or when a task is manually retried (e.g. `task.retry()`), we end up trying
6870 to publish a task with the same id as the task currently running.
6971
7072 Previously publishing the new task would overwrite the existing `celery.run` span
@@ -90,7 +92,10 @@ def detach_span(task, task_id, is_publish=False):
9092 return
9193
9294 # DEV: See note in `attach_span` for key info
93- weak_dict .pop ((task_id , is_publish ), None )
95+ try :
96+ del weak_dict [(task_id , is_publish )]
97+ except KeyError :
98+ pass
9499
95100
96101def retrieve_span (task , task_id , is_publish = False ):
0 commit comments