from ddtrace.trace import tracer from ddtrace._trace.context import Context from ddtrace.propagation.http import HTTPPropagator import json from functools import wraps from typing import Optional from ddtrace.trace import tracer from ddtrace.sampler import DatadogSampler from ddtrace.sampling_rule import SamplingRule # env_name is optional and used for ddog sampling for prod, by default set it to dev, which commonly means no sampling def distributed_trace(span_name: str, service_name: str, env_name: str = "dev"): """ A decorator for generating tracing spans around the execution of the decorated function. This function creates a decorator that, when applied to another function, wraps the execution of that function in a tracing span. This is useful for monitoring and debugging the performance and behavior of the decorated function in a distributed system. Args: span_name (str): The name of the span that will be created for tracing. service_name (str): The name of the service under which the span will be categorized. Returns: A decorator function that takes a function and returns a wrapped version of that function with tracing enabled. """ def decorator(func): @wraps(func) def wrapper(self, *args, parent_context: Optional[str] = None, **kwargs): try: if parent_context: parent_context = HTTPPropagator.extract(json.loads(parent_context)) except Exception as e: print("Error extracting parent context:", e) parent_context = None if (env_name == "prod") or (env_name == "msft"): tracer.configure( sampler=DatadogSampler( rules=[ SamplingRule(sample_rate=0.0001), ] ) ) with tracer.start_span( span_name, service=service_name, child_of=parent_context, activate=True, ): return func(self, *args, **kwargs) return wrapper return decorator def serialize_context(context: Optional[Context] = None, http=True) -> str: if context is None: context = tracer.current_trace_context() if http: headers = {} HTTPPropagator.inject(context, headers) return json.dumps(headers) else: # This is deprecated, for backwards compatibility return json.dumps( { "trace_id": context.trace_id, "span_id": context.span_id, } )