Skip to content

Add GCP Cloud Run OpenTelemetry support - #1767

Open
seanbollin wants to merge 6 commits into
mainfrom
gcp-cloud-run-otel
Open

Add GCP Cloud Run OpenTelemetry support#1767
seanbollin wants to merge 6 commits into
mainfrom
gcp-cloud-run-otel

Conversation

@seanbollin

@seanbollin seanbollin commented Aug 19, 2026

Copy link
Copy Markdown

Summary

Screenshot 2026-08-21 at 11 19 42 AM

Adds GCP Cloud Run serverless-worker OpenTelemetry support, mirroring the approved .NET SDK common-core refactor (temporalio/sdk-dotnet#844) and building on the earlier draft #1658.

  • New package temporalio.contrib.gcp.cloud_run — an OpenTelemetryPlugin that exports Core metrics and tracing spans over OTLP/gRPC to a local OpenTelemetry Collector sidecar. Cloud Run specifics only (service name from CLOUD_RUN_WORKER_POOL/K_SERVICE, 60s metric periodicity). Gated behind a new cloud-run-worker-otel extra; no google-cloud-* libraries — the collector does GCP resource detection, auth, and export.
  • New private temporalio/contrib/opentelemetry/_serverless.py — shared, provider-neutral helpers (endpoint/service-name resolution, Core-metrics telemetry config, a lazy OTLP span-processor factory). It is not re-exported, so importing temporalio.contrib.opentelemetry gains no exporter import.
  • Refactor the AWS Lambda lambda_worker/otel.py onto _serverless, with no public API or behavior change.

Credit

Builds directly on @eamsden's draft #1658. Ported from that PR:

  • The Cloud Run OpenTelemetryPlugin subclass — connect_service_client runtime injection, force_flush / shutdown / flush_on_worker_stop, add_temporal_spans — its unit tests, and the README.
  • The optional-dependency extra and the env-var precedence + 60s default + no-batch design.

New in this PR, on top of @eamsden's work: the shared private _serverless.py extraction, the refactor of aws/lambda_worker/otel.py onto it, the temporalio.contrib.gcp.cloud_run sub-package placement, and the cloud-run-worker-otel extra naming + OTel version-floor alignment.

Non-breaking

The base opentelemetry extra is unchanged, and importing temporalio.contrib.opentelemetry pulls in zero exporter modules (the exporter import is lazy, inside build_otlp_span_processor). The AWS Lambda otel.py public signatures/behavior are unchanged — its existing tests pass unmodified (the non-breakage gate). Non-Lambda / non-Cloud-Run users are unaffected.

Verification

pytest tests/contrib/opentelemetry/test_serverless.py tests/contrib/gcp tests/contrib/aws/lambda_worker/test_otel.py — 48 pass (incl. the AWS file unmodified). Isolation proof verified empirically; ruff / pyright / basedpyright / mypy clean.

uv.lock is updated with the minimal change for the new extra — its three packages were already locked via lambda-worker-otel, so there are no new packages or version bumps. revision = 3 and the exclude-newer window are preserved.

Related

Companion sample: temporalio/samples-python (Cloud Run worker). Cross-SDK effort with sdk-go, sdk-java, and .NET (temporalio/sdk-dotnet#844).

🤖 Generated with Claude Code

Adds a Cloud Run serverless-worker OpenTelemetry integration, mirroring the
approved .NET SDK common-core refactor (temporalio/sdk-dotnet#844) and building
on #1658.

- New package temporalio.contrib.gcp.cloud_run: an OpenTelemetryPlugin that
  exports Core metrics and tracing spans over OTLP/gRPC to a local OpenTelemetry
  Collector sidecar. Cloud Run specifics only (service name from
  CLOUD_RUN_WORKER_POOL/K_SERVICE, 60s metric periodicity); gated behind a new
  cloud-run-worker-otel extra, no google-cloud client libraries.
- New private temporalio/contrib/opentelemetry/_serverless.py: shared,
  provider-neutral helpers (endpoint/service-name resolution, Core-metrics
  telemetry config, lazy OTLP span-processor factory). It is not re-exported, so
  importing temporalio.contrib.opentelemetry gains no exporter import.
- Refactor the AWS Lambda lambda_worker/otel.py onto _serverless with no public
  API or behavior change (existing tests unmodified).

Co-authored-by: Edward Amsden <edward.amsden@temporal.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Aug 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

seanbollin and others added 3 commits August 19, 2026 15:35
Records the new optional-dependency extra in the lockfile. The extra reuses
packages already locked via lambda-worker-otel, so there are no new package or
version changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The lazy OTLPSpanExporter import in _serverless.build_otlp_span_processor
tripped basedpyright reportMissingTypeStubs under the test-latest-deps job
(whose newer exporter build ships no type stubs). Matches the existing
suppression pattern in contrib/aws/lambda_worker/otel.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin
seanbollin marked this pull request as ready for review August 20, 2026 19:15
@seanbollin
seanbollin requested a review from a team as a code owner August 20, 2026 19:15
seanbollin and others added 2 commits August 20, 2026 13:06
The extra required opentelemetry-exporter-otlp-proto-grpc>=1.11.1 without a
companion constraint pinning a modern OpenTelemetry stack (unlike
lambda-worker-otel, whose opentelemetry-sdk-extension-aws>=2.0.0 transitively
caps protobuf<7). That let uv lock --upgrade downgrade the exporter to 1.11.1
and pull the just-released protobuf 7.35.1, whose runtime is incompatible with
the old generated protobuf code (test-latest-deps failures). Raising the floor
to >=1.26 (matching the api/sdk floors in this extra) removes the ancient
version from the resolution; uv lock --upgrade now holds at protobuf 6.33.6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Raising the exporter floor to >=1.26 (previous commit) fixed test-latest-deps
but broke check-protos: that job forces protobuf<4 and runs uv sync
--all-extras, and a >=1.26 exporter requires protobuf>=4, so uv could not
resolve. Restore the low >=1.11.1 floor (matching lambda-worker-otel) so the
exporter can downgrade to a protobuf-3-compatible build under protobuf<4, and
add an explicit protobuf<7 cap so uv lock --upgrade (test-latest-deps) cannot
downgrade the exporter to pull the incompatible protobuf 7.x. Satisfies both
jobs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants