From 0af72e31acc2d70fa4fb0258ae83fdfafa9e887b Mon Sep 17 00:00:00 2001 From: Michael Minella Date: Wed, 3 Jul 2019 11:01:08 -0500 Subject: [PATCH] Polish --- ...oudFoundryMicrometerTagsConfiguration.java | 79 ---------- .../MetricsAutoConfiguration.java | 136 +++++++++++++++++ ...TaskMicrometerCommonTagsConfiguration.java | 63 -------- .../task/listener/TaskLifecycleListener.java | 2 +- .../cloud/task/listener/TaskMetrics.java | 6 +- .../metrics/fork/MeterRegistryCustomizer.java | 44 ------ .../fork/MetricsAutoConfiguration.java | 139 ------------------ .../main/resources/META-INF/spring.factories | 4 +- .../task/micrometer/TaskMetricsTests.java | 2 +- 9 files changed, 144 insertions(+), 331 deletions(-) delete mode 100644 spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/CloudFoundryMicrometerTagsConfiguration.java create mode 100644 spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/MetricsAutoConfiguration.java delete mode 100644 spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SpringCloudTaskMicrometerCommonTagsConfiguration.java delete mode 100644 spring-cloud-task-core/src/main/java/org/springframework/cloud/task/metrics/fork/MeterRegistryCustomizer.java delete mode 100644 spring-cloud-task-core/src/main/java/org/springframework/cloud/task/metrics/fork/MetricsAutoConfiguration.java diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/CloudFoundryMicrometerTagsConfiguration.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/CloudFoundryMicrometerTagsConfiguration.java deleted file mode 100644 index 0c3d3fc3..00000000 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/CloudFoundryMicrometerTagsConfiguration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2019-2019 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; - -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.task.metrics.fork.MeterRegistryCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; - -/** - * Micrometer common tags for Cloud Foundry deployment properties. Based on the CF - * application environment variables: - * https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html - * - * Tags are set only if the "cloud" Spring profile is set. The "cloud" profile is - * activated automatically when an application is deployed in CF: - * https://docs.cloudfoundry.org/buildpacks/java/configuring-service-connections/spring-service-bindings.html#cloud-profiles - * - * Use the spring.cloud.task.metrics.cf.tags.enabled=false property to disable inserting - * those tags. - * - * @author Christian Tzolov - */ -@Configuration -@Profile("cloud") -@ConditionalOnProperty(name = "spring.cloud.task.metrics.cf.tags.enabled", - havingValue = "true", matchIfMissing = true) -public class CloudFoundryMicrometerTagsConfiguration { - - @Value("${vcap.application.org_name:default}") - private String organizationName; - - @Value("${vcap.application.space_id:unknown}") - private String spaceId; - - @Value("${vcap.application.space_name:unknown}") - private String spaceName; - - @Value("${vcap.application.application_name:unknown}") - private String applicationName; - - @Value("${vcap.application.application_id:unknown}") - private String applicationId; - - @Value("${vcap.application.application_version:unknown}") - private String applicationVersion; - - @Value("${vcap.application.instance_index:0}") - private String instanceIndex; - - @Bean - public MeterRegistryCustomizer cloudFoundryMetricsCommonTags() { - return registry -> registry.config().commonTags("cf.org.name", organizationName) - .commonTags("cf.space.id", spaceId).commonTags("cf.space.name", spaceName) - .commonTags("cf.app.id", applicationId) - .commonTags("cf.app.name", applicationName) - .commonTags("cf.app.version", applicationVersion) - .commonTags("cf.instance.index", instanceIndex); - } - -} diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/MetricsAutoConfiguration.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/MetricsAutoConfiguration.java new file mode 100644 index 00000000..bf7ff72b --- /dev/null +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/MetricsAutoConfiguration.java @@ -0,0 +1,136 @@ +/* + * Copyright 2019-2019 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; + +import java.util.Arrays; + +import io.micrometer.core.annotation.Timed; +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.MeterRegistry; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; + +/** + * Forked and simplified version of the + * org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration form + * spring-boot-actuator + * + * {@link EnableAutoConfiguration Auto-configuration} for Micrometer-based metrics. + * + * @author Michael Minella + * @since 2.2 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass(Timed.class) +@AutoConfigureBefore(name = { + "org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration" }) +public class MetricsAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public Clock micrometerClockFork() { + return Clock.SYSTEM; + } + + @Bean + public static MeterRegistryPostProcessor meterRegistryPostProcessorFork() { + return new MeterRegistryPostProcessor(); + } + + static class MeterRegistryPostProcessor + implements BeanPostProcessor, EnvironmentAware { + + private Environment environment; + + @Value("${spring.cloud.task.name:unknown}") + private String taskName; + + @Value("${spring.cloud.task.executionid:unknown}") + private String taskExecutionId; + + @Value("${spring.cloud.task.external-execution-id:unknown}") + private String taskExternalExecutionId; + + @Value("${spring.cloud.task.parent-execution-id:unknown}") + private String taskParentExecutionId; + + @Value("${vcap.application.org_name:default}") + private String organizationName; + + @Value("${vcap.application.space_id:unknown}") + private String spaceId; + + @Value("${vcap.application.space_name:unknown}") + private String spaceName; + + @Value("${vcap.application.application_name:unknown}") + private String applicationName; + + @Value("${vcap.application.application_id:unknown}") + private String applicationId; + + @Value("${vcap.application.application_version:unknown}") + private String applicationVersion; + + @Value("${vcap.application.instance_index:0}") + private String instanceIndex; + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + + if (bean instanceof MeterRegistry) { + MeterRegistry registry = (MeterRegistry) bean; + + if (Arrays.asList(this.environment.getActiveProfiles()) + .contains("cloud")) { + registry.config().commonTags("cf.org.name", organizationName) + .commonTags("cf.space.id", spaceId) + .commonTags("cf.space.name", spaceName) + .commonTags("cf.app.id", applicationId) + .commonTags("cf.app.name", applicationName) + .commonTags("cf.app.version", applicationVersion) + .commonTags("cf.instance.index", instanceIndex); + } + + registry.config().commonTags("task.name", taskName) + .commonTags("task.execution.id", taskExecutionId) + .commonTags("task.external.execution.id", taskExternalExecutionId) + .commonTags("task.parent.execution.id", taskParentExecutionId); + } + + return bean; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + } + +} diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SpringCloudTaskMicrometerCommonTagsConfiguration.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SpringCloudTaskMicrometerCommonTagsConfiguration.java deleted file mode 100644 index b7bfc2ab..00000000 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/SpringCloudTaskMicrometerCommonTagsConfiguration.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2019-2019 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; - -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.task.metrics.fork.MeterRegistryCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Auto configuration extends the micrometer metrics with additional tags such as: task - * name, application name, instance index and guids. Later are necessary to allow - * discrimination and aggregation of app metrics by external metrics collection and - * visualizaiton tools. - * - * Use the spring.cloud.task.metrics.common.tags.enabled=false property to disable - * inserting those tags. - * - * @author Christian Tzolov - */ -@Configuration -@ConditionalOnProperty(name = "spring.cloud.task.metrics.common.tags.enabled", - havingValue = "true", matchIfMissing = true) -public class SpringCloudTaskMicrometerCommonTagsConfiguration { - - @Value("${spring.cloud.task.name:unknown}") - private String taskName; - - @Value("${spring.cloud.task.executionid:unknown}") - private String taskExecutionId; - - @Value("${spring.cloud.task.external-execution-id:unknown}") - private String taskExternalExecutionId; - - @Value("${spring.cloud.task.parent-execution-id:unknown}") - private String taskParentExecutionId; - - @Bean - public MeterRegistryCustomizer metricsCommonTags() { - return registry -> registry.config().commonTags("task.name", taskName) - .commonTags("task.execution.id", taskExecutionId) - .commonTags("task.external.execution.id", taskExternalExecutionId) - .commonTags("task.parent.execution.id", taskParentExecutionId); - } - -} diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java index b2580996..0f982124 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskLifecycleListener.java @@ -362,7 +362,7 @@ public class TaskLifecycleListener implements ApplicationListener - * Customizers are guaranteed to be applied before any {@link Meter} is registered with - * the registry. - * - * @author Michael Minella - */ -@FunctionalInterface -public interface MeterRegistryCustomizer { - - /** - * Customize the given {@code registry}. - * @param registry the registry to customize - */ - void customize(T registry); - -} diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/metrics/fork/MetricsAutoConfiguration.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/metrics/fork/MetricsAutoConfiguration.java deleted file mode 100644 index d2b2ccc1..00000000 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/metrics/fork/MetricsAutoConfiguration.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2019-2019 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.metrics.fork; - -import java.util.List; -import java.util.stream.Collectors; - -import io.micrometer.core.annotation.Timed; -import io.micrometer.core.instrument.Clock; -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.util.LambdaSafe; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Forked and stripped down version of the - * org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration form - * spring-boot-actuator - * - * {@link EnableAutoConfiguration Auto-configuration} for Micrometer-based metrics. - * - * @author Michael Minella - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Timed.class) -@AutoConfigureBefore(name = { - "org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration" }) -public class MetricsAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public Clock micrometerClockFork() { - return Clock.SYSTEM; - } - - @Bean - public static MeterRegistryPostProcessor meterRegistryPostProcessorFork( - ObjectProvider> meterRegistryCustomizers) { - return new MeterRegistryPostProcessor(meterRegistryCustomizers); - } - - /** - * Forked and stripped down version of the - * org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor - * form spring-boot-actuator - * - * {@link BeanPostProcessor} that delegates to a lazily created - * {@link MeterRegistryConfigurer} to post-process {@link MeterRegistry} beans. - * - */ - static class MeterRegistryPostProcessor implements BeanPostProcessor { - - private final ObjectProvider> meterRegistryCustomizers; - - private volatile MeterRegistryConfigurer configurer; - - MeterRegistryPostProcessor( - ObjectProvider> meterRegistryCustomizers) { - this.meterRegistryCustomizers = meterRegistryCustomizers; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) - throws BeansException { - if (bean instanceof MeterRegistry) { - getConfigurer().configure((MeterRegistry) bean); - } - return bean; - } - - private MeterRegistryConfigurer getConfigurer() { - if (this.configurer == null) { - this.configurer = new MeterRegistryConfigurer( - this.meterRegistryCustomizers); - } - return this.configurer; - } - - } - - /** - * Forked and stripped down version of the - * org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer form - * spring-boot-actuator - * - * Configurer to apply {@link MeterRegistryCustomizer customizers} to - * {@link MeterRegistry meter registries}. - * - */ - static class MeterRegistryConfigurer { - - private final ObjectProvider> customizers; - - MeterRegistryConfigurer(ObjectProvider> customizers) { - this.customizers = customizers; - } - - void configure(MeterRegistry registry) { - customize(registry); - } - - @SuppressWarnings("unchecked") - private void customize(MeterRegistry registry) { - LambdaSafe - .callbacks(MeterRegistryCustomizer.class, - asOrderedList(this.customizers), registry) - .withLogger(MeterRegistryConfigurer.class) - .invoke((customizer) -> customizer.customize(registry)); - } - - private List asOrderedList(ObjectProvider provider) { - return provider.orderedStream().collect(Collectors.toList()); - } - - } - -} diff --git a/spring-cloud-task-core/src/main/resources/META-INF/spring.factories b/spring-cloud-task-core/src/main/resources/META-INF/spring.factories index aeba503d..e0401a79 100644 --- a/spring-cloud-task-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-task-core/src/main/resources/META-INF/spring.factories @@ -1,7 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.task.configuration.SingleTaskConfiguration,\ org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration,\ -org.springframework.cloud.task.configuration.CloudFoundryMicrometerTagsConfiguration,\ -org.springframework.cloud.task.configuration.SpringCloudTaskMicrometerCommonTagsConfiguration,\ -org.springframework.cloud.task.metrics.fork.MetricsAutoConfiguration\ +org.springframework.cloud.task.configuration.MetricsAutoConfiguration\ diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/micrometer/TaskMetricsTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/micrometer/TaskMetricsTests.java index 942197f7..e2504d31 100644 --- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/micrometer/TaskMetricsTests.java +++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/micrometer/TaskMetricsTests.java @@ -129,7 +129,7 @@ public class TaskMetricsTests { assertThat(longTaskTimer.getId().getTag(TaskMetrics.TASK_EXECUTION_ID_TAG)) .isEqualTo("123"); - taskMetrics.onTaskFailed(taskExecution, new RuntimeException("Test")); + taskMetrics.onTaskFailed(new RuntimeException("Test")); // Finish Task. TaskLifecycleListen calls onTaskEnd after the onTaskFailed. Make // sure that the counter status