Removed execution task listener - it makes runner spans share the same trace id

This commit is contained in:
Marcin Grzejszczak
2022-05-30 11:01:23 +02:00
parent 88111e3eaa
commit 6ba808781b
6 changed files with 11 additions and 175 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.cloud.task.configuration.observation;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -42,12 +41,6 @@ import org.springframework.context.annotation.Configuration;
@AutoConfigureAfter(ObservationAutoConfiguration.class)
public class ObservationTaskAutoConfiguration {
@Bean
ObservationTaskExecutionListener traceTaskExecutionListener(ObservationRegistry registry,
@Value("${spring.application.name:default}") String appName) {
return new ObservationTaskExecutionListener(registry, appName);
}
@Bean
static ObservationCommandLineRunnerBeanPostProcessor observedCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) {
return new ObservationCommandLineRunnerBeanPostProcessor(beanFactory);

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2018-2022 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.cloud.task.configuration.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.task.listener.TaskExecutionListener;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.core.Ordered;
/**
* Sets the span upon starting and closes it upon ending a task.
*
* @author Marcin Grzejszczak
* @since 3.1.0
*/
class ObservationTaskExecutionListener implements TaskExecutionListener, Ordered {
private static final Log log = LogFactory.getLog(ObservationTaskExecutionListener.class);
private final ObservationRegistry registry;
private final String projectName;
ObservationTaskExecutionListener(ObservationRegistry registry, String projectName) {
this.registry = registry;
this.projectName = projectName;
}
@Override
public void onTaskStartup(TaskExecution taskExecution) {
Observation observation = TaskDocumentedObservation.TASK_EXECUTION_LISTENER_OBSERVATION.observation(this.registry)
.contextualName(this.projectName)
.start();
observation.openScope();
if (log.isDebugEnabled()) {
log.debug("Put the observation [" + observation + "] in scope");
}
}
@Override
public void onTaskEnd(TaskExecution taskExecution) {
Observation.Scope scope = this.registry.getCurrentObservationScope();
if (scope != null) {
scope.close();
scope.getCurrentObservation().stop();
if (log.isDebugEnabled()) {
log.debug("Removed the [" + scope.getCurrentObservation() + "] from thread local");
}
}
}
@Override
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
Observation.Scope scope = this.registry.getCurrentObservationScope();
if (scope != null) {
Observation observation = scope.getCurrentObservation();
observation.error(throwable);
onTaskEnd(taskExecution);
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}

View File

@@ -35,22 +35,6 @@ enum TaskDocumentedObservation implements DocumentedObservation {
return TaskRunnerTags.values();
}
@Override
public String getPrefix() {
return "spring.cloud.task";
}
},
/**
* Observation created within the lifecycle of a task.
*/
TASK_EXECUTION_LISTENER_OBSERVATION {
@Override
public String getName() {
return "spring.cloud.task.execution";
}
@Override
public String getPrefix() {
return "spring.cloud.task";

View File

@@ -47,6 +47,8 @@ import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingA
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -79,7 +81,8 @@ class ObservationIntegrationTests {
}
@Configuration
@ImportAutoConfiguration({ObservationAutoConfiguration.class, ObservationTaskAutoConfiguration.class, BraveAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, ZipkinAutoConfiguration.class})
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, ObservationAutoConfiguration.class, ObservationTaskAutoConfiguration.class, BraveAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, ZipkinAutoConfiguration.class})
@EnableTask
static class Config {
private static final Logger log = LoggerFactory.getLogger(Config.class);

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2017-2022 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.cloud.task.configuration.observation;
import java.util.Date;
import java.util.List;
import io.micrometer.core.tck.TestObservationRegistry;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.task.repository.TaskExecution;
import static io.micrometer.core.tck.TestObservationRegistryAssert.then;
class ObservationTaskExecutionListenerTests {
@Test
void testSuccessfulObservation() {
TestObservationRegistry registry = TestObservationRegistry.create();
ObservationTaskExecutionListener listener = new ObservationTaskExecutionListener(registry, "my-project");
TaskExecution taskExecution = taskExecution();
listener.onTaskStartup(taskExecution);
listener.onTaskEnd(taskExecution);
then(registry)
.hasSingleObservationThat()
.hasNameEqualTo("spring.cloud.task.execution")
.hasContextualNameEqualTo("my-project");
}
@Test
void testErrorObservation() {
TestObservationRegistry registry = TestObservationRegistry.create();
ObservationTaskExecutionListener listener = new ObservationTaskExecutionListener(registry, "my-project");
TaskExecution taskExecution = taskExecution();
listener.onTaskStartup(taskExecution);
listener.onTaskFailed(taskExecution, new RuntimeException("error"));
then(registry)
.hasSingleObservationThat()
.hasNameEqualTo("spring.cloud.task.execution")
.hasContextualNameEqualTo("my-project")
.thenThrowable()
.hasMessage("error");
}
private TaskExecution taskExecution() {
return new TaskExecution(1L, 1, "task", new Date(), new Date(), "bye", List.of("arg"), "boom", "id");
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files=".*ObservationTaskAutoConfiguration.*" checks="HideUtilityClassConstructorCheck"/>
</suppressions>