Skip to content

distro: don't require grpc to be importable - #666

Merged
xrmx merged 2 commits into
elastic:mainfrom
samuelhnrq:distro-optional-grpc
Oct 26, 2026
Merged

xrmx merged 2 commits into
elastic:mainfrom
samuelhnrq:distro-optional-grpc

Conversation

@samuelhnrq

@samuelhnrq samuelhnrq commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

What does this pull request do?

Makes the distro work when grpc is unavailable (e.g. missing / mismatched binary extension), so configuring with http/protobuf still works.

With operator auto-instrumentation, the injected image ships cp312 grpcio. On a Python >3.13 app, grpc._cython.cygrpc fails to import, so elasticotel.distro failed at module load. Even though operator would export over http/protobuf anyway.

  • The grpc exporter imports are wrapped in try/except ImportError.
  • The grpc channel_options user agent is only added to exporter_args_map when grpc is available. The HTTP exporters still get the EDOT user agent.
  • Adds a unit test that makes grpc unimportable, reloads the distro, and checks that the SDK is configured with HTTP exporter args only.

The change is based on @xrmx's diff in #653. Checked against 1.18.0 plus a pure-Python uuid7 shim on Python 3.13 (amd64 and arm64): the tracer provider is configured and grpc is never imported.

Related issues

Full independence from binary extensions still depends on uuid_utils, pending open-telemetry/opentelemetry-python-contrib#5207

The operator image ships cp312 grpcio, so on Python 3.13 apps importing
grpc fails and the distro failed at module load, even though the operator
exports via http/protobuf. Make the grpc exporter imports optional and
only set the grpc user agent channel option when grpc is available.

Refs elastic#653
@samuelhnrq
samuelhnrq requested a review from a team as a code owner October 23, 2026 11:55
Comment thread src/elasticotel/distro/__init__.py Outdated
Comment thread src/elasticotel/distro/__init__.py Outdated
@xrmx
xrmx requested a balanced review from Copilot October 23, 2026 12:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fallback preserves existing exporter behavior and includes regression coverage for configuration without gRPC.

No open issues 🎉

What changed in this PR

Allows the distro to configure HTTP/protobuf exporters when gRPC cannot be imported, addressing the gRPC-related operator injection failure on mismatched Python versions. The separate uuid_utils dependency remains outside this PR’s scope.

Changes:

  • Guards gRPC exporter imports and adds gRPC user-agent options only when those imports succeed.
  • Adds a regression test verifying HTTP-only SDK configuration and EDOT user-agent headers when gRPC is unavailable.
File Description
tests/​distro/​test_distro.py Tests HTTP-only configuration with gRPC imports blocked.
src/​elasticotel/​distro/​__init__.py Makes gRPC imports and exporter options conditional.

Review effort: Balanced

Comment thread src/elasticotel/distro/__init__.py Outdated
Doing the optional grpc import in _configure with try/except/else lets
pyright see the exporters are bound where they are used, so we don't
need a None sentinel for _USER_AGENT_HEADER_VALUE or type: ignore
comments. Annotate exporter_args_map so the grpc entries can be added.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The functional fix and regression coverage are complete; the remaining release-note update is a non-blocking nit.

No open issues 🎉

Review effort: Lite

@xrmx
xrmx merged commit f8c26db into elastic:main Oct 26, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants