This is an automated email from the ASF dual-hosted git repository.

sarvekshayr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new fa3fcc8897a HDDS-14765. Improve Trace Hierarchy for Ozone Shell Put 
Key Command (#9908)
fa3fcc8897a is described below

commit fa3fcc8897aba3ea1c776d249ca6a516e989e68e
Author: sravani <[email protected]>
AuthorDate: Fri Mar 20 19:28:21 2026 +0530

    HDDS-14765. Improve Trace Hierarchy for Ozone Shell Put Key Command (#9908)
---
 .../apache/hadoop/hdds/tracing/SkipTracing.java    | 31 ++++++++++++++
 .../apache/hadoop/hdds/tracing/TraceAllMethod.java | 31 +++++++++-----
 .../apache/hadoop/hdds/tracing/TracingUtil.java    | 22 ++++++++--
 .../hadoop/hdds/tracing/TestTraceAllMethod.java    | 34 ++++++++++++++++
 .../hadoop/hdds/tracing/TestTracingUtil.java       | 47 ++++++++++++++++++++++
 .../apache/hadoop/ozone/client/ObjectStore.java    |  3 +-
 ...OzoneManagerProtocolClientSideTranslatorPB.java |  2 +
 7 files changed, 156 insertions(+), 14 deletions(-)

diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/SkipTracing.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/SkipTracing.java
new file mode 100644
index 00000000000..861b24ad467
--- /dev/null
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/SkipTracing.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hdds.tracing;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to mark methods that should be excluded from tracing.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface SkipTracing {
+}
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java
index 95e735b8965..623e004a96e 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java
@@ -25,6 +25,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import org.apache.commons.lang3.tuple.Pair;
 
 /**
  * A Java proxy invocation handler to trace all the methods of the delegate
@@ -37,8 +38,7 @@ public class TraceAllMethod<T> implements InvocationHandler {
   /**
    * Cache for all the method objects of the delegate class.
    */
-  private final Map<String, Map<Class<?>[], Method>> methods = new HashMap<>();
-
+  private final Map<String, Map<Class<?>[], Pair<Boolean, Method>>> methods = 
new HashMap<>();
   private final T delegate;
 
   private final String name;
@@ -50,18 +50,31 @@ public TraceAllMethod(T delegate, String name) {
       if (method.getDeclaringClass().equals(Object.class)) {
         continue;
       }
+      boolean shouldSkip = method.isAnnotationPresent(SkipTracing.class);
       methods.computeIfAbsent(method.getName(), any -> new HashMap<>())
-          .put(method.getParameterTypes(), method);
+          .put(method.getParameterTypes(), Pair.of(shouldSkip, method));
     }
   }
 
   @Override
   public Object invoke(Object proxy, Method method, Object[] args)
       throws Throwable {
-    Method delegateMethod = findDelegatedMethod(method);
-    if (delegateMethod == null) {
-      throw new NoSuchMethodException("Method not found: " +
-        method.getName());
+    Pair<Boolean, Method> methodInfo = findDelegatedMethod(method);
+    if (methodInfo == null) {
+      throw new NoSuchMethodException("Method not found: " + method.getName());
+    }
+    boolean shouldSkip = methodInfo.getLeft();
+    Method delegateMethod = methodInfo.getRight();
+    if (shouldSkip) {
+      try {
+        return delegateMethod.invoke(delegate, args);
+      } catch (Exception ex) {
+        if (ex.getCause() != null) {
+          throw ex.getCause();
+        } else {
+          throw ex;
+        }
+      }
     }
 
     try (TracingUtil.TraceCloseable ignored = 
TracingUtil.createActivatedSpan(name + "." + method.getName())) {
@@ -77,8 +90,8 @@ public Object invoke(Object proxy, Method method, Object[] 
args)
     }
   }
 
-  private Method findDelegatedMethod(Method method) {
-    for (Entry<Class<?>[], Method> entry : methods.getOrDefault(
+  private Pair<Boolean, Method> findDelegatedMethod(Method method) {
+    for (Entry<Class<?>[], Pair<Boolean, Method>> entry : methods.getOrDefault(
         method.getName(), emptyMap()).entrySet()) {
       if (Arrays.equals(entry.getKey(), method.getParameterTypes())) {
         return entry.getValue();
diff --git 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TracingUtil.java
 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TracingUtil.java
index 560f3876c11..8d6e0fd240f 100644
--- 
a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TracingUtil.java
+++ 
b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TracingUtil.java
@@ -179,10 +179,11 @@ public static boolean isTracingEnabled(
 
   /**
    * Execute {@code runnable} inside an activated new span.
+   * If a parent span exists in the current context, this becomes a child span.
    */
   public static <E extends Exception> void executeInNewSpan(String spanName,
       CheckedRunnable<E> runnable) throws E {
-    Span span = tracer.spanBuilder(spanName).setNoParent().startSpan();
+    Span span = buildSpan(spanName);
     executeInSpan(span, runnable);
   }
 
@@ -191,7 +192,7 @@ public static <E extends Exception> void 
executeInNewSpan(String spanName,
    */
   public static <R, E extends Exception> R executeInNewSpan(String spanName,
       CheckedSupplier<R, E> supplier) throws E {
-    Span span = tracer.spanBuilder(spanName).setNoParent().startSpan();
+    Span span = buildSpan(spanName);
     return executeInSpan(span, supplier);
   }
 
@@ -244,7 +245,7 @@ public static <E extends Exception> void 
executeAsChildSpan(String spanName,
    * in case of Exceptions.
    */
   public static TraceCloseable createActivatedSpan(String spanName) {
-    Span span = tracer.spanBuilder(spanName).setNoParent().startSpan();
+    Span span = buildSpan(spanName);
     Scope scope = span.makeCurrent();
     return () -> {
       scope.close();
@@ -299,4 +300,19 @@ private void parse(String carrier) {
       }
     }
   }
+
+  /**
+   * Creates a new span, using the current context as a parent if valid;
+   * otherwise, creates a root span.
+   */
+  private static Span buildSpan(String spanName) {
+    Context currentContext = Context.current();
+    Span parentSpan = Span.fromContext(currentContext);
+
+    if (parentSpan.getSpanContext().isValid()) {
+      return 
tracer.spanBuilder(spanName).setParent(currentContext).startSpan();
+    } else {
+      return tracer.spanBuilder(spanName).setNoParent().startSpan();
+    }
+  }
 }
diff --git 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTraceAllMethod.java
 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTraceAllMethod.java
index bae0cbdd67c..f24a54367b3 100644
--- 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTraceAllMethod.java
+++ 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTraceAllMethod.java
@@ -20,6 +20,8 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
+import io.opentelemetry.api.trace.Span;
+import java.io.IOException;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -52,6 +54,12 @@ default String defaultMethod() {
       return otherMethod("default");
     }
 
+    String skippedMethod();
+
+    void throwingMethod() throws IOException;
+
+    String normalMethod();
+
     String otherMethod(String name);
   }
 
@@ -60,9 +68,35 @@ default String defaultMethod() {
    */
   public static class ServiceImpl implements Service {
 
+    private boolean spanActive = false;
+
     @Override
     public String otherMethod(String name) {
       return "Hello " + name;
     }
+
+    @Override
+    @SkipTracing
+    public String skippedMethod() {
+      this.spanActive = Span.current().getSpanContext().isValid();
+      return "skipped";
+    }
+
+    @Override
+    @SkipTracing
+    public void throwingMethod() throws IOException {
+      this.spanActive = Span.current().getSpanContext().isValid();
+      throw new IOException("Original Exception");
+    }
+
+    @Override
+    public String normalMethod() {
+      this.spanActive = Span.current().getSpanContext().isValid();
+      return "normal";
+    }
+
+    public boolean wasSpanActive() {
+      return spanActive;
+    }
   }
 }
diff --git 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTracingUtil.java
 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTracingUtil.java
index 0df11a03ed3..7b73b30ab7f 100644
--- 
a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTracingUtil.java
+++ 
b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/tracing/TestTracingUtil.java
@@ -20,8 +20,12 @@
 import static org.apache.hadoop.hdds.tracing.TracingUtil.createProxy;
 import static org.apache.hadoop.hdds.tracing.TracingUtil.exportCurrentSpan;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import java.io.IOException;
 import org.apache.hadoop.hdds.conf.InMemoryConfigurationForTesting;
 import org.apache.hadoop.hdds.conf.MutableConfigurationSource;
 import org.apache.hadoop.hdds.scm.ScmConfigKeys;
@@ -58,4 +62,47 @@ private static MutableConfigurationSource tracingEnabled() {
     return config;
   }
 
+  /**
+   * Test for checking if span was not created when a regular method
+   * in Service implementation has @SkipTracing.
+   */
+  @Test
+  public void testSkipTracingNoSpan() {
+    TracingUtil.initTracing("TestService", tracingEnabled());
+    ServiceImpl impl = new ServiceImpl();
+    Service serviceProxy = createProxy(impl, Service.class, tracingEnabled());
+
+    serviceProxy.skippedMethod();
+    assertFalse(impl.wasSpanActive(), "Span should NOT be created for 
@SkipTracing methods.");
+  }
+
+  /**
+   * Test for checking if span was not created when a method throws exception
+   * in Service implementation and has @SkipTracing.
+   */
+  @Test
+  public void testSkipTracingExceptionUnwrapped() {
+    TracingUtil.initTracing("TestService", tracingEnabled());
+    ServiceImpl impl = new ServiceImpl();
+    Service serviceProxy = createProxy(impl, Service.class, tracingEnabled());
+
+    IOException ex = assertThrows(IOException.class,
+        () -> serviceProxy.throwingMethod());
+    assertEquals("Original Exception", ex.getMessage());
+    assertFalse(impl.wasSpanActive(), "Span should NOT have been created for a 
@SkipTracing throwing method.");
+  }
+
+  /**
+   * Test for checking if span is created when a method in Service 
implementation
+   * does not have @SkipTracing.
+   */
+  @Test
+  public void testProxyNormalVsSkipped() {
+    TracingUtil.initTracing("TestService", tracingEnabled());
+    ServiceImpl impl = new ServiceImpl();
+    Service serviceProxy = createProxy(impl, Service.class, tracingEnabled());
+
+    serviceProxy.normalMethod();
+    assertTrue(impl.wasSpanActive(), "Normal method should have an active 
span.");
+  }
 }
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 456dc916214..519cda0c9ae 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -28,7 +28,6 @@
 import org.apache.hadoop.crypto.key.KeyProvider;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
-import org.apache.hadoop.hdds.tracing.TracingUtil;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ozone.OmUtils;
 import org.apache.hadoop.ozone.OzoneAcl;
@@ -83,7 +82,7 @@ public class ObjectStore {
    * @param proxy ClientProtocol proxy.
    */
   public ObjectStore(ConfigurationSource conf, ClientProtocol proxy) {
-    this.proxy = TracingUtil.createProxy(proxy, ClientProtocol.class, conf);
+    this.proxy = proxy;
     this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
     s3BucketLayout = OmUtils.validateBucketLayout(
         conf.getTrimmed(
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 9f09fb37e03..6960c11aaaa 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -48,6 +48,7 @@
 import 
org.apache.hadoop.hdds.protocol.proto.HddsProtos.TransferLeadershipRequestProto;
 import 
org.apache.hadoop.hdds.protocol.proto.HddsProtos.UpgradeFinalizationStatus;
 import org.apache.hadoop.hdds.scm.container.common.helpers.ExcludeList;
+import org.apache.hadoop.hdds.tracing.SkipTracing;
 import org.apache.hadoop.hdds.tracing.TracingUtil;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ipc_.CallerContext;
@@ -2088,6 +2089,7 @@ public ThreadLocal<S3Auth> getS3CredentialsProvider() {
   }
 
   @Override
+  @SkipTracing
   public S3Auth getThreadLocalS3Auth() {
     return this.threadLocalS3Auth.get();
   }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to