Skip to content

Commit 62ea858

Browse files
Merge pull request #93 from ivanildobarauna-dev/feature/implement-otel-observability
[FEATURE] Implement Open Telemetry
2 parents f2ced89 + b63af5d commit 62ea858

File tree

9 files changed

+800
-226
lines changed

9 files changed

+800
-226
lines changed

.idea/api-to-dataframe.iml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

poetry.lock

+776-157
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "api-to-dataframe"
3-
version = "1.3.13"
3+
version = "1.4.0"
44
description = "A package to convert API responses to pandas dataframe"
55
authors = ["IvanildoBarauna <[email protected]>"]
66
readme = "README.md"
@@ -27,7 +27,7 @@ python = "^3.9"
2727
pandas = "^2.2.3"
2828
requests = "^2.32.3"
2929
logging = "^0.4.9.6"
30-
datadog = "^0.50.2"
30+
otel-wrapper = "^0.0.1"
3131

3232
[tool.poetry.group.dev.dependencies]
3333
poetry-dynamic-versioning = "^1.3.0"

src/api_to_dataframe/controller/client_builder.py

+16-20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from api_to_dataframe.models.retainer import retry_strategies, Strategies
22
from api_to_dataframe.models.get_data import GetData
3-
from api_to_dataframe.utils.logger import log, LogLevel
4-
from api_to_dataframe.utils.metrics import MetricsClient
3+
from api_to_dataframe.utils.logger import logger
4+
from otel_wrapper import OpenObservability
55

66

77
class ClientBuilder:
@@ -35,16 +35,16 @@ def __init__( # pylint: disable=too-many-positional-arguments,too-many-argument
3535
if headers is None:
3636
headers = {}
3737
if endpoint == "":
38-
log("endpoint param is mandatory", LogLevel.ERROR)
38+
logger.error("endpoint cannot be an empty string")
3939
raise ValueError
4040
if not isinstance(retries, int) or retries < 0:
41-
log("retries must be a non-negative integer", LogLevel.ERROR)
41+
logger.error("retries must be a non-negative integer")
4242
raise ValueError
4343
if not isinstance(initial_delay, int) or initial_delay < 0:
44-
log("delay must be a non-negative integer", LogLevel.ERROR)
44+
logger.error("initial_delay must be a non-negative integer")
4545
raise ValueError
4646
if not isinstance(connection_timeout, int) or connection_timeout < 0:
47-
log("connection_timeout must be a non-negative integer", LogLevel.ERROR)
47+
logger.error("connection_timeout must be a non-negative integer")
4848
raise ValueError
4949

5050
self.endpoint = endpoint
@@ -53,10 +53,9 @@ def __init__( # pylint: disable=too-many-positional-arguments,too-many-argument
5353
self.headers = headers
5454
self.retries = retries
5555
self.delay = initial_delay
56-
self.metrics_client = MetricsClient()
57-
58-
self.metrics_client.increment("builded_client")
59-
56+
self._o11y_wrapper = OpenObservability(application_name="api-to-dataframe").get_wrapper()
57+
self._traces = self._o11y_wrapper.traces()
58+
self._tracer = self._traces.get_tracer()
6059

6160
@retry_strategies
6261
def get_api_data(self):
@@ -71,16 +70,15 @@ def get_api_data(self):
7170
dict: The JSON response from the API as a dictionary.
7271
"""
7372

74-
self.metrics_client.increment("get_api_data_attempt")
75-
76-
response = GetData.get_response(
77-
endpoint=self.endpoint,
78-
headers=self.headers,
79-
connection_timeout=self.connection_timeout,
80-
)
73+
with self._tracer.start_as_current_span("get_last_quote") as span:
74+
span.set_attribute("endpoint", self.endpoint)
8175

76+
response = GetData.get_response(
77+
endpoint=self.endpoint,
78+
headers=self.headers,
79+
connection_timeout=self.connection_timeout,
80+
)
8281

83-
self.metrics_client.increment("get_api_data_success")
8482

8583
return response.json()
8684

@@ -99,9 +97,7 @@ def api_to_dataframe(response: dict):
9997
Returns:
10098
DataFrame: A pandas DataFrame containing the data from the API response.
10199
"""
102-
MetricsClient().increment("api_to_dataframe_attempt")
103100

104101
df = GetData.to_dataframe(response)
105102

106-
MetricsClient().increment("api_to_dataframe_success")
107103
return df

src/api_to_dataframe/models/get_data.py

-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import requests
22
import pandas as pd
33

4-
from api_to_dataframe.utils.logger import log, LogLevel
5-
64

75
class GetData:
86
@staticmethod
@@ -16,13 +14,11 @@ def to_dataframe(response):
1614
try:
1715
df = pd.DataFrame(response)
1816
except Exception as err:
19-
log(f"Error serializing to dataframe: {err}", LogLevel.ERROR)
2017
raise TypeError(
2118
f"Invalid response for transform in dataframe: {err}"
2219
) from err
2320

2421
if df.empty:
25-
log("DataFrame is empty", LogLevel.ERROR)
2622
raise ValueError("::: DataFrame is empty :::")
2723

2824
return df

src/api_to_dataframe/models/retainer.py

+3-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from enum import Enum
33

44
from requests.exceptions import RequestException
5-
from api_to_dataframe.utils.logger import log, LogLevel
5+
from api_to_dataframe.utils.logger import logger
66
from api_to_dataframe.utils import Constants
77

88

@@ -18,11 +18,7 @@ def wrapper(*args, **kwargs): # pylint: disable=inconsistent-return-statements
1818
while retry_number < args[0].retries:
1919
try:
2020
if retry_number > 0:
21-
log(
22-
f"Trying for the {retry_number} of {Constants.MAX_OF_RETRIES} retries. "
23-
f"Using {args[0].retry_strategy}",
24-
LogLevel.INFO,
25-
)
21+
logger.info(f"Trying for the {retry_number} of {Constants.MAX_OF_RETRIES} retries. Using {args[0].retry_strategy}")
2622
return func(*args, **kwargs)
2723
except RequestException as e:
2824
retry_number += 1
@@ -35,10 +31,7 @@ def wrapper(*args, **kwargs): # pylint: disable=inconsistent-return-statements
3531
time.sleep(args[0].delay * retry_number)
3632

3733
if retry_number in (args[0].retries, Constants.MAX_OF_RETRIES):
38-
log(
39-
f"Failed after {retry_number} retries using {args[0].retry_strategy}",
40-
LogLevel.ERROR,
41-
)
34+
logger.error(f"Failed after {retry_number} retries")
4235
raise e
4336

4437
return wrapper

src/api_to_dataframe/utils/logger.py

+1-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
import logging
2-
from enum import Enum
3-
4-
5-
class LogLevel(Enum):
6-
INFO = logging.INFO
7-
WARNING = logging.WARNING
8-
ERROR = logging.ERROR
9-
102

113
# Configure logging once at the start of your program
124
logging.basicConfig(
@@ -16,7 +8,4 @@ class LogLevel(Enum):
168
level=logging.INFO,
179
)
1810

19-
20-
def log(message: str, level: LogLevel):
21-
logger = logging.getLogger("api-to-dataframe")
22-
logger.log(level.value, message)
11+
logger = logging.getLogger("api-to-dataframe")

src/api_to_dataframe/utils/metrics.py

-19
This file was deleted.

0 commit comments

Comments
 (0)