feat(observability): [WIP] implement universal 4-path OpenTelemetry tracing - #18433
Draft
chalmerlowe wants to merge 95 commits into
Draft
chalmerlowe wants to merge 95 commits into
chalmerlowe wants to merge 95 commits into
Conversation
… 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
…ments without grpc
…parsing, and attribute handling
…nv version in response hook
…and fix mypy comment
- Broaden transport check in client.py.j2 to allow gRPC transport subclasses. - Align version comments in client.py.j2 and grpc.py.j2 to 2.36.0+. - Synchronize all golden client and transport files with template updates. - Harden zero-overhead and custom tracer provider isolation assertions in test_tracing.py. - Add direct client initialization test to verify template injection end-to-end.
…port template - Place ClientInterceptor import under if TYPE_CHECKING: in grpc.py.j2 to eliminate runtime import overhead and avoid import failures on older google-api-core versions. - String-quote "ClientInterceptor" in the interceptors type annotation for GrpcTransport.__init__. - Regenerate and synchronize all golden gRPC transport files.
Align if TYPE_CHECKING: in golden gRPC transport files with # pragma: NO COVER to match grpc.py.j2 template output.
…t_options to wrapped methods
… branch - Drop # pragma: NO COVER annotations from lines 181-183 in base.py.j2. - Remove outdated comment since unit tests explicitly exercise this fallback.
…thod and _wrap_async_method
…d prep_wrapped_messages
… format for Google Sheets
…tegration goldens
…o-1 canonical Python values
…r showcase testing
…on using nullcontext
…compliance test suite
…o restore 100% coverage
…d symbol patching - Parametrize client options and channel injection tests in gapic-generator template and test_method_async - Replace string-based module patching with refactor-safe symbol patching - Add boundary tests for client options and fail-open mutation test for telemetry initialization - Regenerate Bazel integration goldens to match updated unit test template - Safeguard trace_http_request context manager exit when initialization fails open
…oud-python into feat/otel-tracing-universal-4path
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(observability): implement universal 4-path OpenTelemetry tracing
Problems Solved
Google Cloud Python client libraries support four communication paths: synchronous gRPC, asynchronous gRPC, synchronous REST (HTTP), and asynchronous REST (HTTP). Previously, distributed OpenTelemetry tracing was only wired for synchronous gRPC calls, leaving asynchronous and HTTP communications untraced. Additionally, earlier drafts of asynchronous tracing attempted to modify gRPC channels after creation, which violated the immutability rules of the underlying Python gRPC library, and did not consistently forward client options across all transport classes.
Solutions
This pull request provides a unified, cross-transport tracing implementation:
Universal 4-Transport Support:
GrpcTransport): Continues using OpenTelemetry gRPC channel interceptors.GrpcAsyncIOTransport): Supplies OpenTelemetry interceptors directly during channel creation, respecting the immutable design of asynchronous gRPC channels.RestTransport): Adds wire span tracking around HTTP requests with automatic W3C trace context header injection (traceparent).AsyncRestTransport): Integrates HTTP wire span tracking and async context lifecycle handling with W3C header propagation.Refined Transport Contracts & Cleanup:
BaseTransport.kindto safely return an empty string by default instead of raising an exception.asyncio.CancelledError) so spans are closed accurately when asynchronous tasks are cancelled.Notes for Reviewers
packages/gapic-generatorand core helper functions inpackages/google-api-core.