Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.42

* **Support "none" value for OTEL_TRACES_EXPORTER and OTEL_METRICS_EXPORTER** - Filter "none" from exporter lists and return None when no exporters configured to properly disable OpenTelemetry instrumentation

## 0.0.39

* **Remove wrap_error logic as exceptions are categorized in unstructured-ingest**
Expand Down
68 changes: 68 additions & 0 deletions test/test_otel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from opentelemetry.environment_variables import OTEL_METRICS_EXPORTER, OTEL_TRACES_EXPORTER
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.trace import TracerProvider

from unstructured_platform_plugins.etl_uvicorn.otel import (
get_metric_provider,
get_settings,
get_trace_provider,
)


def test_get_settings_filters_none_from_traces(monkeypatch):
monkeypatch.setenv(OTEL_TRACES_EXPORTER, "none")
settings = get_settings()
assert settings["trace_exporters"] == []


def test_get_settings_filters_none_from_metrics(monkeypatch):
monkeypatch.setenv(OTEL_METRICS_EXPORTER, "none")
settings = get_settings()
assert settings["metric_exporters"] == []


def test_get_settings_filters_none_from_combined_trace_exporters(monkeypatch):
monkeypatch.setenv(OTEL_TRACES_EXPORTER, "none,console")
settings = get_settings()
assert settings["trace_exporters"] == ["console"]


def test_get_settings_filters_none_from_combined_metric_exporters(monkeypatch):
monkeypatch.setenv(OTEL_METRICS_EXPORTER, "none,console")
settings = get_settings()
assert settings["metric_exporters"] == ["console"]


def test_get_trace_provider_returns_none_when_exporter_is_none(monkeypatch):
monkeypatch.setenv(OTEL_TRACES_EXPORTER, "none")
assert get_trace_provider() is None


def test_get_metric_provider_returns_none_when_exporter_is_none(monkeypatch):
monkeypatch.setenv(OTEL_METRICS_EXPORTER, "none")
assert get_metric_provider() is None


def test_get_trace_provider_returns_provider_when_exporter_set(monkeypatch):
monkeypatch.setenv(OTEL_TRACES_EXPORTER, "console")
provider = get_trace_provider()
assert isinstance(provider, TracerProvider)


def test_get_metric_provider_returns_provider_when_exporter_set(monkeypatch):
monkeypatch.setenv(OTEL_METRICS_EXPORTER, "console")
provider = get_metric_provider()
assert isinstance(provider, MeterProvider)


def test_wrap_in_fastapi_does_not_crash_with_none_otel_exporters(monkeypatch):
"""Regression: previously crashed with NotImplementedError when none was set."""
monkeypatch.setenv(OTEL_TRACES_EXPORTER, "none")
monkeypatch.setenv(OTEL_METRICS_EXPORTER, "none")

from test.assets.async_typed_dict_response import async_sample_function
from unstructured_platform_plugins.etl_uvicorn.api_generator import wrap_in_fastapi

# Should not raise NotImplementedError
app = wrap_in_fastapi(func=async_sample_function, plugin_id="test_plugin")
assert app is not None
2 changes: 1 addition & 1 deletion unstructured_platform_plugins/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.41" # pragma: no cover
__version__ = "0.0.42" # pragma: no cover
12 changes: 10 additions & 2 deletions unstructured_platform_plugins/etl_uvicorn/otel.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,23 @@ def get_settings() -> OtelSettings:
service_name = os.environ.get(OTEL_SERVICE_NAME, "unknown_service")
trace_exporters = os.environ.get(OTEL_TRACES_EXPORTER)
trace_exporters = trace_exporters.split(",") if trace_exporters else []
trace_exporters = [e for e in trace_exporters if e != "none"]

metric_exporters = os.environ.get(OTEL_METRICS_EXPORTER)
metric_exporters = metric_exporters.split(",") if metric_exporters else []
metric_exporters = [e for e in metric_exporters if e != "none"]
return OtelSettings(
service_name=service_name,
trace_exporters=trace_exporters,
metric_exporters=metric_exporters,
)


def get_trace_provider() -> TracerProvider:
def get_trace_provider() -> TracerProvider | None:
settings = get_settings()
if not settings["trace_exporters"]:
return None

provider = TracerProvider(resource=Resource({SERVICE_NAME: settings["service_name"]}))

for trace_exporter_type in settings["trace_exporters"]:
Expand All @@ -50,8 +55,11 @@ def get_trace_provider() -> TracerProvider:
return provider


def get_metric_provider() -> MeterProvider:
def get_metric_provider() -> MeterProvider | None:
settings = get_settings()
if not settings["metric_exporters"]:
return None

readers = []
for metric_exporter_type in settings["metric_exporters"]:
readers.append(_get_metrics_reader(exporter_type=metric_exporter_type))
Expand Down