Skip to content

Conversation

@diegomarquezp
Copy link
Contributor

No description provided.

diegomarquezp and others added 30 commits January 8, 2026 13:37
…metryTracingRecorder.java

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
|
[com.google.cloud:grpc-gcp](https://togithub.com/GoogleCloudPlatform/grpc-gcp-java/tree/master/grpc-gcp)
([source](https://togithub.com/GoogleCloudPlatform/grpc-gcp-java)) |
patch | `1.9.0` -> `1.9.1` |
|
[com.google.errorprone:error_prone_annotations](https://errorprone.info)
([source](https://togithub.com/google/error-prone)) | minor | `2.45.0`
-> `2.46.0` |
|
[com.google.http-client:google-http-client](https://togithub.com/googleapis/google-http-java-client)
| patch | `2.0.2` -> `2.0.3` |
|
[com.google.protobuf:protobuf-java](https://developers.google.com/protocol-buffers/)
([source](https://togithub.com/protocolbuffers/protobuf)) | patch |
`4.33.1` -> `4.33.4` |
|
[commons-codec:commons-codec](https://commons.apache.org/proper/commons-codec/)
([source](https://togithub.com/apache/commons-codec)) | minor | `1.19.0`
-> `1.20.0` |
|
[io.opentelemetry:opentelemetry-bom](https://togithub.com/open-telemetry/opentelemetry-java)
| minor | `1.57.0` -> `1.58.0` |
|
[org.apache.httpcomponents.client5:httpclient5](https://hc.apache.org/)
| minor | `5.5.1` -> `5.6` |
| [org.apache.httpcomponents.core5:httpcore5](https://hc.apache.org/) |
minor | `5.3.6` -> `5.4` |

---

### Release Notes

<details>
<summary>GoogleCloudPlatform/grpc-gcp-java
(com.google.cloud:grpc-gcp)</summary>

###
[`v1.9.1`](https://togithub.com/GoogleCloudPlatform/grpc-gcp-java/releases/tag/v1.9.1)

[Compare
Source](https://togithub.com/GoogleCloudPlatform/grpc-gcp-java/compare/v1.9.0...v1.9.1)

#### What's Changed

- fix: race for metrics values. Plus fix log metrics when reported via
otel callbacks by [@&#8203;nimf](https://togithub.com/nimf) in
[https://github.com/GoogleCloudPlatform/grpc-gcp-java/pull/228](https://togithub.com/GoogleCloudPlatform/grpc-gcp-java/pull/228)

**Full Changelog**:
GoogleCloudPlatform/grpc-gcp-java@v1.9.0...v1.9.1

</details>

<details>
<summary>google/error-prone
(com.google.errorprone:error_prone_annotations)</summary>

###
[`v2.46.0`](https://togithub.com/google/error-prone/releases/tag/v2.46.0):
Error Prone 2.46.0

[Compare
Source](https://togithub.com/google/error-prone/compare/v2.45.0...v2.46.0)

Changes:

- The javac flag `-XDaddTypeAnnotationsToSymbol=true` is now required
for Error Prone invocations on JDK 21, to enable the javac fix for
[JDK-8225377: type annotations are not visible to javac plugins across
compilation boundaries](https://bugs.openjdk.org/browse/JDK-8225377).
See
[https://github.com/google/error-prone/issues/5426](https://togithub.com/google/error-prone/issues/5426)
for details.
- Remove deprecated `value` attribute from `@IncompatibleModifiers` and
`@RequiredModifiers`
([https://github.com/google/error-prone/issues/2122](https://togithub.com/google/error-prone/issues/2122))
- Error Prone API changes to encapsulate references to internal javac
APIs for end position handling (`EndPosTable`, `DiagnosticPosition`)
(google/error-prone@5440bb4,
google/error-prone@06c2905,
google/error-prone@f3915ec)

New checks:

-
[`DuplicateAssertion`](https://errorprone.info/bugpattern/DuplicateAssertion):
detect duplicated assertion lines where the argument to `assertThat` is
pure
-
[`IfChainToSwitch`](https://errorprone.info/bugpattern/IfChainToSwitch):
suggest converting chains of if-statements into arrow switches
-
[`ScannerUseDelimiter`](https://errorprone.info/bugpattern/ScannerUseDelimiter):
discourage `Scanner.useDelimiter("\\A")`
-
[`AddNullMarkedToClass`](https://errorprone.info/bugpattern/AddNullMarkedToClass):
refactoring to add `@NullMarked` annotation to top level classes

</details>

<details>
<summary>googleapis/google-http-java-client
(com.google.http-client:google-http-client)</summary>

###
[`v2.0.3`](https://togithub.com/googleapis/google-http-java-client/blob/HEAD/CHANGELOG.md#203-2025-12-19)

[Compare
Source](https://togithub.com/googleapis/google-http-java-client/compare/v2.0.2...v2.0.3)

##### Bug Fixes

- **apache5:** Set connection request timeout on setTimeout
([#&#8203;2129](https://togithub.com/googleapis/google-http-java-client/issues/2129))
([d11d794](https://togithub.com/googleapis/google-http-java-client/commit/d11d794d452a662bddd4402cd5d3895bcbe769f3))

</details>

<details>
<summary>apache/commons-codec (commons-codec:commons-codec)</summary>

###
[`v1.20.0`](https://togithub.com/apache/commons-codec/blob/HEAD/RELEASE-NOTES.txt#Apache-Commons-Codec-1200-Release-Notes)

The Apache Commons Codec team is pleased to announce the release of
Apache Commons Codec 1.20.0.

The Apache Commons Codec component contains encoders and decoders for
formats such as Base16, Base32, Base64, digest, and Hexadecimal. In
addition to these
widely used encoders and decoders, the codec package also maintains a
collection of phonetic encoding utilities.

This is a feature and maintenance release. Java 8 or later is required.

</details>



<details>
<summary>open-telemetry/opentelemetry-java
(io.opentelemetry:opentelemetry-bom)</summary>

###
[`v1.58.0`](https://togithub.com/open-telemetry/opentelemetry-java/blob/HEAD/CHANGELOG.md#Version-1580-2026-01-09)

[Compare
Source](https://togithub.com/open-telemetry/opentelemetry-java/compare/v1.57.0...v1.58.0)

##### API

##### Incubator

- Delete GlobalConfigProvider in favor of access via
ExtendedOpenTelemetry

([#&#8203;7914](https://togithub.com/open-telemetry/opentelemetry-java/pull/7914))
-   Add DeclarativeConfigProperties#get method

([#&#8203;7923](https://togithub.com/open-telemetry/opentelemetry-java/pull/7923))
- Update ConfigProvider#getInstrumentationConfig response to be non-null

([#&#8203;7954](https://togithub.com/open-telemetry/opentelemetry-java/pull/7954))
-   Add declarative config utility methods for common operations

([#&#8203;7927](https://togithub.com/open-telemetry/opentelemetry-java/pull/7927))

##### SDK

##### Traces

-   Implement SDK metrics for trace

([#&#8203;7895](https://togithub.com/open-telemetry/opentelemetry-java/pull/7895),

[#&#8203;7930](https://togithub.com/open-telemetry/opentelemetry-java/pull/7930))
-   Emit warning when TraceIdRatioBasedSampler is used as child sampler

([#&#8203;7937](https://togithub.com/open-telemetry/opentelemetry-java/pull/7937))

##### Logs

-   Implement SDK metrics for logs

([#&#8203;7931](https://togithub.com/open-telemetry/opentelemetry-java/pull/7931))

##### Exporters

-   Prom exporter update

([#&#8203;7934](https://togithub.com/open-telemetry/opentelemetry-java/pull/7934))

##### Extensions

-   Declarative config: update to opentelemetry-configuration 1.0.0-rc.3

([#&#8203;7861](https://togithub.com/open-telemetry/opentelemetry-java/pull/7861))
- Declarative config: update jaeger remote sampler to require endpoint,
initial_sampler

([#&#8203;7943](https://togithub.com/open-telemetry/opentelemetry-java/pull/7943))
-   Declarative config: add support for view unit

([#&#8203;7942](https://togithub.com/open-telemetry/opentelemetry-java/pull/7942))
- Declarative config: add support for new logger config minimum_severity
and trace_based properties

([#&#8203;7940](https://togithub.com/open-telemetry/opentelemetry-java/pull/7940))
- Declarative config: add support for composable parent threshold
sampler

([#&#8203;7941](https://togithub.com/open-telemetry/opentelemetry-java/pull/7941))
- Declarative config: improve pattern for validating and loading SDK
extension plugins

([#&#8203;7947](https://togithub.com/open-telemetry/opentelemetry-java/pull/7947))

##### Project tooling

-   Use develocity build cache in PRs and local builds

([#&#8203;7906](https://togithub.com/open-telemetry/opentelemetry-java/pull/7906))
-   Configure japicmp classpath to avoid false positives

([#&#8203;7945](https://togithub.com/open-telemetry/opentelemetry-java/pull/7945))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://togithub.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
chore: update googleapis commit at Wed Dec 10 02:37:02 UTC 2025
🤖 I have created a release *beep* *boop*
---


<details><summary>2.65.0</summary>

##
[2.65.0](v2.64.2...v2.65.0)
(2026-01-12)


### Features

* add org.json:json to third-party-dependencies pom
([#4047](#4047))
([ffa432e](ffa432e)),
closes
[#4046](#4046)
* remove dependency management of graal-sdk
([#4033](#4033))
([ad05c34](ad05c34))


### Bug Fixes

* add api_version breadcrumb to client docs
([#4018](#4018))
([a2b2179](a2b2179))
* Create a single S2AChannelCredentials per application
([#3989](#3989))
([3758b43](3758b43))
* provide API to share the same background executor for channel po…
([#4030](#4030))
([178182c](178182c))


### Dependencies

* update dependencies.txt for grpc-gcp to 1.9.0
([#4025](#4025))
([b68791d](b68791d))
* update google api dependencies
([#3917](#3917))
([480cf13](480cf13))
* update google.http-client.version to 2.0.3
([#4054](#4054))
([b9a8c89](b9a8c89))


### Documentation

* Fix retry guide link in javadocs
([#4029](#4029))
([b43f77c](b43f77c))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
[GoogleCredentialsProvider#setScopesToApply](https://github.com/googleapis/sdk-platform-java/blob/b9a8c8924e7b03bca8a97e476abfd012b86f6d45/gax-java/gax/src/main/java/com/google/api/gax/core/GoogleCredentialsProvider.java#L123)
would only work if the underlying credentials require the scopes to be
set. Update the docs to reflect the intended behavior.

Fixes #3738
🤖 I have created a release *beep* *boop*
---


<details><summary>2.65.1-SNAPSHOT</summary>

### Updating meta-information for bleeding-edge SNAPSHOT release.
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
@product-auto-label product-auto-label bot added the size: l Pull request size is large. label Jan 29, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @diegomarquezp, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request lays the groundwork for integrating OpenTelemetry tracing into the gax-java library. It establishes a robust framework for capturing and managing distributed traces for API operations, including individual retry attempts, thereby significantly enhancing the observability of client-side interactions. This initial implementation provides the necessary components to start instrumenting and monitoring the performance and behavior of API calls within a distributed environment.

Highlights

  • OpenTelemetry Integration: The core gax-java library now includes foundational support for OpenTelemetry, enabling distributed tracing for API calls.
  • New Tracing Abstractions: Introduced a TracingRecorder interface and its OpenTelemetryTracingRecorder implementation to manage the lifecycle of OpenTelemetry spans, including starting, ending, and recording errors.
  • Granular Span Management: The OpenTelemetryTracingTracer now creates distinct spans for the overall API operation and for each individual retry attempt, providing detailed visibility into the execution flow and potential retries.
  • Configurable Trace Attributes: The ApiTracerFactory has been extended with a withAttributes method, allowing custom attributes to be added to traces at both the operation and attempt levels for enhanced context.
  • Comprehensive Testing: New unit tests for OpenTelemetryTracingRecorder, OpenTelemetryTracingTracer, and OpenTelemetryTracingTracerFactory, along with an integration test in java-showcase, ensure the correct functionality and integration of the tracing implementation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

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

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 a proof-of-concept for OpenTelemetry-based tracing in gax-java. The changes include new interfaces for tracing (TracingRecorder, SpanHandle), OpenTelemetry implementations for these interfaces, and integration into the client lifecycle via a new ApiTracerFactory. The overall approach is sound and lays a good foundation.

My review includes a few key points:

  • A high-level design suggestion to make the attribute system more flexible by not limiting it to string values. This is crucial for capturing rich, typed trace data.
  • A refactoring suggestion to reduce code duplication in the new tracer implementation.
  • Several improvements for the integration tests to make them more robust and to address commented-out code that indicates potential issues.

The changes are a good start for this feature.

Comment on lines +47 to +68
SpanHandle startSpan(String name, Map<String, String> attributes);

/** Starts a span with a parent and returns a handle to manage its lifecycle. */
default SpanHandle startSpan(String name, Map<String, String> attributes, SpanHandle parent) {
return startSpan(name, attributes);
}

/**
* Installs the span into the current thread-local context.
*
* @return a scope that must be closed to remove the span from the context.
*/
default ApiTracer.Scope inScope(SpanHandle handle) {
return () -> {};
}

interface SpanHandle {
void end();

void recordError(Throwable error);

void setAttribute(String key, String value);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The use of String for attribute values throughout this new tracing API (in startSpan and SpanHandle.setAttribute) is overly restrictive. Tracing attributes are often numeric or boolean, and converting them to strings loses important type information, hindering analysis in tracing backends (e.g., attemptNumber should be an integer).

To make this API more powerful and aligned with OpenTelemetry, I recommend changing attribute values from String to a more flexible type. Some options:

  1. Use io.opentelemetry.api.common.Attributes: This is the most idiomatic OTel approach.
  2. Use Map<String, Object>: A more generic approach if you want to avoid a hard dependency on the OTel Attributes class in the interface.
  3. Overload setAttribute: For SpanHandle, you could add overloads for common types (long, double, boolean).

This change would need to be propagated through ApiTracerFactory, TracingRecorder, and OpenTelemetryTracingTracer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is true and a pending task: Otel SemConv specifies other types such as int

Comment on lines +90 to +111
public void attemptFailedDuration(Throwable error, java.time.Duration delay) {
if (attemptHandle != null) {
attemptHandle.recordError(error);
}
endAttempt();
}

@Override
public void attemptFailedRetriesExhausted(Throwable error) {
if (attemptHandle != null) {
attemptHandle.recordError(error);
}
endAttempt();
}

@Override
public void attemptPermanentFailure(Throwable error) {
if (attemptHandle != null) {
attemptHandle.recordError(error);
}
endAttempt();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The methods attemptFailedDuration, attemptFailedRetriesExhausted, and attemptPermanentFailure contain identical logic for recording an error on the attempt span and ending it. This duplication can be removed by extracting the logic into a private helper method.

For example:

private void failAttempt(Throwable error) {
  if (attemptHandle != null) {
    attemptHandle.recordError(error);
  }
  endAttempt();
}

Then, each of the attemptFailed... methods can simply call failAttempt(error).

  @Override
  public void attemptFailedDuration(Throwable error, java.time.Duration delay) {
    failAttempt(error);
  }

  @Override
  public void attemptFailedRetriesExhausted(Throwable error) {
    failAttempt(error);
  }

  @Override
  public void attemptPermanentFailure(Throwable error) {
    failAttempt(error);
  }

  private void failAttempt(Throwable error) {
    if (attemptHandle != null) {
      attemptHandle.recordError(error);
    }
    endAttempt();
  }

Comment on lines 95 to 102
// Verify operation span (low-cardinality)
// SpanData operationSpan =
// spans.stream()
// .filter(span -> span.getName().equals("Echo.Echo/operation"))
// .findFirst()
// .orElseThrow(() -> new AssertionError("Operation span 'Echo.Echo/operation'
// not found"));
// assertThat(operationSpan.getStatus().getStatusCode()).isEqualTo(StatusCode.OK);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This block of code for verifying the operation span is commented out, which suggests it might not be working as expected. As this is a work-in-progress, it's understandable, but commented-out tests should be avoided in the final version. Could you please either fix the underlying issue so these assertions can be enabled, or remove the commented-out code if it's no longer relevant?


List<SpanData> spans = spanExporter.getFinishedSpanItems();
assertThat(spans).isNotEmpty();
assertThat(spans.size() == 10); // 10 retires
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This assertion is not using the Truth API idiomatically and is brittle.

  1. The expression spans.size() == 10 evaluates to a boolean. You are essentially doing assertThat(true). The idiomatic way is assertThat(spans).hasSize(10);.
  2. Asserting a hardcoded number of retries makes the test fragile to changes in retry configuration.

Since you already verify that spans are not empty and all have an error status, consider if this exact size check is necessary. If so, please update to the idiomatic Truth syntax and fix the typo in 'retires'.

Suggested change
assertThat(spans.size() == 10); // 10 retires
assertThat(spans).hasSize(10); // 10 retries

Comment on lines 164 to 171
// SpanData operationSpan =
// spans.stream()
// .filter(span -> span.getName().equals("Echo.Echo/operation"))
// .findFirst()
// .orElseThrow(() -> new AssertionError("Operation span 'Echo.Echo/operation'
// not found"));
// assertThat(operationSpan.getAttributes().get(AttributeKey.stringKey("op-key")))
// .isEqualTo("op-value");
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the other test, the verification for the operation span is commented out. Please either fix the functionality to allow this to be tested or remove the commented code before merging.

@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: l Pull request size is large. labels Jan 29, 2026
ApiTracerFactory tracerFactory = settings.getTracerFactory();
if (tracerFactory != null) {
String rpcSystem = "";
if ("grpc".equals(transportChannel.getTransportName())) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This logic would likely be better in the tracer factory constructor.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed for 'gapic-generator-java-root'

Failed conditions
73.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@sonarqubecloud
Copy link

Quality Gate Passed Quality Gate passed for 'java_showcase_integration_tests'

Issues
6 New issues
0 Accepted issues

Measures
0 Security Hotspots
82.5% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: xl Pull request size is extra large.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants