diff --git a/src/phoenix/server/telemetry.py b/src/phoenix/server/telemetry.py index be464d4348..5465801fb1 100644 --- a/src/phoenix/server/telemetry.py +++ b/src/phoenix/server/telemetry.py @@ -1,16 +1,42 @@ import os from typing import TYPE_CHECKING -if TYPE_CHECKING: - from opentelemetry.trace import TracerProvider - from phoenix.config import ( ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT, ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_HTTP_ENDPOINT, ) +if TYPE_CHECKING: + from opentelemetry.trace import TracerProvider +from logging import getLogger + +logger = getLogger(__name__) + + +def normalize_http_collector_endpoint(endpoint: str) -> str: + normalized_endpoint = endpoint + if not normalized_endpoint.startswith("http://") and not normalized_endpoint.startswith( + "https://" + ): + logger.warning( + "HTTP collector endpoint should include the protocol (http:// or https://)." + "Assuming http." + ) + # assume http if no protocol is provided + normalized_endpoint = f"http://{endpoint}" + if normalized_endpoint.endswith("/v1/traces"): + logger.warning( + "HTTP collector endpoint should not include the /v1/traces path. Removing it." + ) + # remove the /v1/traces path + normalized_endpoint = normalized_endpoint[: -len("/v1/traces")] + # remove trailing slashes + normalized_endpoint = normalized_endpoint.rstrip("/") + return normalized_endpoint + def initialize_opentelemetry_tracer_provider() -> "TracerProvider": + logger.info("Initializing OpenTelemetry tracer provider") from opentelemetry.sdk import trace as trace_sdk from opentelemetry.sdk.trace.export import BatchSpanProcessor @@ -18,6 +44,8 @@ def initialize_opentelemetry_tracer_provider() -> "TracerProvider": if http_endpoint := os.getenv( ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_HTTP_ENDPOINT ): + logger.info(f"Using HTTP collector endpoint: {http_endpoint}") + http_endpoint = normalize_http_collector_endpoint(http_endpoint) + "/v1/traces" from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( OTLPSpanExporter as HttpExporter, ) @@ -26,9 +54,11 @@ def initialize_opentelemetry_tracer_provider() -> "TracerProvider": if grpc_endpoint := os.getenv( ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT ): + logger.info(f"Using gRPC collector endpoint: {grpc_endpoint}") from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( OTLPSpanExporter as GrpcExporter, ) tracer_provider.add_span_processor(BatchSpanProcessor(GrpcExporter(grpc_endpoint))) + logger.info("🔭 OpenTelemetry tracer provider initialized") return tracer_provider diff --git a/tests/server/test_telemetry.py b/tests/server/test_telemetry.py new file mode 100644 index 0000000000..8109cb8008 --- /dev/null +++ b/tests/server/test_telemetry.py @@ -0,0 +1,16 @@ +from phoenix.server.telemetry import normalize_http_collector_endpoint + + +def test_normalize_http_collector_endpoint(): + assert normalize_http_collector_endpoint("http://localhost:4317") == "http://localhost:4317" + assert normalize_http_collector_endpoint("https://localhost:4317") == "https://localhost:4317" + assert normalize_http_collector_endpoint("localhost:4317") == "http://localhost:4317" + assert ( + normalize_http_collector_endpoint("http://localhost:4317/v1/traces") + == "http://localhost:4317" + ) + assert ( + normalize_http_collector_endpoint("https://localhost:4317/v1/traces") + == "https://localhost:4317" + ) + assert normalize_http_collector_endpoint("localhost:4317/v1/traces") == "http://localhost:4317"