Skip to content

Commit

Permalink
refactor: add other attibutes to the function
Browse files Browse the repository at this point in the history
Signed-off-by: QuentinN42 <[email protected]>
  • Loading branch information
QuentinN42 committed Jan 9, 2024
1 parent 0a07584 commit f30f87e
Showing 1 changed file with 71 additions and 24 deletions.
95 changes: 71 additions & 24 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,15 @@
from enum import Enum
from functools import wraps
from logging import getLogger
from typing import Callable, Iterator, Optional, Sequence, cast
from typing import (
Callable,
Iterator,
Optional,
ParamSpec,
Sequence,
TypeVar,
cast,
)

from deprecated import deprecated

Expand Down Expand Up @@ -116,6 +124,9 @@

logger = getLogger(__name__)

P = ParamSpec("P")
R = TypeVar("R")


class _LinkBase(ABC):
def __init__(self, context: "SpanContext") -> None:
Expand Down Expand Up @@ -274,34 +285,70 @@ class Tracer(ABC):
and controlling spans' lifecycles.
"""

def _with_span_sync(self, func: Callable) -> Callable:
"""Decorate sync functions."""

@wraps(func)
def func_wrapper(*args, **kwargs):
with self.start_as_current_span(func.__name__):
return func(*args, **kwargs)

return func_wrapper

def _with_span_async(self, func: Callable) -> Callable:
"""Decorate async functions."""
def decorate(
self,
name: str = None,
kind: SpanKind = SpanKind.INTERNAL,
attributes: types.Attributes = None,
record_exception: bool = True,
set_status_on_exception: bool = True,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
"""Decorate the function with a span.
@wraps(func)
async def func_wrapper(*args, **kwargs):
with self.start_as_current_span(func.__name__):
return await func(*args, **kwargs)
Decorate the function with a span. For more information see `start_as_current_span`.
return func_wrapper
Example::
def decorate(self, func: Callable) -> Callable:
# define if a function is async or not
CO_COROUTINE = 0x0080
@tracer.decorate()
def foo():
pass
if bool(func.__code__.co_flags & CO_COROUTINE):
return self._with_span_async(func)
Args:
name: The name of the span to be created, if not provided, the function
name will be used.
kind: The span's kind (relationship to parent). Note that is
meaningful even if there is no parent.
attributes: The span's attributes.
record_exception: Whether to record any exceptions raised within the
context as error event on the span.
set_status_on_exception: Only relevant if the returned span is used
in a with/context manager. Defines whether the span status will
be automatically set to ERROR when an uncaught exception is
raised in the span with block. The span status won't be set by
this mechanism if it was previously set manually.
"""

return self._with_span_sync(func)
def __decorator(func: Callable[P, R]) -> Callable[P, R]:
_span_name = name or func.__name__
if bool(func.__code__.co_flags & 0x80):

@wraps(func)
async def __decorated(*args, **kwargs):
with self.start_as_current_span(
name=_span_name,
kind=kind,
attributes=attributes,
record_exception=record_exception,
set_status_on_exception=set_status_on_exception,
):
return await func(*args, **kwargs)

else:

@wraps(func)
def __decorated(*args, **kwargs):
with self.start_as_current_span(
name=_span_name,
kind=kind,
attributes=attributes,
record_exception=record_exception,
set_status_on_exception=set_status_on_exception,
):
return func(*args, **kwargs)

return __decorated

return __decorator

@abstractmethod
def start_span(
Expand Down

0 comments on commit f30f87e

Please sign in to comment.