Skip to content

Upgrade to micrometer 1.0.0-rc.5 #11071

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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 @@ -24,6 +24,7 @@

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand All @@ -36,25 +37,29 @@
class MeterBindersConfiguration {

@Bean
@ConditionalOnProperty(value = "spring.metrics.binders.jvmmemory.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean(JvmMemoryMetrics.class)
public JvmMemoryMetrics jvmMemoryMetrics() {
return new JvmMemoryMetrics();
}

@Bean
@ConditionalOnMissingBean(LogbackMetrics.class)
@ConditionalOnProperty(value = "spring.metrics.binders.logback.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnClass(name = "ch.qos.logback.classic.Logger")
public LogbackMetrics logbackMetrics() {
return new LogbackMetrics();
}

@Bean
@ConditionalOnProperty(value = "spring.metrics.binders.uptime.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean(UptimeMetrics.class)
public UptimeMetrics uptimeMetrics() {
return new UptimeMetrics();
}

@Bean
@ConditionalOnProperty(value = "spring.metrics.binders.processor.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean(ProcessorMetrics.class)
public ProcessorMetrics processorMetrics() {
return new ProcessorMetrics();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsConfiguration;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.boot.actuate.metrics.config.EnvironmentMeterFilter;
import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand All @@ -54,6 +55,8 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.integration.config.EnableIntegrationManagement;
import org.springframework.integration.support.management.IntegrationManagementConfigurer;

Expand All @@ -75,6 +78,11 @@
SimpleExportConfiguration.class, StatsdExportConfiguration.class })
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MetricsAutoConfiguration {
@Bean
@Order(0)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sanity check please?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can use @Order on @Bean methods.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scrub that, yes you can.

MeterRegistryConfigurer springEnvironmentMeterFilter(Environment environment) {
return r -> r.config().meterFilter(new EnvironmentMeterFilter(environment));
}

@Bean
@ConditionalOnMissingBean(MeterRegistry.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.time.Duration;

import io.micrometer.core.instrument.simple.CountingMode;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;

import org.springframework.boot.context.properties.ConfigurationProperties;
Expand All @@ -42,6 +43,8 @@ public class SimpleProperties {
*/
private Duration step = Duration.ofSeconds(10);

private CountingMode mode = CountingMode.Cumulative;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unusual enum format. Any reason for Cumulative, Step and not CUMULATIVE, STEP? Binding should work regardless I think.


public boolean getEnabled() {
return this.enabled;
}
Expand All @@ -57,4 +60,12 @@ public Duration getStep() {
public void setStep(Duration step) {
this.step = step;
}

public CountingMode getMode() {
return mode;
}

public void setMode(CountingMode mode) {
this.mode = mode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.time.Duration;

import io.micrometer.core.instrument.simple.CountingMode;
import io.micrometer.core.instrument.simple.SimpleConfig;

import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
Expand Down Expand Up @@ -50,4 +51,9 @@ public boolean enabled() {
public Duration step() {
return get(SimpleProperties::getStep, SimpleConfig::step);
}

@Override
public CountingMode mode() {
return get(SimpleProperties::getMode, SimpleConfig::mode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright 2012-2017 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
*
* 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.springframework.boot.actuate.metrics.async;

import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;

import io.micrometer.core.instrument.FunctionCounter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.binder.MeterBinder;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
* Monitors the status of {@link ThreadPoolTaskExecutor} pools. Does not record timings on
* operations executed in the {@link ExecutorService}, as this requires the instance to be
* wrapped. Timings are provided separately by wrapping the executor service with
* {@link TimedThreadPoolTaskExecutor}.
*
* @author David Held
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the author signed the CLA? We can't accept this if not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dheld-expedia are you the original author for this? Any chance you could consider submitting it as a PR for Boot so the CLA bot confirms that you've signed the CLA.

*/
public class ThreadPoolTaskExecutorMetrics implements MeterBinder {
/**
* Returns a new {@link ThreadPoolTaskExecutor} with recorded metrics.
*
* @param registry The registry to bind metrics to.
* @param name The name prefix of the metrics.
* @param tags Tags to apply to all recorded metrics.
* @return The instrumented executor, proxied.
*/
public static ThreadPoolTaskExecutor monitor(MeterRegistry registry, String name,
Iterable<Tag> tags) {
return new TimedThreadPoolTaskExecutor(registry, name, tags);
}

/**
* Returns a new {@link ThreadPoolTaskExecutor} with recorded metrics.
*
* @param registry The registry to bind metrics to.
* @param name The name prefix of the metrics.
* @param tags Tags to apply to all recorded metrics.
* @return The instrumented executor, proxied.
*/
public static Executor monitor(MeterRegistry registry, String name, Tag... tags) {
return monitor(registry, name, Arrays.asList(tags));
}

private final ThreadPoolTaskExecutor executor;
private final String name;
private final Iterable<Tag> tags;

public ThreadPoolTaskExecutorMetrics(ThreadPoolTaskExecutor executor, String name,
Iterable<Tag> tags) {
this.name = name;
this.tags = tags;
this.executor = executor;
}

@Override
public void bindTo(MeterRegistry registry) {
if (this.executor == null) {
return;
}
monitor(registry, this.executor.getThreadPoolExecutor());
}

private void monitor(MeterRegistry registry, ThreadPoolExecutor tp) {
FunctionCounter
.builder(this.name + ".completed", tp,
ThreadPoolExecutor::getCompletedTaskCount)
.tags(this.tags)
.description(
"The approximate total number of tasks that have completed execution")
.register(registry);

Gauge.builder(this.name + ".active", tp, ThreadPoolExecutor::getActiveCount)
.tags(this.tags)
.description(
"The approximate number of threads that are actively executing tasks")
.register(registry);

Gauge.builder(this.name + ".queued", tp, tpRef -> tpRef.getQueue().size())
.tags(this.tags)
.description(
"The approximate number of threads that are queued for execution")
.register(registry);

Gauge.builder(this.name + ".pool", tp, ThreadPoolExecutor::getPoolSize)
.tags(this.tags).description("The current number of threads in the pool")
.register(registry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2012-2017 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
*
* 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.springframework.boot.actuate.metrics.async;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;

/**
* A {@link ThreadPoolTaskExecutor} which is timed.
*
* @author David Held
*/
public class TimedThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
private final MeterRegistry registry;
private final String name;
private final Iterable<Tag> tags;
private final Timer timer;

public TimedThreadPoolTaskExecutor(MeterRegistry registry, String name,
Iterable<Tag> tags) {
this.registry = registry;
this.name = name;
this.tags = tags;
this.timer = registry.timer(name, tags);
}

@Override
public void initialize() {
super.initialize();
new ThreadPoolTaskExecutorMetrics(this, this.name, this.tags)
.bindTo(this.registry);
}

@Override
public void execute(Runnable task) {
super.execute(this.timer.wrap(task));
}

@Override
public void execute(Runnable task, long startTimeout) {
super.execute(this.timer.wrap(task), startTimeout);
}

@Override
public <T> Future<T> submit(Callable<T> task) {
return super.submit(this.timer.wrap(task));
}

@Override
public Future<?> submit(Runnable task) {
return super.submit(this.timer.wrap(task));
}

@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
return super.submitListenable(this.timer.wrap(task));
}

@Override
public ListenableFuture<?> submitListenable(Runnable task) {
return super.submitListenable(this.timer.wrap(task));
}
}
Loading