Skip to content

feat(api_core): implement L2/L3 method error logging and L4 transport attempt logging - #19000

Draft
chalmerlowe wants to merge 4 commits into
feat/otel-logging-m2-buildersfrom
feat/otel-logging-m3-core
Draft

chalmerlowe wants to merge 4 commits into
feat/otel-logging-m2-buildersfrom
feat/otel-logging-m3-core

Conversation

@chalmerlowe

Copy link
Copy Markdown
Contributor

Summary

Implements OpenTelemetry-correlated Production Error Logging (PEL) across GAPIC method calls (Tier 3 / L3) and underlying gRPC and HTTP transport wire attempts (Tier 4 / L4) in google-api-core:

  • Feature Gating (client_logging.is_error_logging_enabled): Gates Production Error Logging via GOOGLE_SDK_EXPERIMENTAL_PYTHON_LOGGING_ENABLED and client_options.logger_provider, keeping it distinct from Application Payload Debug Logging (GOOGLE_SDK_PYTHON_LOGGING_SCOPE).
  • Tier 3 Method-Layer Error & Cancellation Telemetry (gapic_v1/method.py): Enriches active Tier 3 spans with structured error attributes and emits a single terminal ERROR log record on RPC failure (or a DEBUG log record without traceback on cancellation) across sync and async calls.
  • Tier 4 Transport-Attempt Debug Logging (_observability.py): Emits DEBUG log records for failed/retried gRPC and HTTP wire attempts (log_transport_attempt, _GrpcAttemptLoggingInterceptor, _AsyncGrpcAttemptLoggingInterceptor, and _TraceContext) while remaining a zero-allocation no-op on successful 2xx / OK attempts.

Stacked on #18893.

@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 introduces OpenTelemetry-correlated Production Error Logging (PEL) for both gRPC and HTTP transports across synchronous and asynchronous clients, including new interceptors, feature gating, and terminal RPC error logging. The review feedback highlights three critical issues in _observability.py that could compromise the library's fail-open design: first, calling response.exception() on a cancelled gRPC future in the synchronous interceptor may raise an unhandled CancelledError and crash the application; second, converting grpc.StatusCode enums directly to strings using str() yields incorrect status names (e.g., 'StatusCode.OK'), breaking failure detection; and third, executing post-dispatch logging inside the exception-capturing context manager in the asynchronous interceptor could allow logging failures to disrupt the main RPC flow.



def _extract_rpc_identity(
method_name: str,

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.

Note

To the reviewer: this has been moved to _observability.py

This branch has not been deployed

No deployments
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.

1 participant