Skip to content

[FEATURE] Support GRPC OTLP exporter #689

@jkwening

Description

@jkwening

Problem Statement

Hi - I'm trying to configure Arize Phoenix as tracer_provider using the local phoenix serve CLI cmd but kept running into issues with it. Finally realized, unlike the docker container version, the local run version requires grpc protocol and doesn't allow http/protobuf protocol. Is it possible to support grpc protocol for the exporter?

I tried a bunch of configuration options including setting OTEL explicit variables but OTLP kept on trying to use the http endpoint:

# Force gRPC with explicit variables
    # os.environ["OTEL_TRACES_EXPORTER"] = "otlp"
    # os.environ["OTEL_EXPORTER_OTLP_PROTOCOL"] = "grpc"
    # os.environ["OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"] = "grpc"

and tracer provider config:

tracer_provider = register(
        project_name=project_name, protocol="grpc", auto_instrument=True, batch=True,
        endpoint="localhost:4317"
    )

    # Explicitly set protocol to gRPC
    StrandsTelemetry(tracer_provider=tracer_provider).setup_otlp_exporter().setup_meter(
        enable_otlp_exporter=True
    )

But not worked. It looks like no matter what you configure strands always uses http exporter: opentelemetry.exporter.otlp.proto.http.trace_exporter

Proposed Solution

Finally dug into the strands code and realized its because no matter what is configured only the http exporter is used:

from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

I implemented something as simple as this and that seemed to do the trick, adding protocol args to allow explicit configuration between http vs grpc protocol:

    def setup_otlp_exporter(self, protocol: str = "http/protobuf", **kwargs: Any) -> "StrandsTelemetry":
        """Set up OTLP exporter for the tracer provider.

        Args:
            **kwargs: Optional keyword arguments passed directly to
                OpenTelemetry's OTLPSpanExporter initializer.

        Returns:
            self: Enables method chaining.

        This method configures a BatchSpanProcessor with an OTLPSpanExporter,
        allowing trace data to be exported to an OTLP endpoint. Any additional
        keyword arguments provided will be forwarded to the OTLPSpanExporter.
        """
        if protocol == "grpc":
            from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
        else:
            from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

        try:
            otlp_exporter = OTLPSpanExporter(**kwargs)
            batch_processor = BatchSpanProcessor(otlp_exporter)
            self.tracer_provider.add_span_processor(batch_processor)
            logger.info("OTLP exporter configured")
        except Exception as e:
            logger.exception("error=<%s> | Failed to configure OTLP exporter", e)
        return self

I think this should do the trick but I'm new to OpenTelemetry so wanted to confirm. I can submit a PR for this but wanted to start discussion just in case there was more to this than that or if there was better solution via consuming tracer provider configuration and/or OTEL ENVs.

Use Case

Allow strands agents Telemetry to support more tracer providers that require grpc protocol. Currently, there is no way to configure between http/protobuf vs grpc when setting up OTLP exporter, no does it adhere to ENV variables or tracer provided configurations.

Alternatives Solutions

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions