Skip to content

Commit 8cf83ef

Browse files
committed
fix: add support for missing OpenTelemetry library
1 parent ddf1377 commit 8cf83ef

File tree

4 files changed

+104
-97
lines changed

4 files changed

+104
-97
lines changed

eodag/api/core.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import geojson
2929
import pkg_resources
3030
import yaml.parser
31-
from opentelemetry import trace
3231
from pkg_resources import resource_filename
3332
from whoosh import analysis, fields
3433
from whoosh.fields import Schema
@@ -1655,26 +1654,21 @@ def _do_search(
16551654
total_results = 0
16561655

16571656
try:
1658-
tracer = trace.get_tracer("eodag.tracer")
1659-
with tracer.start_as_current_span("core-search") as span:
1660-
trace_id = span.get_span_context().trace_id
1661-
timer = telemetry.get_overhead_timer(trace_id)
1662-
start_time = perf_counter()
1657+
trace_id = telemetry.get_current_trace_id()
1658+
timer = telemetry.get_overhead_timer(trace_id)
1659+
start_time = perf_counter()
16631660

1664-
if need_auth and auth_plugin and can_authenticate:
1665-
search_plugin.auth = auth_plugin.authenticate()
1661+
if need_auth and auth_plugin and can_authenticate:
1662+
search_plugin.auth = auth_plugin.authenticate()
16661663

1667-
res, nb_res = search_plugin.query(
1668-
count=count, auth=auth_plugin, **kwargs
1669-
)
1664+
res, nb_res = search_plugin.query(count=count, auth=auth_plugin, **kwargs)
16701665

1671-
end_time = perf_counter()
1672-
total_time = end_time - start_time
1673-
telemetry.record_outbound_request_duration(
1674-
search_plugin.provider, total_time
1675-
)
1676-
if timer:
1677-
timer.record_subtask_time(total_time)
1666+
end_time = perf_counter()
1667+
total_time = end_time - start_time
1668+
telemetry.record_outbound_request_duration(
1669+
search_plugin.provider, total_time
1670+
)
1671+
timer.record_subtask_time(total_time)
16781672

16791673
# Only do the pagination computations when it makes sense. For example,
16801674
# for a search by id, we can reasonably guess that the provider will return

eodag/rest/server.py

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
from fastapi.middleware.cors import CORSMiddleware
4545
from fastapi.openapi.utils import get_openapi
4646
from fastapi.responses import ORJSONResponse, StreamingResponse
47-
from opentelemetry import trace
4847
from pydantic import BaseModel
4948
from starlette.exceptions import HTTPException as StarletteHTTPException
5049

@@ -399,26 +398,24 @@ def stac_collections_item_download(
399398
collection_id: str, item_id: str, request: Request
400399
) -> StreamingResponse:
401400
"""STAC collection item download"""
402-
tracer = trace.get_tracer("eodag.tracer")
403-
with tracer.start_as_current_span("server-download") as span:
404-
trace_id = span.get_span_context().trace_id
405-
timer = telemetry.create_overhead_timer(trace_id)
406-
timer.start_global_timer()
407-
logger.debug(f"URL: {request.url}")
408-
409-
arguments = dict(request.query_params)
410-
provider = arguments.pop("provider", None)
411-
412-
response = download_stac_item_by_id_stream(
413-
catalogs=[collection_id], item_id=item_id, provider=provider, **arguments
414-
)
401+
trace_id = telemetry.get_current_trace_id()
402+
timer = telemetry.create_overhead_timer(trace_id)
403+
timer.start_global_timer()
404+
logger.debug(f"URL: {request.url}")
405+
406+
arguments = dict(request.query_params)
407+
provider = arguments.pop("provider", None)
408+
409+
response = download_stac_item_by_id_stream(
410+
catalogs=[collection_id], item_id=item_id, provider=provider, **arguments
411+
)
415412

416-
timer.stop_global_timer()
417-
telemetry.record_request_duration(provider, timer.get_global_time())
418-
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
419-
telemetry.delete_overhead_timer(trace_id)
413+
timer.stop_global_timer()
414+
telemetry.record_request_duration(provider, timer.get_global_time())
415+
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
416+
telemetry.delete_overhead_timer(trace_id)
420417

421-
return response
418+
return response
422419

423420

424421
@router.get(
@@ -602,28 +599,26 @@ def stac_catalogs_item_download(
602599
catalogs: str, item_id: str, request: Request
603600
) -> StreamingResponse:
604601
"""STAC Catalog item download"""
605-
tracer = trace.get_tracer("eodag.tracer")
606-
with tracer.start_as_current_span("server-download") as span:
607-
trace_id = span.get_span_context().trace_id
608-
timer = telemetry.create_overhead_timer(trace_id)
609-
timer.start_global_timer()
610-
logger.debug(f"URL: {request.url}")
602+
trace_id = telemetry.get_current_trace_id()
603+
timer = telemetry.create_overhead_timer(trace_id)
604+
timer.start_global_timer()
605+
logger.debug(f"URL: {request.url}")
611606

612-
arguments = dict(request.query_params)
613-
provider = arguments.pop("provider", None)
607+
arguments = dict(request.query_params)
608+
provider = arguments.pop("provider", None)
614609

615-
list_catalog = catalogs.strip("/").split("/")
610+
list_catalog = catalogs.strip("/").split("/")
616611

617-
response = download_stac_item_by_id_stream(
618-
catalogs=list_catalog, item_id=item_id, provider=provider, **arguments
619-
)
612+
response = download_stac_item_by_id_stream(
613+
catalogs=list_catalog, item_id=item_id, provider=provider, **arguments
614+
)
620615

621-
timer.stop_global_timer()
622-
telemetry.record_request_duration(provider, timer.get_global_time())
623-
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
624-
telemetry.delete_overhead_timer(trace_id)
616+
timer.stop_global_timer()
617+
telemetry.record_request_duration(provider, timer.get_global_time())
618+
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
619+
telemetry.delete_overhead_timer(trace_id)
625620

626-
return response
621+
return response
627622

628623

629624
@router.get(
@@ -774,16 +769,14 @@ def stac_search(
774769
request: Request, search_body: Optional[SearchBody] = None
775770
) -> ORJSONResponse:
776771
"""STAC collections items"""
777-
tracer = trace.get_tracer("eodag.tracer")
778-
with tracer.start_as_current_span("server-search") as span:
779-
trace_id = span.get_span_context().trace_id
780-
timer = telemetry.create_overhead_timer(trace_id)
781-
timer.start_global_timer()
782-
logger.debug(f"URL: {request.url}")
783-
logger.debug(f"Body: {search_body}")
772+
trace_id = telemetry.get_current_trace_id()
773+
timer = telemetry.create_overhead_timer(trace_id)
774+
timer.start_global_timer()
775+
logger.debug(f"URL: {request.url}")
776+
logger.debug(f"Body: {search_body}")
784777

785-
url = request.state.url
786-
url_root = request.state.url_root
778+
url = request.state.url
779+
url_root = request.state.url_root
787780

788781
if search_body is None:
789782
body = {}
@@ -792,29 +785,29 @@ def stac_search(
792785
if body["sortby"] is not None:
793786
body["sortby"] = convert_sortby_to_get_format(body["sortby"])
794787

795-
arguments = dict(request.query_params, **body)
796-
provider = arguments.pop("provider", None)
788+
arguments = dict(request.query_params, **body)
789+
provider = arguments.pop("provider", None)
797790

798-
# metrics
799-
args_collections = arguments.get("collections", None)
800-
product_type = args_collections.split(",")[0] if args_collections else None
801-
telemetry.record_searched_product_type(product_type)
791+
# metrics
792+
args_collections = arguments.get("collections", None)
793+
product_type = args_collections.split(",")[0] if args_collections else None
794+
telemetry.record_searched_product_type(product_type)
802795

803-
response = search_stac_items(
804-
url=url,
805-
arguments=arguments,
806-
root=url_root,
807-
provider=provider,
808-
method=request.method,
809-
)
810-
resp = ORJSONResponse(
811-
content=response, status_code=200, media_type="application/json"
812-
)
813-
timer.stop_global_timer()
814-
telemetry.record_request_duration(provider, timer.get_global_time())
815-
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
816-
telemetry.delete_overhead_timer(trace_id)
817-
return resp
796+
response = search_stac_items(
797+
url=url,
798+
arguments=arguments,
799+
root=url_root,
800+
provider=provider,
801+
method=request.method,
802+
)
803+
resp = ORJSONResponse(
804+
content=response, status_code=200, media_type="application/json"
805+
)
806+
timer.stop_global_timer()
807+
telemetry.record_request_duration(provider, timer.get_global_time())
808+
telemetry.record_request_overhead_duration(provider, timer.get_overhead_time())
809+
telemetry.delete_overhead_timer(trace_id)
810+
return resp
818811

819812

820813
app.include_router(router)

eodag/rest/utils.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,10 +1342,6 @@ def telemetry_init(app: FastAPI):
13421342
13431343
:param app: FastAPI to automatically instrument.
13441344
:type app: FastAPI"""
1345-
1346-
if not os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"):
1347-
return None
1348-
13491345
telemetry.configure_instruments(eodag_api, app)
13501346

13511347

eodag/utils/otel.py

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from __future__ import annotations
1919

2020
import logging
21+
import os
22+
import sys
2123
from time import perf_counter
2224
from typing import TYPE_CHECKING, Dict, Iterable
2325

@@ -37,7 +39,7 @@
3739
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
3840
from opentelemetry.metrics import CallbackOptions, Instrument, Observation
3941
from opentelemetry.sdk.metrics import MeterProvider
40-
from opentelemetry.sdk.metrics._internal.export import PeriodicExportingMetricReader
42+
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
4143
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
4244
from opentelemetry.sdk.trace import TracerProvider
4345
from opentelemetry.sdk.trace.export import BatchSpanProcessor
@@ -100,7 +102,7 @@ def __init__(self):
100102
self._eodag_app: FastAPI = None
101103
self._instruments: Dict[str, Instrument] = {}
102104
self._overhead_timers: Dict[str, OverheadTimer] = {}
103-
self._instrumented: bool = False
105+
self._is_instrumented: bool = False
104106

105107
def configure_instruments(self, eodag_api: EODataAccessGateway, eodag_app: FastAPI):
106108
"""Configure the instrumentation.
@@ -110,6 +112,12 @@ def configure_instruments(self, eodag_api: EODataAccessGateway, eodag_app: FastA
110112
:param eodag_app: EODAG's app
111113
:type eodag_app: FastAPI
112114
"""
115+
116+
if not os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"):
117+
return None
118+
if "opentelemetry" not in sys.modules:
119+
return None
120+
113121
self._eodag_api = eodag_api
114122
self._eodag_app = eodag_app
115123
self._instruments.clear()
@@ -167,7 +175,7 @@ def configure_instruments(self, eodag_api: EODataAccessGateway, eodag_app: FastA
167175
unit="s",
168176
description="Measure the duration of the outbound HTTP request",
169177
)
170-
self._instrumented = True
178+
self._is_instrumented = True
171179

172180
def _available_providers_callback(
173181
self, options: CallbackOptions
@@ -212,7 +220,7 @@ def record_downloaded_data(self, provider: str, byte_count: int):
212220
:param byte_count: Number of bytes downloaded.
213221
:type byte_count: int
214222
"""
215-
if not self._instrumented:
223+
if not self._is_instrumented:
216224
return
217225

218226
self._instruments["downloaded_data_bytes_total"].add(
@@ -226,7 +234,7 @@ def record_searched_product_type(self, product_type: str):
226234
:param product_type: The product type.
227235
:type product_type: str
228236
"""
229-
if not self._instrumented:
237+
if not self._is_instrumented:
230238
return
231239

232240
self._instruments["searched_product_types_total"].add(
@@ -241,7 +249,7 @@ def record_request_duration(self, provider: str, time: float):
241249
:param time: Duration of the request.
242250
:type time: float
243251
"""
244-
if not self._instrumented:
252+
if not self._is_instrumented:
245253
return
246254

247255
attributes = {"provider": str(provider)}
@@ -255,7 +263,7 @@ def record_request_overhead_duration(self, provider: str, time: float):
255263
:param time: Duration of the overhead.
256264
:type time: float
257265
"""
258-
if not self._instrumented:
266+
if not self._is_instrumented:
259267
return
260268

261269
attributes = {"provider": str(provider)}
@@ -269,7 +277,7 @@ def record_outbound_request_duration(self, provider: str, time: float):
269277
:param time: Duration of the request.
270278
:type time: float
271279
"""
272-
if not self._instrumented:
280+
if not self._is_instrumented:
273281
return
274282

275283
attributes = {"provider": str(provider)}
@@ -286,8 +294,10 @@ def create_overhead_timer(self, timer_id: str) -> OverheadTimer:
286294
:returns: The new timer.
287295
:rtype: OverheadTimer
288296
"""
297+
if not self._is_instrumented:
298+
return OverheadTimer()
289299
timer = OverheadTimer()
290-
self._overhead_timers[timer_id] = OverheadTimer()
300+
self._overhead_timers[timer_id] = timer
291301
return timer
292302

293303
def delete_overhead_timer(self, timer_id: str):
@@ -296,6 +306,8 @@ def delete_overhead_timer(self, timer_id: str):
296306
:param timer_id: The ID of the timer to delete.
297307
:type timer_id: str
298308
"""
309+
if not self._is_instrumented:
310+
return None
299311
del self._overhead_timers[timer_id]
300312

301313
def get_overhead_timer(self, timer_id: str) -> OverheadTimer:
@@ -306,7 +318,19 @@ def get_overhead_timer(self, timer_id: str) -> OverheadTimer:
306318
:returns: The timer.
307319
:rtype: OverheadTimer
308320
"""
321+
if not self._is_instrumented:
322+
return OverheadTimer()
309323
return self._overhead_timers[timer_id]
310324

325+
def get_current_trace_id(self):
326+
"""Get the trace ID of the current span
327+
328+
:returns: The trace ID.
329+
:rtype: int
330+
"""
331+
if not self._is_instrumented:
332+
return None
333+
return trace.get_current_span().get_span_context().trace_id
334+
311335

312336
telemetry: Telemetry = Telemetry()

0 commit comments

Comments
 (0)