-
Notifications
You must be signed in to change notification settings - Fork 867
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Spring scheduling: run error handler with the same context as task (#…
- Loading branch information
Showing
8 changed files
with
243 additions
and
2 deletions.
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
...nstrumentation/spring/scheduling/v3_1/DelegatingErrorHandlingRunnableInstrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.spring.scheduling.v3_1; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor; | ||
import static net.bytebuddy.matcher.ElementMatchers.isPublic; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.Scope; | ||
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
import org.springframework.util.ErrorHandler; | ||
|
||
public class DelegatingErrorHandlingRunnableInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("org.springframework.scheduling.support.DelegatingErrorHandlingRunnable"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isConstructor().and(takesArgument(1, named("org.springframework.util.ErrorHandler"))), | ||
this.getClass().getName() + "$WrapErrorHandlerAdvice"); | ||
|
||
transformer.applyAdviceToMethod( | ||
isPublic().and(named("run")), this.getClass().getName() + "$RunAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class WrapErrorHandlerAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void onEnter( | ||
@Advice.Argument(value = 1, readOnly = false) ErrorHandler errorHandler) { | ||
if (errorHandler != null) { | ||
errorHandler = new ErrorHandlerWrapper(errorHandler); | ||
} | ||
} | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class RunAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static Scope onEnter() { | ||
Context parentContext = Java8BytecodeBridge.currentContext(); | ||
return TaskContextHolder.init(parentContext).makeCurrent(); | ||
} | ||
|
||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) | ||
public static void onExit(@Advice.Enter Scope scope) { | ||
if (scope != null) { | ||
scope.close(); | ||
} | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...o/opentelemetry/javaagent/instrumentation/spring/scheduling/v3_1/ErrorHandlerWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.spring.scheduling.v3_1; | ||
|
||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.Scope; | ||
import org.springframework.util.ErrorHandler; | ||
|
||
public final class ErrorHandlerWrapper implements ErrorHandler { | ||
private final ErrorHandler errorHandler; | ||
|
||
public ErrorHandlerWrapper(ErrorHandler errorHandler) { | ||
this.errorHandler = errorHandler; | ||
} | ||
|
||
@Override | ||
public void handleError(Throwable throwable) { | ||
Context taskContext = TaskContextHolder.getTaskContext(Context.current()); | ||
// run the error handler with the same context as task execution | ||
try (Scope ignore = taskContext != null ? taskContext.makeCurrent() : null) { | ||
errorHandler.handleError(throwable); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
.../io/opentelemetry/javaagent/instrumentation/spring/scheduling/v3_1/TaskContextHolder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.spring.scheduling.v3_1; | ||
|
||
import static io.opentelemetry.context.ContextKey.named; | ||
|
||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.ContextKey; | ||
import io.opentelemetry.context.ImplicitContextKeyed; | ||
import javax.annotation.Nullable; | ||
|
||
public final class TaskContextHolder implements ImplicitContextKeyed { | ||
|
||
private static final ContextKey<TaskContextHolder> KEY = | ||
named("opentelemetry-spring-scheduling-task"); | ||
|
||
private Context taskContext; | ||
|
||
private TaskContextHolder() {} | ||
|
||
public static Context init(Context context) { | ||
if (context.get(KEY) != null) { | ||
return context; | ||
} | ||
return context.with(new TaskContextHolder()); | ||
} | ||
|
||
public static void set(Context taskContext) { | ||
TaskContextHolder holder = taskContext.get(KEY); | ||
if (holder != null) { | ||
holder.taskContext = taskContext; | ||
} | ||
} | ||
|
||
@Nullable | ||
public static Context getTaskContext(Context context) { | ||
Context taskContext = null; | ||
TaskContextHolder holder = context.get(KEY); | ||
if (holder != null) { | ||
taskContext = holder.taskContext; | ||
} | ||
return taskContext; | ||
} | ||
|
||
@Override | ||
public Context storeInContext(Context context) { | ||
return context.with(KEY, this); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
instrumentation/spring/spring-scheduling-3.1/javaagent/src/test/java/TaskWithError.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.TimeUnit; | ||
import org.springframework.scheduling.annotation.Scheduled; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class TaskWithError implements Runnable { | ||
|
||
private final CountDownLatch latch = new CountDownLatch(1); | ||
|
||
@Scheduled(fixedRate = 5000) | ||
@Override | ||
public void run() { | ||
latch.countDown(); | ||
throw new IllegalStateException("failure"); | ||
} | ||
|
||
public void blockUntilExecute() throws InterruptedException { | ||
latch.await(5, TimeUnit.SECONDS); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...rumentation/spring/spring-scheduling-3.1/javaagent/src/test/java/TaskWithErrorConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import io.opentelemetry.instrumentation.testing.GlobalTraceUtil; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.scheduling.TaskScheduler; | ||
import org.springframework.scheduling.annotation.EnableScheduling; | ||
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; | ||
|
||
@Configuration | ||
@EnableScheduling | ||
public class TaskWithErrorConfig { | ||
@Bean | ||
public TaskWithError task() { | ||
return new TaskWithError(); | ||
} | ||
|
||
@Bean | ||
public TaskScheduler taskScheduler() { | ||
ConcurrentTaskScheduler scheduler = new ConcurrentTaskScheduler(); | ||
scheduler.setErrorHandler(throwable -> GlobalTraceUtil.runWithSpan("error-handler", () -> {})); | ||
return scheduler; | ||
} | ||
} |