Skip to content

feat(gapic): add OpenTelemetry channel tracing to generator templates - #18342

Draft
chalmerlowe wants to merge 68 commits into
feat/otel-tracing-t4-resource-attributesfrom
feat/otel-tracing-gapic-showcase
Draft

feat(gapic): add OpenTelemetry channel tracing to generator templates#18342
chalmerlowe wants to merge 68 commits into
feat/otel-tracing-t4-resource-attributesfrom
feat/otel-tracing-gapic-showcase

Conversation

@chalmerlowe

@chalmerlowe chalmerlowe commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Problem

Generated client libraries currently lack OpenTelemetry tracing interceptor support for gRPC channels. When OpenTelemetry is configured in client options, generated clients cannot automatically create and pass interceptors down to their transport and gRPC channel.

Solution

Updates the code in the following ways:

  • Imports the centralized ClientInterceptor in the gRPC transport template and updates the transport initializer signature and docstrings to accept channel interceptors.
  • Updates the client template to look up OpenTelemetry interceptors via google.api_core._observability and pass them into the gRPC transport arguments.
  • Adds mock unit tests to the generated unit test templates to verify interceptor injection and transport application.

Notes for Reviewers

  • This pull request is currently work in progress (WIP) and is opened as a draft while end-to-end integration tests are being developed.
  • The changes here are based on the feat/otel-tracing-t4-resource-attributes branch which introduces the required core observability helpers.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request adds OpenTelemetry tracing capabilities (Tier 3 observability) for gRPC channels in the GAPIC generator and google-api-core. It integrates client-side span creation and attribute extraction for non-streaming gRPC calls. The review feedback highlights two important improvements: handling potential ValueError exceptions gracefully when parsing malformed ports from api_endpoint in _observability.py, and supporting client_options when passed as a dictionary when resolving the custom tracer_provider in method.py.

Comment thread packages/google-api-core/google/api_core/_observability.py Outdated
Comment thread packages/google-api-core/google/api_core/gapic_v1/method.py Outdated
@chalmerlowe
chalmerlowe added this pull request to stack #18275 September 11, 2026 11:18
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-t4-resource-attributes branch from 5f64897 to daeed98 Compare September 11, 2026 11:20
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-gapic-showcase branch from 84d77b0 to cdd5eb8 Compare September 11, 2026 11:23
@chalmerlowe chalmerlowe changed the title [WIP] feat(gapic): add OpenTelemetry channel tracing to generator templates feat(gapic): add OpenTelemetry channel tracing to generator templates Sep 11, 2026
# Note: ClientInterceptor was added in google-api-core 2.25.0+; fallback for older versions
try:
from google.api_core.grpc_helpers import ClientInterceptor # type: ignore[attr-defined]
except ImportError: # pragma: NO COVER

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added do-not-merge

Until the most recent version of google-api-core is published to PyPI, the ClientInterceptor object is unavailable. While working on this PR, this is a temporary workaround to enable testing, etc. Will be removed before merge.

@chalmerlowe chalmerlowe self-assigned this Sep 11, 2026
@chalmerlowe chalmerlowe added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Sep 11, 2026
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-t4-resource-attributes branch from daeed98 to c68dab6 Compare September 11, 2026 12:07
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-gapic-showcase branch 3 times, most recently from c6a30e5 to 52176ce Compare September 11, 2026 14:18
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-t4-resource-attributes branch from 8775743 to d6307d6 Compare September 11, 2026 14:18
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-gapic-showcase branch from 52176ce to 59ae00b Compare September 11, 2026 14:19
@chalmerlowe

Copy link
Copy Markdown
Contributor Author

We have not yet re-generated the Goldens, thus these are both failing:

  • Gapic Generator Specialized Tests / integration
  • Gapic Generator Specialized Tests / status (roll-up of all test status)

The goldens are forth coming.

@chalmerlowe
chalmerlowe marked this pull request as ready for review September 11, 2026 16:17
@chalmerlowe
chalmerlowe requested a review from a team as a code owner September 11, 2026 16:17
@chalmerlowe
chalmerlowe marked this pull request as draft September 11, 2026 16:17
… application

