Skip to content

feat(o11y): introduce server.port attribute#4128

Open
diegomarquezp wants to merge 2 commits intomainfrom
observability/tracing-attr/server.port
Open

feat(o11y): introduce server.port attribute#4128
diegomarquezp wants to merge 2 commits intomainfrom
observability/tracing-attr/server.port

Conversation

@diegomarquezp
Copy link
Contributor

@diegomarquezp diegomarquezp commented Mar 2, 2026

image

@product-auto-label product-auto-label bot added the size: m Pull request size is medium. label Mar 2, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, 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 enhances the observability features by introducing a server.port attribute to tracing spans. This allows for more granular monitoring and debugging by providing the specific port used for server communication in addition to the server address. The changes involve updating core GAX components to extract, store, and propagate this new attribute, along with adapting the OpenTelemetry integration to handle integer-type attributes.

Highlights

  • Introduced server.port attribute: The server.port attribute is now extracted from the endpoint and included in observability traces, providing more detailed connection information.
  • Updated tracing context to support Integer attributes: ApiTracerContext and related tracing components now support Integer values for attributes, specifically for server.port, by changing attribute maps from Map<String, String> to Map<String, Object>.
  • Enhanced endpoint parsing: EndpointContext gained new logic to parse and resolve the server port from an endpoint string, handling various formats including those with schemes and IPv6 literals.
Changelog
  • gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java
    • Added setServerPort call to ApiTracerContext.newBuilder().
  • gax-java/gax/src/main/java/com/google/api/gax/rpc/EndpointContext.java
    • Added abstract method resolvedServerPort() to EndpointContext.
    • Added abstract method setResolvedServerPort() to EndpointContext.Builder.
    • Implemented parseServerPort() method to extract the port from an endpoint string.
    • Called setResolvedServerPort() in the build() method to populate the port.
  • gax-java/gax/src/main/java/com/google/api/gax/tracing/ApiTracerContext.java
    • Changed getAttemptAttributes() return type from Map<String, String> to Map<String, Object>.
    • Added getServerPort() abstract method.
    • Added setServerPort() abstract method to Builder.
    • Included server.port in getAttemptAttributes() if available.
  • gax-java/gax/src/main/java/com/google/api/gax/tracing/ObservabilityAttributes.java
    • Defined SERVER_PORT_ATTRIBUTE constant.
  • gax-java/gax/src/main/java/com/google/api/gax/tracing/OpenTelemetryTraceManager.java
    • Updated createSpan to accept Map<String, Object> for attributes.
    • Modified attribute handling to correctly set String and Integer (converted to long) types for OpenTelemetry spans.
  • gax-java/gax/src/main/java/com/google/api/gax/tracing/SpanTracer.java
    • Updated attemptAttributes and attemptStarted to use Map<String, Object> for attributes.
  • gax-java/gax/src/test/java/com/google/api/gax/rpc/EndpointContextTest.java
    • Added assertions to verify resolvedServerPort() correctly extracts port numbers from various endpoint formats.
  • gax-java/gax/src/test/java/com/google/api/gax/tracing/OpenTelemetryTraceManagerTest.java
    • Updated testCreateSpan_recordsSpan to use Map<String, Object> for attributes.
  • gax-java/gax/src/test/java/com/google/api/gax/tracing/SpanTracerFactoryTest.java
    • Updated attributesCaptor to capture Map<String, Object>.
  • gax-java/gax/src/test/java/com/google/api/gax/tracing/SpanTracerTest.java
    • Updated attributesCaptor to capture Map<String, Object>.
  • java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelTracing.java
    • Added SHOWCASE_SERVER_PORT constant.
    • Enhanced integration tests to assert the presence and correctness of the server.port attribute in OpenTelemetry traces for both gRPC and HTTP/JSON.
Activity
  • No specific activity (comments, reviews, etc.) was provided in the context for this pull request.
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 the server.port attribute for observability, which is a valuable addition for tracing. The changes are consistently applied across the codebase, from endpoint parsing in EndpointContext to the OpenTelemetryTraceManager. The necessary API changes, like updating attribute maps to Map<String, Object>, are handled correctly. The tests, including unit and integration tests, are updated to cover the new functionality. I have one suggestion to improve the robustness of attribute handling in OpenTelemetryTraceManager for future maintainability.

Comment on lines +62 to +67
(k, v) -> {
if (v instanceof String) {
spanBuilder.setAttribute(k, (String) v);
} else if (v instanceof Integer) {
spanBuilder.setAttribute(k, (long) (Integer) v);
}
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 current implementation for setting attributes on the span only handles String and Integer types. While this is sufficient for the current changes, it makes the code brittle. If other attribute types (like Long, Double, or Boolean) are added in the future, they will be silently ignored. To improve future maintainability, it would be more robust to handle all primitive types supported by OpenTelemetry attributes.

          (k, v) -> {
            if (v instanceof String) {
              spanBuilder.setAttribute(k, (String) v);
            } else if (v instanceof Integer) {
              spanBuilder.setAttribute(k, (long) (Integer) v);
            } else if (v instanceof Long) {
              spanBuilder.setAttribute(k, (Long) v);
            } else if (v instanceof Double) {
              spanBuilder.setAttribute(k, (Double) v);
            } else if (v instanceof Boolean) {
              spanBuilder.setAttribute(k, (Boolean) v);
            }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/gemini I think it's worth to restrict it to only types we are introducing for now. New types are not expected and expanding this list will also imply additional testing (maintenance) for adding only one more type.

Copy link
Contributor

Choose a reason for hiding this comment

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

Does the type matter? Would it cause any differences in the UI? If not, can we just use String?

@diegomarquezp diegomarquezp marked this pull request as ready for review March 2, 2026 22:46
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

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

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

See analysis details on SonarQube Cloud

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 2, 2026

Quality Gate Failed Quality Gate failed for 'java_showcase_integration_tests'

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

See analysis details on SonarQube Cloud

}
try {
HostAndPort parsedHostPort = HostAndPort.fromString(hostPort);
if (parsedHostPort.hasPort()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic in this method is pretty much identical to the last method parseServerAddress, can we merge these two?

Comment on lines +62 to +67
(k, v) -> {
if (v instanceof String) {
spanBuilder.setAttribute(k, (String) v);
} else if (v instanceof Integer) {
spanBuilder.setAttribute(k, (long) (Integer) v);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the type matter? Would it cause any differences in the UI? If not, can we just use String?

.setTransportChannelProviderEndpoint(null)
.build();
Truth.assertThat(endpointContext.resolvedServerAddress()).isEqualTo("localhost");
Truth.assertThat(endpointContext.resolvedServerPort()).isEqualTo(7469);
Copy link
Contributor

Choose a reason for hiding this comment

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

I might missed this in the first PR, it's better to split these test cases to one case per test.

if (serverAddress() != null) {
attributes.put(ObservabilityAttributes.SERVER_ADDRESS_ATTRIBUTE, serverAddress());
}
if (serverPort() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's try to check both null and empty, this applies to all attributes too. We can use Strings.isNullOrEmpty.

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

Labels

size: m Pull request size is medium.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants