Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -53,6 +54,7 @@
private final String attemptSpanName;
private final ApiTracerContext apiTracerContext;
private @Nullable Span attemptSpan;
private io.opentelemetry.context.@Nullable Scope attemptScope;

Check warning on line 57 in sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/OpenTelemetryTracingTracer.java

View check run for this annotation

SonarQubeCloud / [gapic-generator-java-root] SonarCloud Code Analysis

Remove this unused "attemptScope" private field.

See more on https://sonarcloud.io/project/issues?id=googleapis_google-cloud-java_showcase&issues=AZ-54pRWSOjhs3JvDZdm&open=AZ-54pRWSOjhs3JvDZdm&pullRequest=13977

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.

high

The field attemptScope is declared here but is never initialized, used, or closed anywhere in the class. The PR description states that the OpenTelemetry context Scope is activated during attemptStarted(...), but that implementation is missing. Please implement the scope activation in attemptStarted(...) using otelContext.makeCurrent() as described.

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.

high

The field attemptScope is declared here but is never initialized, used, or closed. The PR description states that active scope context propagation is implemented via otelContext.makeCurrent() and cleaned up in endAttempt(), but these changes are missing from the implementation. Please ensure that the scope is properly activated when the attempt starts and closed when the attempt ends to prevent context leaks.


@Override
public void injectTraceContext(java.util.Map<String, String> carrier) {
Expand Down Expand Up @@ -225,21 +227,22 @@
attemptSpan.setAllAttributes(ObservabilityUtils.toOtelAttributes(responseAttributes));
}

if (error != null && !Strings.isNullOrEmpty(error.getMessage())) {
attemptSpan.setAttribute(
ObservabilityAttributes.STATUS_MESSAGE_ATTRIBUTE, error.getMessage());
if (error != null) {
attemptSpan.setStatus(StatusCode.ERROR);
if (!Strings.isNullOrEmpty(error.getMessage())) {
attemptSpan.setAttribute(
ObservabilityAttributes.STATUS_MESSAGE_ATTRIBUTE, error.getMessage());
}
}
Comment on lines +230 to 236

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.

medium

Since attemptSpan is annotated with @Nullable, we should perform a null check before calling methods on it to prevent potential NullPointerExceptions.

Suggested change
if (error != null) {
attemptSpan.setStatus(StatusCode.ERROR);
if (!Strings.isNullOrEmpty(error.getMessage())) {
attemptSpan.setAttribute(
ObservabilityAttributes.STATUS_MESSAGE_ATTRIBUTE, error.getMessage());
}
}
if (attemptSpan != null && error != null) {
attemptSpan.setStatus(StatusCode.ERROR);
if (!Strings.isNullOrEmpty(error.getMessage())) {
attemptSpan.setAttribute(
ObservabilityAttributes.STATUS_MESSAGE_ATTRIBUTE, error.getMessage());
}
}


endAttempt();
}

private void endAttempt() {
if (attemptSpan == null) {
return;
if (attemptSpan != null) {
attemptSpan.end();
attemptSpan = null;
}

attemptSpan.end();
attemptSpan = null;
}
Comment on lines 241 to 246

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.

high

To prevent context leaks, the attemptScope must be closed when ending the attempt. Ensure that closeable resources are closed in the reverse order of their creation (LIFO) and that the implementation is exception-safe so that all resources are closed even if an exception occurs during closing.

  private void endAttempt() {
    try {
      if (attemptScope != null) {
        attemptScope.close();
      }
    } finally {
      attemptScope = null;
      try {
        if (attemptSpan != null) {
          attemptSpan.end();
        }
      } finally {
        attemptSpan = null;
      }
    }
  }
References
  1. When managing a collection of closeable resources (e.g., scopes), ensure they are closed in the reverse order of their creation (LIFO). The implementation must be exception-safe to prevent resource leaks, meaning all opened resources should be closed even if exceptions occur during their creation or closing.

Comment on lines 241 to 246

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.

high

The attemptScope is not closed in endAttempt(). To prevent context leaks, ensure that the scope is closed in endAttempt(). According to general rules, closeable resources should be closed in the reverse order of their creation (LIFO) and in an exception-safe manner.

  private void endAttempt() {
    try {
      if (attemptScope != null) {
        attemptScope.close();
      }
    } finally {
      attemptScope = null;
      try {
        if (attemptSpan != null) {
          attemptSpan.end();
        }
      } finally {
        attemptSpan = null;
      }
    }
  }
References
  1. When managing a collection of closeable resources (e.g., scopes), ensure they are closed in the reverse order of their creation (LIFO). The implementation must be exception-safe to prevent resource leaks, meaning all opened resources should be closed even if exceptions occur during their creation or closing.


@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ void testAttemptLifecycle_startsAndEndsAttemptSpan() {
verify(span).end();
}

@Test
void testAttemptFailed_setsErrorStatus() {
openTelemetryTracingTracer.attemptStarted(new Object(), 1);
openTelemetryTracingTracer.attemptFailedDuration(
new RuntimeException("Test error"), java.time.Duration.ofSeconds(1));

verify(span).setStatus(io.opentelemetry.api.trace.StatusCode.ERROR);
verify(span).end();
}
Comment on lines +91 to +98

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.

medium

This test only verifies that the span status is set to ERROR and that the span is ended. It does not verify that the active scope is managed (i.e., activated and closed/restored). Once the scope management is implemented, please add assertions/verifications to ensure the scope is correctly activated and closed.


@Test
void testAttemptSucceeded_grpc() {
ApiTracerContext context =
Expand Down
Loading