- Use _observability.create_channel_with_otel in SecretManagerServiceClient

- Use grpc_helpers.apply_interceptors in SecretManagerServiceGrpcTransport

- Add unit tests for channel injection and interceptor wiring
…ing enabled

- Use functools.partial to bind create_channel_with_otel with Transport.create_channel and client_options

- Eliminate manual extraction of host, credentials, scopes, and quota_project_id in client

- Update unit tests to verify functools.partial factory binding and lazy transport kwargs
- Use functools.partial for _start_span_fn, eliminating redundant instance attributes on _GapicCallable
- Let OpenTelemetry context manager automatically record escaping exceptions to prevent duplicates
- Streamline _extract_status_code with parallel docstrings/comments and unify _extract_error_attributes
- Remove unnecessary runtime type checks on strictly typed method_name
- Defer async method tracing to follow-up PR, restoring method_async.py to main
Simplify domain, reason, and metadata checks in _extract_error_attributes by relying on standard truthiness checks.
Remove obsolete _BASE_SPAN_ATTRIBUTES alias and reuse _DEFAULT_SPAN_ATTRIBUTES
across custom client options and no-service method tests.
… hook

- Add rpc.system.name: 'grpc'
- Extract server.address and server.port from client options endpoint
- Extract gcp.grpc.resend_count from request resend count
- Extract gcp.resource.destination.id from request name or parent
- Add _client_response_hook for status code, error.type, and status.message
- Plumb response_hook into get_otel_interceptor and get_otel_async_interceptor
- Test endpoint attribute parsing across host/port variations
- Test destination id and resend count extraction
- Test client request and response hooks covering all status and error cases
- Test interceptor creation and custom endpoint attribute propagation
- Achieve 100% statement and branch coverage on _observability.py
…and hooks

- Rename _extract_t4_attributes to _extract_grpc_request_attributes
- Rename _make_client_request_hook to _make_grpc_client_request_hook
- Rename _client_request_hook to _grpc_client_request_hook
- Rename _client_response_hook to _grpc_client_response_hook
- Preserve generic _extract_endpoint_attributes for shared transport usage
…ntion

- Rename test_extract_t4_attributes to test_extract_grpc_request_attributes
- Rename test_client_request_hook to test_grpc_client_request_hook
- Rename test_client_response_hook to test_grpc_client_response_hook
- Update interceptor hook references to _grpc_client_* hooks
- Add url.domain extraction from universe_domain or default to googleapis.com
- Add _extract_error_attributes helper to extract gcp.errors.domain and gcp.errors.metadata.<key>
- Omit server.port when port matches scheme defaults (443 for https/grpc, 80 for http)
- Remove redundant _grpc_client_response_hook and _STATUS_CODE_NAMES
- Deduplicate name and parent resource lookup for gcp.resource.destination.id
- Add comprehensive parametrized unit tests and update interceptor test suites
…tem attribute

- Strip leading slash from gRPC attempt span names via span.update_name
- Set rpc.method to the fully qualified method name per PRD specification
- Retain rpc.system.name: 'grpc' and remove legacy rpc.system attribute to avoid duplication
- Update unit tests to verify span name normalization and attribute deduplication
- Remove gcp.resource.destination.id extraction from _extract_grpc_request_attributes
- Update unit tests to reflect attribute removal per July Strategy Update
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-t4-resource-attributes branch from d6307d6 to b3931e9 Compare September 11, 2026 18:41
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-gapic-showcase branch from 86b7b10 to 72ad56d Compare September 11, 2026 18:41
@chalmerlowe
chalmerlowe removed this pull request from stack #18275 September 11, 2026 22:17
@chalmerlowe
chalmerlowe force-pushed the feat/otel-tracing-t4-resource-attributes branch from b3931e9 to 99a4d3d Compare September 11, 2026 23:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Indicates a pull request not ready for merge, due to either quality or timing.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant