Skip to content

Commit 5eab094

Browse files
committed
refactor tracer provider, add a xray provider
1 parent 06c9110 commit 5eab094

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .xray_provider import Xray_provider
2+
3+
__all__ = ["Xray_provider"]

aws_lambda_powertools/tracing/provider/base.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import numbers
33
import traceback
44
from contextlib import contextmanager
5-
from typing import Any, Generator, List, Optional, Sequence, Union
5+
from typing import Any, Callable, Generator, List, Optional, Sequence, Union
66

77

88
class BaseSegment(abc.ABC):
@@ -72,11 +72,30 @@ def add_exception(self, exception: BaseException, stack: List[traceback.StackSum
7272
Whether it's a client error (False) or downstream service error (True), by default False
7373
"""
7474

75+
# new function below
76+
@abc.abstractmethod
77+
def ignore_endpoint(self, hostname: Optional[str] = None, urls: Optional[List[str]] = None):
78+
"""To ignore the endpoints you don't want requests to be traced,
79+
perhaps due to the volume of calls or sensitive URLs."""
80+
81+
@abc.abstractmethod
82+
def inject_context(self, context):
83+
"""To inject missing context/information like service name"""
84+
85+
@abc.abstractmethod
86+
def capture_method_async(
87+
self,
88+
method: Callable,
89+
capture_response: Optional[Union[bool, str]] = None,
90+
capture_error: Optional[Union[bool, str]] = None,
91+
):
92+
"""To capture async method"""
93+
7594

7695
class BaseProvider(abc.ABC):
7796
@abc.abstractmethod
7897
@contextmanager
79-
def in_subsegment(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
98+
def trace(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
8099
"""Return a subsegment context manger.
81100
82101
Parameters
@@ -89,7 +108,7 @@ def in_subsegment(self, name=None, **kwargs) -> Generator[BaseSegment, None, Non
89108

90109
@abc.abstractmethod
91110
@contextmanager
92-
def in_subsegment_async(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
111+
def trace_async(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
93112
"""Return a subsegment async context manger.
94113
95114
Parameters
@@ -100,6 +119,18 @@ def in_subsegment_async(self, name=None, **kwargs) -> Generator[BaseSegment, Non
100119
Optional parameters to be propagated to segment
101120
"""
102121

122+
@abc.abstractmethod
123+
def start_span(self, name=None) -> Generator[BaseSegment, None, None]:
124+
"""This method is proposed as a solution as it exists for other providers
125+
This method is responsible for starting the trace. This might involve initializing some data structures,
126+
connecting to an external service, or performing some other setup work"""
127+
128+
@abc.abstractmethod
129+
def end_span(self, span: BaseSegment):
130+
"""This method is proposed as a solution as it exists for other providers.
131+
This method is responsible for ending the tracing of a span. This might involve finalizing data structures,
132+
sending data to an external service, or performing some other cleanup work"""
133+
103134
@abc.abstractmethod
104135
def put_annotation(self, key: str, value: Union[str, numbers.Number, bool]) -> None:
105136
"""Annotate current active trace entity with a key-value pair.
@@ -130,6 +161,10 @@ def put_metadata(self, key: str, value: Any, namespace: str = "default") -> None
130161
Metadata namespace, by default 'default'
131162
"""
132163

164+
@abc.abstractmethod
165+
def put_exception(self, *args, **kwargs) -> None:
166+
"""Add exception to the current active trace entity."""
167+
133168
@abc.abstractmethod
134169
def patch(self, modules: Sequence[str]) -> None:
135170
"""Instrument a set of supported libraries
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from contextlib import contextmanager
2+
from typing import Generator, Optional
3+
4+
from ...shared import constants
5+
from ...shared.lazy_import import LazyLoader
6+
from .base import BaseProvider, BaseSegment
7+
8+
aws_xray_sdk = LazyLoader(constants.XRAY_SDK_MODULE, globals(), constants.XRAY_SDK_MODULE)
9+
10+
11+
class Xray_provider(BaseProvider):
12+
def __init__(self):
13+
from aws_xray_sdk.core import xray_recorder
14+
15+
self.recorder = xray_recorder
16+
self.patch = aws_xray_sdk.core.patch
17+
self.patch_all = aws_xray_sdk.core.patch_all
18+
self.put_annotation = self.recorder.put_annotation
19+
self.put_metadata = self.recorder.put_metadata
20+
21+
@contextmanager
22+
def trace(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
23+
"""Return a subsegment context manger.
24+
25+
Parameters
26+
----------
27+
name: str
28+
Subsegment name
29+
kwargs: Optional[dict]
30+
Optional parameters to be propagated to segment
31+
"""
32+
return self.recorder.in_subsegment(name)
33+
34+
@contextmanager
35+
def trace_async(self, name=None, **kwargs) -> Generator[BaseSegment, None, None]:
36+
"""Return a subsegment async context manger.
37+
38+
Parameters
39+
----------
40+
name: str
41+
Subsegment name
42+
kwargs: Optional[dict]
43+
Optional parameters to be propagated to segment
44+
"""
45+
return self.recorder.in_subsegment_async(name)
46+
47+
# we don't need to start,end explicitly in xray
48+
def start_span(self, name=None) -> Generator[BaseSegment, None, None]:
49+
"""This method is proposed as a solution as it exists for other providers
50+
This method is responsible for starting the trace. This might involve initializing some data structures,
51+
connecting to an external service, or performing some other setup work"""
52+
raise Exception("Not implemented")
53+
54+
def end_span(self, span: BaseSegment):
55+
"""This method is proposed as a solution as it exists for other providers.
56+
This method is responsible for ending the tracing of a span. This might involve finalizing data structures,
57+
sending data to an external service, or performing some other cleanup work"""
58+
raise Exception("Not implemented")
59+
60+
def put_exception(
61+
self,
62+
method_name: str,
63+
error: Exception,
64+
subsegment: BaseSegment,
65+
capture_error: Optional[bool] = None,
66+
namespace: str = None,
67+
):
68+
if not capture_error:
69+
return
70+
self.put_metadata(key=f"{method_name} error", value=error, namespace=namespace)

0 commit comments

Comments
 (0)