INT-4423: Make Micrometer dependency optional
JIRA: https://jira.spring.io/browse/INT-4423 Add a facade on top of micrometer so the dependency can be optional.t Next iteration - PR comments Checkstyle More polishing; static classes etc. checkstyle Further polishing; docs; auto-register `MicrometerMetricsCaptor`. Polishing - move captor load to a static method on the captor. * Fix Checkstyle violation * Some code style polishing
This commit is contained in:
committed by
Artem Bilan
parent
a92933e800
commit
6718d8d433
@@ -331,7 +331,7 @@ project('spring-integration-core') {
|
||||
}
|
||||
compile("io.fastjson:boon:$boonVersion", optional)
|
||||
compile("com.esotericsoftware:kryo-shaded:$kryoShadedVersion", optional)
|
||||
compile "io.micrometer:micrometer-core:$micrometerVersion"
|
||||
compile("io.micrometer:micrometer-core:$micrometerVersion", optional)
|
||||
|
||||
testCompile ("org.aspectj:aspectjweaver:$aspectjVersion")
|
||||
testCompile "io.projectreactor:reactor-test:$reactorVersion"
|
||||
|
||||
@@ -36,8 +36,11 @@ import org.springframework.integration.support.management.ConfigurableMetricsAwa
|
||||
import org.springframework.integration.support.management.DefaultMessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.IntegrationManagedResource;
|
||||
import org.springframework.integration.support.management.MessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.support.management.MetricsContext;
|
||||
import org.springframework.integration.support.management.SampleFacade;
|
||||
import org.springframework.integration.support.management.Statistics;
|
||||
import org.springframework.integration.support.management.TimerFacade;
|
||||
import org.springframework.integration.support.management.TrackableComponent;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -48,10 +51,6 @@ import org.springframework.messaging.support.ChannelInterceptor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.Timer.Sample;
|
||||
|
||||
/**
|
||||
* Base class for {@link MessageChannel} implementations providing common
|
||||
* properties such as the channel name. Also provides the common functionality
|
||||
@@ -90,11 +89,11 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
|
||||
private volatile AbstractMessageChannelMetrics channelMetrics = new DefaultMessageChannelMetrics();
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
private MetricsCaptor metricsCaptor;
|
||||
|
||||
private Timer successTimer;
|
||||
private TimerFacade successTimer;
|
||||
|
||||
private Timer failureTimer;
|
||||
private TimerFacade failureTimer;
|
||||
|
||||
public AbstractMessageChannel() {
|
||||
this.interceptors = new ChannelInterceptorList(logger);
|
||||
@@ -111,12 +110,12 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMeterRegistry(MeterRegistry registry) {
|
||||
this.meterRegistry = registry;
|
||||
public void registerMetricsCaptor(MetricsCaptor metricsCaptor) {
|
||||
this.metricsCaptor = metricsCaptor;
|
||||
}
|
||||
|
||||
protected MeterRegistry getMeterRegistry() {
|
||||
return this.meterRegistry;
|
||||
protected MetricsCaptor getMetricsCaptor() {
|
||||
return this.metricsCaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -422,7 +421,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
boolean countsEnabled = this.countsEnabled;
|
||||
ChannelInterceptorList interceptors = this.interceptors;
|
||||
AbstractMessageChannelMetrics channelMetrics = this.channelMetrics;
|
||||
Sample sample = null;
|
||||
SampleFacade sample = null;
|
||||
try {
|
||||
if (this.datatypes.length > 0) {
|
||||
message = this.convertPayloadIfNecessary(message);
|
||||
@@ -440,8 +439,8 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
if (countsEnabled) {
|
||||
metrics = channelMetrics.beforeSend();
|
||||
if (this.meterRegistry != null) {
|
||||
sample = Timer.start(this.meterRegistry);
|
||||
if (this.metricsCaptor != null) {
|
||||
sample = this.metricsCaptor.start();
|
||||
}
|
||||
sent = doSend(message, timeout);
|
||||
if (sample != null) {
|
||||
@@ -478,7 +477,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
}
|
||||
|
||||
private Timer sendTimer(boolean sent) {
|
||||
private TimerFacade sendTimer(boolean sent) {
|
||||
if (sent) {
|
||||
if (this.successTimer == null) {
|
||||
this.successTimer = buildSendTimer(true, "none");
|
||||
@@ -493,14 +492,14 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
}
|
||||
|
||||
private Timer buildSendTimer(boolean success, String exception) {
|
||||
return Timer.builder(SEND_TIMER_NAME)
|
||||
private TimerFacade buildSendTimer(boolean success, String exception) {
|
||||
return this.metricsCaptor.timerBuilder(SEND_TIMER_NAME)
|
||||
.tag("type", "channel")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", success ? "success" : "failure")
|
||||
.tag("exception", exception)
|
||||
.description("Send processing time")
|
||||
.register(this.meterRegistry);
|
||||
.build();
|
||||
}
|
||||
|
||||
private Message<?> convertPayloadIfNecessary(Message<?> message) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.integration.support.management.CounterFacade;
|
||||
import org.springframework.integration.support.management.PollableChannelManagement;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
@@ -27,8 +28,6 @@ import org.springframework.messaging.support.ChannelInterceptor;
|
||||
import org.springframework.messaging.support.ExecutorChannelInterceptor;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
|
||||
/**
|
||||
* Base class for all pollable channels.
|
||||
*
|
||||
@@ -42,7 +41,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
|
||||
private volatile int executorInterceptorsSize;
|
||||
|
||||
private Counter receiveCounter;
|
||||
private CounterFacade receiveCounter;
|
||||
|
||||
@Override
|
||||
public int getReceiveCount() {
|
||||
@@ -108,7 +107,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
}
|
||||
Message<?> message = this.doReceive(timeout);
|
||||
if (countsEnabled && message != null) {
|
||||
if (getMeterRegistry() != null) {
|
||||
if (getMetricsCaptor() != null) {
|
||||
incrementReceiveCounter();
|
||||
}
|
||||
getMetrics().afterReceive();
|
||||
@@ -128,14 +127,14 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (countsEnabled && !counted) {
|
||||
if (getMeterRegistry() != null) {
|
||||
Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
if (getMetricsCaptor() != null) {
|
||||
getMetricsCaptor().counterBuilder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("type", "channel")
|
||||
.tag("result", "failure")
|
||||
.tag("exception", e.getClass().getSimpleName())
|
||||
.description("Messages received")
|
||||
.register(getMeterRegistry())
|
||||
.build()
|
||||
.increment();
|
||||
}
|
||||
getMetrics().afterError();
|
||||
@@ -149,13 +148,13 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
|
||||
private void incrementReceiveCounter() {
|
||||
if (this.receiveCounter == null) {
|
||||
this.receiveCounter = Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
this.receiveCounter = getMetricsCaptor().counterBuilder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName())
|
||||
.tag("type", "channel")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(getMeterRegistry());
|
||||
.build();
|
||||
}
|
||||
this.receiveCounter.increment();
|
||||
}
|
||||
|
||||
@@ -28,15 +28,14 @@ import org.springframework.integration.support.management.ConfigurableMetricsAwa
|
||||
import org.springframework.integration.support.management.DefaultMessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.IntegrationManagedResource;
|
||||
import org.springframework.integration.support.management.MessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.support.management.Statistics;
|
||||
import org.springframework.integration.support.management.TimerFacade;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* A channel implementation that essentially behaves like "/dev/null".
|
||||
* All receive() calls will return <em>null</em>, and all send() calls
|
||||
@@ -65,9 +64,9 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
|
||||
private String beanName;
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
private MetricsCaptor metricsCaptor;
|
||||
|
||||
private Timer successTimer;
|
||||
private TimerFacade successTimer;
|
||||
|
||||
@Override
|
||||
public void setBeanName(String beanName) {
|
||||
@@ -97,8 +96,8 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMeterRegistry(MeterRegistry registry) {
|
||||
this.meterRegistry = registry;
|
||||
public void registerMetricsCaptor(MetricsCaptor registry) {
|
||||
this.metricsCaptor = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -235,7 +234,7 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
this.logger.debug("message sent to null channel: " + message);
|
||||
}
|
||||
if (this.countsEnabled) {
|
||||
if (this.meterRegistry != null) {
|
||||
if (this.metricsCaptor != null) {
|
||||
sendTimer().record(0, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
this.channelMetrics.afterSend(this.channelMetrics.beforeSend(), true);
|
||||
@@ -243,15 +242,15 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
return true;
|
||||
}
|
||||
|
||||
private Timer sendTimer() {
|
||||
private TimerFacade sendTimer() {
|
||||
if (this.successTimer == null) {
|
||||
this.successTimer = Timer.builder(SEND_TIMER_NAME)
|
||||
this.successTimer = this.metricsCaptor.timerBuilder(SEND_TIMER_NAME)
|
||||
.tag("type", "channel")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Subflow process time")
|
||||
.register(this.meterRegistry);
|
||||
.build();
|
||||
}
|
||||
return this.successTimer;
|
||||
}
|
||||
|
||||
@@ -26,16 +26,15 @@ import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
|
||||
import org.springframework.integration.support.context.NamedComponent;
|
||||
import org.springframework.integration.support.management.CounterFacade;
|
||||
import org.springframework.integration.support.management.IntegrationManagedResource;
|
||||
import org.springframework.integration.support.management.MessageSourceMetrics;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.util.AbstractExpressionEvaluator;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
@@ -64,9 +63,9 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
|
||||
private volatile boolean loggingEnabled = true;
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
private MetricsCaptor metricsCaptor;
|
||||
|
||||
private Counter receiveCounter;
|
||||
private CounterFacade receiveCounter;
|
||||
|
||||
public void setHeaderExpressions(Map<String, Expression> headerExpressions) {
|
||||
this.headerExpressions = (headerExpressions != null)
|
||||
@@ -74,8 +73,8 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMeterRegistry(MeterRegistry registry) {
|
||||
this.meterRegistry = registry;
|
||||
public void registerMetricsCaptor(MetricsCaptor metricsCaptor) {
|
||||
this.metricsCaptor = metricsCaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,7 +193,7 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
.build();
|
||||
}
|
||||
if (this.countsEnabled && message != null) {
|
||||
if (this.meterRegistry != null) {
|
||||
if (this.metricsCaptor != null) {
|
||||
incrementReceiveCounter();
|
||||
}
|
||||
this.messageCount.incrementAndGet();
|
||||
@@ -204,13 +203,13 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
|
||||
private void incrementReceiveCounter() {
|
||||
if (this.receiveCounter == null) {
|
||||
this.receiveCounter = Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
this.receiveCounter = this.metricsCaptor.counterBuilder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("type", "source")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(this.meterRegistry);
|
||||
.build();
|
||||
}
|
||||
this.receiveCounter.increment();
|
||||
}
|
||||
|
||||
@@ -27,8 +27,11 @@ import org.springframework.integration.support.management.ConfigurableMetricsAwa
|
||||
import org.springframework.integration.support.management.DefaultMessageHandlerMetrics;
|
||||
import org.springframework.integration.support.management.IntegrationManagedResource;
|
||||
import org.springframework.integration.support.management.MessageHandlerMetrics;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.support.management.MetricsContext;
|
||||
import org.springframework.integration.support.management.SampleFacade;
|
||||
import org.springframework.integration.support.management.Statistics;
|
||||
import org.springframework.integration.support.management.TimerFacade;
|
||||
import org.springframework.integration.support.management.TrackableComponent;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -36,9 +39,6 @@ import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.Timer.Sample;
|
||||
import reactor.core.CoreSubscriber;
|
||||
|
||||
/**
|
||||
@@ -75,9 +75,9 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport
|
||||
|
||||
private volatile boolean loggingEnabled = true;
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
private MetricsCaptor metricsCaptor;
|
||||
|
||||
private Timer successTimer;
|
||||
private TimerFacade successTimer;
|
||||
|
||||
@Override
|
||||
public boolean isLoggingEnabled() {
|
||||
@@ -90,9 +90,10 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport
|
||||
this.managementOverrides.loggingConfigured = true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void registerMeterRegistry(MeterRegistry meterRegistry) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
public void registerMetricsCaptor(MetricsCaptor metricsCaptor) {
|
||||
this.metricsCaptor = metricsCaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,9 +145,9 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport
|
||||
MetricsContext start = null;
|
||||
boolean countsEnabled = this.countsEnabled;
|
||||
AbstractMessageHandlerMetrics handlerMetrics = this.handlerMetrics;
|
||||
Sample sample = null;
|
||||
if (countsEnabled && this.meterRegistry != null) {
|
||||
sample = Timer.start(this.meterRegistry);
|
||||
SampleFacade sample = null;
|
||||
if (countsEnabled && this.metricsCaptor != null) {
|
||||
sample = this.metricsCaptor.start();
|
||||
}
|
||||
try {
|
||||
if (this.shouldTrack) {
|
||||
@@ -176,21 +177,21 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport
|
||||
}
|
||||
}
|
||||
|
||||
private Timer sendTimer() {
|
||||
private TimerFacade sendTimer() {
|
||||
if (this.successTimer == null) {
|
||||
this.successTimer = buildSendTimer(true, "none");
|
||||
}
|
||||
return this.successTimer;
|
||||
}
|
||||
|
||||
private Timer buildSendTimer(boolean success, String exception) {
|
||||
return Timer.builder(SEND_TIMER_NAME)
|
||||
private TimerFacade buildSendTimer(boolean success, String exception) {
|
||||
return this.metricsCaptor.timerBuilder(SEND_TIMER_NAME)
|
||||
.tag("type", "handler")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", success ? "success" : "failure")
|
||||
.tag("exception", exception)
|
||||
.description("Send processing time")
|
||||
.register(this.meterRegistry);
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,12 +19,6 @@ package org.springframework.integration.support.management;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* Abstract base class for channel metrics implementations.
|
||||
*
|
||||
@@ -39,14 +33,6 @@ public abstract class AbstractMessageChannelMetrics implements ConfigurableMetri
|
||||
|
||||
protected final String name;
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
private final Counter errorCounter;
|
||||
|
||||
private final Counter receiveCounter;
|
||||
|
||||
private final Counter receiveErrorCounter;
|
||||
|
||||
private volatile boolean fullStatsEnabled;
|
||||
|
||||
/**
|
||||
@@ -54,32 +40,7 @@ public abstract class AbstractMessageChannelMetrics implements ConfigurableMetri
|
||||
* @param name the name.
|
||||
*/
|
||||
public AbstractMessageChannelMetrics(String name) {
|
||||
this(name, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the provided name, timer, error counter, receive counter
|
||||
* and receive error counter.
|
||||
* A non-null timer requires a non-null error counter. When a timer is provided,
|
||||
* Micrometer metrics are used and the legacy metrics are not maintained.
|
||||
* @param name the name.
|
||||
* @param timer the timer.
|
||||
* @param errorCounter the error counter.
|
||||
* @param receiveCounter the receive counter.
|
||||
* @param receiveErrorCounter the receive error counter.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public AbstractMessageChannelMetrics(String name, Timer timer, Counter errorCounter, Counter receiveCounter,
|
||||
Counter receiveErrorCounter) {
|
||||
|
||||
if (timer != null) {
|
||||
Assert.notNull(errorCounter, "'errorCounter' cannot be null if a timer is provided");
|
||||
}
|
||||
this.name = name;
|
||||
this.timer = timer;
|
||||
this.errorCounter = errorCounter;
|
||||
this.receiveCounter = receiveCounter;
|
||||
this.receiveErrorCounter = receiveErrorCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,46 +77,6 @@ public abstract class AbstractMessageChannelMetrics implements ConfigurableMetri
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
/**
|
||||
* Return the timer if Micrometer metrics are being used.
|
||||
* @return the timer, or null to indicate Micrometer is not being used.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
@Nullable
|
||||
public Timer getTimer() {
|
||||
return this.timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the error counter if Micrometer metrics are being used.
|
||||
* @return the counter or null if Micrometer is not being used.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
@Nullable
|
||||
public Counter getErrorCounter() {
|
||||
return this.errorCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the receive counter if Micrometer metrics are being used.
|
||||
* @return the counter or null if Micrometer is not being used.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
@Nullable
|
||||
public Counter getReceiveCounter() {
|
||||
return this.receiveCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the receive error counter if Micrometer metrics are being used.
|
||||
* @return the counter or null if Micrometer is not being used.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
@Nullable
|
||||
public Counter getReceiveErrorCounter() {
|
||||
return this.receiveErrorCounter;
|
||||
}
|
||||
|
||||
public abstract int getSendCount();
|
||||
|
||||
public abstract long getSendCountLong();
|
||||
|
||||
@@ -19,9 +19,6 @@ package org.springframework.integration.support.management;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* Abstract base class for handler metrics implementations.
|
||||
*
|
||||
@@ -35,20 +32,10 @@ public abstract class AbstractMessageHandlerMetrics implements ConfigurableMetri
|
||||
|
||||
protected final String name;
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
private final Counter errorCounter;
|
||||
|
||||
private volatile boolean fullStatsEnabled;
|
||||
|
||||
public AbstractMessageHandlerMetrics(String name) {
|
||||
this(name, null, null);
|
||||
}
|
||||
|
||||
public AbstractMessageHandlerMetrics(String name, Timer timer, Counter errorCounter) {
|
||||
this.name = name;
|
||||
this.timer = timer;
|
||||
this.errorCounter = errorCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,14 +66,6 @@ public abstract class AbstractMessageHandlerMetrics implements ConfigurableMetri
|
||||
|
||||
public abstract void reset();
|
||||
|
||||
public Timer getTimer() {
|
||||
return this.timer;
|
||||
}
|
||||
|
||||
public Counter getErrorCounter() {
|
||||
return this.errorCounter;
|
||||
}
|
||||
|
||||
public abstract long getHandleCountLong();
|
||||
|
||||
public abstract int getHandleCount();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public interface CounterFacade {
|
||||
|
||||
void increment();
|
||||
|
||||
}
|
||||
@@ -18,9 +18,6 @@ package org.springframework.integration.support.management;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* Default implementation; use the full constructor to customize the moving averages.
|
||||
*
|
||||
@@ -65,30 +62,13 @@ public class DefaultMessageChannelMetrics extends AbstractMessageChannelMetrics
|
||||
* @param name the name.
|
||||
*/
|
||||
public DefaultMessageChannelMetrics(String name) {
|
||||
this(name, null, null, null, (Counter) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with default metrics with {@code window=10, period=1 second,
|
||||
* lapsePeriod=1 minute}.
|
||||
* @param name the name.
|
||||
* @param timer a timer.
|
||||
* @param errorCounter a counter.
|
||||
* @param receiveCounter a counter for receives.
|
||||
* @param receiveErrorCounter a counter for receive errors.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public DefaultMessageChannelMetrics(String name, Timer timer, Counter errorCounter, Counter receiveCounter,
|
||||
Counter receiveErrorCounter) {
|
||||
|
||||
this(name, new ExponentialMovingAverage(DEFAULT_MOVING_AVERAGE_WINDOW, 1000000.),
|
||||
new ExponentialMovingAverageRate(
|
||||
ONE_SECOND_SECONDS, ONE_MINUTE_SECONDS, DEFAULT_MOVING_AVERAGE_WINDOW, true),
|
||||
new ExponentialMovingAverageRatio(
|
||||
ONE_MINUTE_SECONDS, DEFAULT_MOVING_AVERAGE_WINDOW, true),
|
||||
new ExponentialMovingAverageRate(
|
||||
ONE_SECOND_SECONDS, ONE_MINUTE_SECONDS, DEFAULT_MOVING_AVERAGE_WINDOW, true),
|
||||
timer, errorCounter, receiveCounter, receiveErrorCounter);
|
||||
ONE_SECOND_SECONDS, ONE_MINUTE_SECONDS, DEFAULT_MOVING_AVERAGE_WINDOW, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,30 +86,7 @@ public class DefaultMessageChannelMetrics extends AbstractMessageChannelMetrics
|
||||
ExponentialMovingAverageRate sendErrorRate, ExponentialMovingAverageRatio sendSuccessRatio,
|
||||
ExponentialMovingAverageRate sendRate) {
|
||||
|
||||
this(name, sendDuration, sendErrorRate, sendSuccessRatio, sendRate, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied metrics. For proper representation of metrics, the
|
||||
* supplied sendDuration must have a {@code factor=1000000.} and the the other arguments
|
||||
* must be created with the {@code millis} constructor argument set to true.
|
||||
* @param name the name.
|
||||
* @param sendDuration an {@link ExponentialMovingAverage} for calculating the send duration.
|
||||
* @param sendErrorRate an {@link ExponentialMovingAverageRate} for calculating the send error rate.
|
||||
* @param sendSuccessRatio an {@link ExponentialMovingAverageRatio} for calculating the success ratio.
|
||||
* @param sendRate an {@link ExponentialMovingAverageRate} for calculating the send rate.
|
||||
* @param timer a timer.
|
||||
* @param errorCounter a counter for sends.
|
||||
* @param receiveCounter a counter for receives.
|
||||
* @param receiveErrorCounter a counter for receive errors.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public DefaultMessageChannelMetrics(String name, ExponentialMovingAverage sendDuration,
|
||||
ExponentialMovingAverageRate sendErrorRate, ExponentialMovingAverageRatio sendSuccessRatio,
|
||||
ExponentialMovingAverageRate sendRate, Timer timer, Counter errorCounter, Counter receiveCounter,
|
||||
Counter receiveErrorCounter) {
|
||||
|
||||
super(name, timer, errorCounter, receiveCounter, receiveErrorCounter);
|
||||
super(name);
|
||||
this.sendDuration = sendDuration;
|
||||
this.sendErrorRate = sendErrorRate;
|
||||
this.sendSuccessRatio = sendSuccessRatio;
|
||||
@@ -261,22 +218,12 @@ public class DefaultMessageChannelMetrics extends AbstractMessageChannelMetrics
|
||||
|
||||
@Override
|
||||
public void afterReceive() {
|
||||
if (getReceiveCounter() != null) {
|
||||
getReceiveCounter().increment();
|
||||
}
|
||||
else {
|
||||
this.receiveCount.incrementAndGet();
|
||||
}
|
||||
this.receiveCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterError() {
|
||||
if (getReceiveErrorCounter() != null) {
|
||||
getReceiveErrorCounter().increment();
|
||||
}
|
||||
else {
|
||||
this.receiveErrorCount.incrementAndGet();
|
||||
}
|
||||
this.receiveErrorCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,9 +18,6 @@ package org.springframework.integration.support.management;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* Default implementation; use the full constructor to customize the moving averages.
|
||||
*
|
||||
@@ -50,19 +47,7 @@ public class DefaultMessageHandlerMetrics extends AbstractMessageHandlerMetrics
|
||||
* @param name the name.
|
||||
*/
|
||||
public DefaultMessageHandlerMetrics(String name) {
|
||||
this(name, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the default moving average window (10).
|
||||
* @param name the name.
|
||||
* @param timer a timer.
|
||||
* @param errorCounter a counter.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public DefaultMessageHandlerMetrics(String name, Timer timer, Counter errorCounter) {
|
||||
this(name, new ExponentialMovingAverage(DEFAULT_MOVING_AVERAGE_WINDOW, 1000000.), timer,
|
||||
errorCounter);
|
||||
this(name, new ExponentialMovingAverage(DEFAULT_MOVING_AVERAGE_WINDOW, 1000000.));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,22 +59,7 @@ public class DefaultMessageHandlerMetrics extends AbstractMessageHandlerMetrics
|
||||
* @since 4.2
|
||||
*/
|
||||
public DefaultMessageHandlerMetrics(String name, ExponentialMovingAverage duration) {
|
||||
this(name, duration, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied {@link ExponentialMovingAverage} calculating
|
||||
* the duration of processing by the message handler (and any downstream synchronous
|
||||
* endpoints).
|
||||
* @param name the name.
|
||||
* @param duration an {@link ExponentialMovingAverage} for calculating the duration.
|
||||
* @param timer a timer.
|
||||
* @param errorCounter a counter.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public DefaultMessageHandlerMetrics(String name, ExponentialMovingAverage duration, Timer timer,
|
||||
Counter errorCounter) {
|
||||
super(name, timer, errorCounter);
|
||||
super(name);
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public interface GaugeFacade {
|
||||
|
||||
}
|
||||
@@ -19,8 +19,6 @@ package org.springframework.integration.support.management;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
/**
|
||||
* Base interface for Integration managed components.
|
||||
*
|
||||
@@ -59,11 +57,11 @@ public interface IntegrationManagement {
|
||||
ManagementOverrides getOverrides();
|
||||
|
||||
/**
|
||||
* Inject a micrometer {@link MeterRegistry}
|
||||
* @param registry the registry.
|
||||
* @since 5.0.3
|
||||
* Inject a {@link MetricsCaptor}
|
||||
* @param captor the captor.
|
||||
* @since 5.0.4
|
||||
*/
|
||||
default void registerMeterRegistry(MeterRegistry registry) {
|
||||
default void registerMetricsCaptor(MetricsCaptor captor) {
|
||||
// no op
|
||||
}
|
||||
|
||||
|
||||
@@ -26,22 +26,20 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.support.management.IntegrationManagement.ManagementOverrides;
|
||||
import org.springframework.integration.support.management.micrometer.MicrometerMetricsCaptor;
|
||||
import org.springframework.integration.util.PatternMatchUtils;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* Configures beans that implement {@link IntegrationManagement}.
|
||||
@@ -61,11 +59,11 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
|
||||
public static final String MANAGEMENT_CONFIGURER_NAME = "integrationManagementConfigurer";
|
||||
|
||||
private final Map<String, MessageChannelMetrics> channelsByName = new HashMap<String, MessageChannelMetrics>();
|
||||
private final Map<String, MessageChannelMetrics> channelsByName = new HashMap<>();
|
||||
|
||||
private final Map<String, MessageHandlerMetrics> handlersByName = new HashMap<String, MessageHandlerMetrics>();
|
||||
private final Map<String, MessageHandlerMetrics> handlersByName = new HashMap<>();
|
||||
|
||||
private final Map<String, MessageSourceMetrics> sourcesByName = new HashMap<String, MessageSourceMetrics>();
|
||||
private final Map<String, MessageSourceMetrics> sourcesByName = new HashMap<>();
|
||||
|
||||
private final Map<String, MessageSourceMetricsConfigurer> sourceConfigurers = new HashMap<>();
|
||||
|
||||
@@ -89,7 +87,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
|
||||
private volatile boolean singletonsInstantiated;
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
private MetricsCaptor metricsCaptor;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
@@ -214,15 +212,13 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
Assert.state(this.applicationContext != null, "'applicationContext' must not be null");
|
||||
Assert.state(MANAGEMENT_CONFIGURER_NAME.equals(this.beanName), getClass().getSimpleName()
|
||||
+ " bean name must be " + MANAGEMENT_CONFIGURER_NAME);
|
||||
try {
|
||||
this.meterRegistry = this.applicationContext.getBean(MeterRegistry.class);
|
||||
if (ClassUtils.isPresent("io.micrometer.core.instrument.MeterRegistry",
|
||||
IntegrationManagementConfigurer.class.getClassLoader())) {
|
||||
this.metricsCaptor = MicrometerMetricsCaptor.loadCaptor(this.applicationContext);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
// no op
|
||||
}
|
||||
if (this.meterRegistry != null) {
|
||||
injectRegistry(this.meterRegistry);
|
||||
registerComponentGauges(this.meterRegistry);
|
||||
if (this.metricsCaptor != null) {
|
||||
injectCaptor();
|
||||
registerComponentGauges();
|
||||
}
|
||||
if (this.metricsFactory == null && StringUtils.hasText(this.metricsFactoryBeanName)) {
|
||||
this.metricsFactory = this.applicationContext.getBean(this.metricsFactoryBeanName, MetricsFactory.class);
|
||||
@@ -249,17 +245,14 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
this.singletonsInstantiated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registry
|
||||
*/
|
||||
private void injectRegistry(MeterRegistry registry) {
|
||||
private void injectCaptor() {
|
||||
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
|
||||
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
|
||||
IntegrationManagement bean = entry.getValue();
|
||||
if (!bean.getOverrides().loggingConfigured) {
|
||||
bean.setLoggingEnabled(this.defaultLoggingEnabled);
|
||||
}
|
||||
bean.registerMeterRegistry(registry);
|
||||
bean.registerMetricsCaptor(this.metricsCaptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +260,7 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (this.singletonsInstantiated) {
|
||||
if (bean instanceof IntegrationManagement) {
|
||||
((IntegrationManagement) bean).registerMeterRegistry(this.meterRegistry);
|
||||
((IntegrationManagement) bean).registerMetricsCaptor(this.metricsCaptor);
|
||||
}
|
||||
return doConfigureMetrics(bean, beanName);
|
||||
}
|
||||
@@ -370,21 +363,21 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
|
||||
this.sourcesByName.put(bean.getManagedName() != null ? bean.getManagedName() : name, bean);
|
||||
}
|
||||
|
||||
private void registerComponentGauges(MeterRegistry meterRegistry) {
|
||||
Gauge.builder("spring.integration.channels", this,
|
||||
private void registerComponentGauges() {
|
||||
this.metricsCaptor.gaugeBuilder("spring.integration.channels", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageChannel.class).size())
|
||||
.description("The number of message channels")
|
||||
.register(meterRegistry);
|
||||
.build();
|
||||
|
||||
Gauge.builder("spring.integration.handlers", this,
|
||||
this.metricsCaptor.gaugeBuilder("spring.integration.handlers", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageHandler.class).size())
|
||||
.description("The number of message handlers")
|
||||
.register(meterRegistry);
|
||||
.build();
|
||||
|
||||
Gauge.builder("spring.integration.sources", this,
|
||||
this.metricsCaptor.gaugeBuilder("spring.integration.sources", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageSource.class).size())
|
||||
.description("The number of message sources")
|
||||
.register(meterRegistry);
|
||||
.build();
|
||||
}
|
||||
|
||||
public String[] getChannelNames() {
|
||||
|
||||
@@ -18,9 +18,6 @@ package org.springframework.integration.support.management;
|
||||
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
|
||||
/**
|
||||
* Base interface containing methods to control complete statistics gathering.
|
||||
@@ -37,22 +34,4 @@ public interface IntegrationStatsManagement extends IntegrationManagement {
|
||||
@ManagedAttribute
|
||||
boolean isStatsEnabled();
|
||||
|
||||
/**
|
||||
* Set a micrometer timer to time operations.
|
||||
* @param timer the timer.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
default void setTimer(Timer timer) {
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a micrometer counter to count errors.
|
||||
* @param counter the counter.
|
||||
* @since 5.0.2
|
||||
*/
|
||||
default void setErrorCounter(Counter counter) {
|
||||
// no op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,9 +20,6 @@ import org.springframework.context.Lifecycle;
|
||||
import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* A {@link MessageHandlerMetrics} that exposes in addition the {@link Lifecycle} interface. The lifecycle methods can
|
||||
* be used to stop and start polling endpoints, for instance, in a live system.
|
||||
@@ -190,14 +187,4 @@ public class LifecycleMessageHandlerMetrics implements MessageHandlerMetrics, Li
|
||||
return this.delegate.getOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimer(Timer timer) {
|
||||
this.delegate.setTimer(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorCounter(Counter counter) {
|
||||
this.delegate.setErrorCounter(counter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.springframework.integration.support.management;
|
||||
import org.springframework.jmx.export.annotation.ManagedMetric;
|
||||
import org.springframework.jmx.support.MetricType;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Gary Russell
|
||||
@@ -59,7 +57,7 @@ public interface MessageSourceMetrics extends IntegrationManagement {
|
||||
* Will be remove in the next release.
|
||||
*/
|
||||
@Deprecated
|
||||
default void setCounter(Counter counter) {
|
||||
default void setCounter(CounterFacade counter) {
|
||||
// no op
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management;
|
||||
|
||||
import java.util.function.ToDoubleFunction;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A metrics facade that delegates to a concrete implementation.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public interface MetricsCaptor {
|
||||
|
||||
/**
|
||||
* Create a timer builder for a timer with the provided name.
|
||||
* @param name the name.
|
||||
* @return the builder.
|
||||
*/
|
||||
TimerBuilder timerBuilder(String name);
|
||||
|
||||
/**
|
||||
* Create a counter builder for a counter with the provided name.
|
||||
* @param name the name.
|
||||
* @return the builder.
|
||||
*/
|
||||
CounterBuilder counterBuilder(String name);
|
||||
|
||||
/**
|
||||
* Create a gauge builder for a gauge with the provided parameters.
|
||||
* @param name the name.
|
||||
* @param obj the object with which to invoke the function.
|
||||
* @param f the function.
|
||||
* @return the builder.
|
||||
*/
|
||||
GaugeBuilder gaugeBuilder(String name, @Nullable Object obj, ToDoubleFunction<Object> f);
|
||||
|
||||
/**
|
||||
* Start a sample collection.
|
||||
* @return the sample.
|
||||
*/
|
||||
SampleFacade start();
|
||||
|
||||
/**
|
||||
* A builder for a timer.
|
||||
*/
|
||||
interface TimerBuilder {
|
||||
|
||||
/**
|
||||
* Add a tag.
|
||||
* @param key the key.
|
||||
* @param value the value.
|
||||
* @return the builder.
|
||||
*/
|
||||
TimerBuilder tag(String key, String value);
|
||||
|
||||
/**
|
||||
* Add the description.
|
||||
* @param desc the description.
|
||||
* @return the builder.
|
||||
*/
|
||||
TimerBuilder description(String desc);
|
||||
|
||||
/**
|
||||
* Build the timer.
|
||||
* @return the timer.
|
||||
*/
|
||||
TimerFacade build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a counter.
|
||||
*/
|
||||
interface CounterBuilder {
|
||||
|
||||
/**
|
||||
* Add a tag.
|
||||
* @param key the key.
|
||||
* @param value the value.
|
||||
* @return the builder.
|
||||
*/
|
||||
CounterBuilder tag(String key, String value);
|
||||
|
||||
/**
|
||||
* Add the description.
|
||||
* @param desc the description.
|
||||
* @return the builder.
|
||||
*/
|
||||
CounterBuilder description(String desc);
|
||||
|
||||
/**
|
||||
* Build the counter.
|
||||
* @return the counter.
|
||||
*/
|
||||
CounterFacade build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for a gauge.
|
||||
*/
|
||||
interface GaugeBuilder {
|
||||
|
||||
/**
|
||||
* Add a tag.
|
||||
* @param key the key.
|
||||
* @param value the value.
|
||||
* @return the builder.
|
||||
*/
|
||||
GaugeBuilder tag(String key, String value);
|
||||
|
||||
/**
|
||||
* Add the description.
|
||||
* @param desc the description.
|
||||
* @return the builder.
|
||||
*/
|
||||
GaugeBuilder description(String desc);
|
||||
|
||||
/**
|
||||
* Build the gauge.
|
||||
* @return the gauge.
|
||||
*/
|
||||
GaugeFacade build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public interface SampleFacade {
|
||||
|
||||
void stop(TimerFacade timer);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public interface TimerFacade {
|
||||
|
||||
void record(long time, TimeUnit unit);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright 2018 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.integration.support.management.micrometer;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.integration.support.management.CounterFacade;
|
||||
import org.springframework.integration.support.management.GaugeFacade;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.support.management.SampleFacade;
|
||||
import org.springframework.integration.support.management.TimerFacade;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
|
||||
/**
|
||||
* The Micrometer implementation of {@link MetricsCaptor}.
|
||||
*
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 5.0.4
|
||||
*
|
||||
*/
|
||||
public class MicrometerMetricsCaptor implements MetricsCaptor {
|
||||
|
||||
public static final String MICROMETER_CAPTOR_NAME = "integrationMicrometerMetricsCaptor";
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
public MicrometerMetricsCaptor(MeterRegistry meterRegistry) {
|
||||
Assert.notNull(meterRegistry, "meterRegistry cannot be null");
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimerBuilder timerBuilder(String name) {
|
||||
return new MicroTimerBuilder(this.meterRegistry, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CounterBuilder counterBuilder(String name) {
|
||||
return new MicroCounterBuilder(this.meterRegistry, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaugeBuilder gaugeBuilder(String name, Object obj, ToDoubleFunction<Object> f) {
|
||||
return new MicroGaugeBuilder(this.meterRegistry, name, obj, f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SampleFacade start() {
|
||||
return new MicroSample(Timer.start(this.meterRegistry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a MicrometerMetricsCaptor to the context if there's a MeterRegistry.
|
||||
* @param applicationContext the application context.
|
||||
* @return the instance.
|
||||
*/
|
||||
public static MetricsCaptor loadCaptor(ApplicationContext applicationContext) {
|
||||
try {
|
||||
MeterRegistry registry = applicationContext.getBean(MeterRegistry.class);
|
||||
if (applicationContext instanceof GenericApplicationContext
|
||||
&& !applicationContext.containsBean(MICROMETER_CAPTOR_NAME)) {
|
||||
((GenericApplicationContext) applicationContext).registerBean(MICROMETER_CAPTOR_NAME,
|
||||
MicrometerMetricsCaptor.class,
|
||||
() -> new MicrometerMetricsCaptor(registry));
|
||||
return applicationContext.getBean(MicrometerMetricsCaptor.class);
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class MicroSample implements SampleFacade {
|
||||
|
||||
private final Timer.Sample sample;
|
||||
|
||||
MicroSample(Timer.Sample sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(TimerFacade timer) {
|
||||
this.sample.stop(((MicroTimer) timer).timer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroTimerBuilder implements TimerBuilder {
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
private final Timer.Builder builder;
|
||||
|
||||
MicroTimerBuilder(MeterRegistry meterRegistry, String name) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.builder = Timer.builder(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MicroTimerBuilder tag(String key, String value) {
|
||||
this.builder.tag(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MicroTimerBuilder description(String desc) {
|
||||
this.builder.description(desc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MicroTimer build() {
|
||||
return new MicroTimer(this.builder.register(this.meterRegistry));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroTimer implements TimerFacade {
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
MicroTimer(Timer timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(long time, TimeUnit unit) {
|
||||
this.timer.record(time, unit);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroCounterBuilder implements CounterBuilder {
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
private final Counter.Builder builder;
|
||||
|
||||
MicroCounterBuilder(MeterRegistry meterRegistry, String name) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.builder = Counter.builder(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CounterBuilder tag(String key, String value) {
|
||||
this.builder.tag(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CounterBuilder description(String desc) {
|
||||
this.builder.description(desc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CounterFacade build() {
|
||||
return new MicroCounter(this.builder.register(this.meterRegistry));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroCounter implements CounterFacade {
|
||||
|
||||
private final Counter counter;
|
||||
|
||||
MicroCounter(Counter counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment() {
|
||||
this.counter.increment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroGaugeBuilder implements GaugeBuilder {
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
private final Gauge.Builder<Object> builder;
|
||||
|
||||
MicroGaugeBuilder(MeterRegistry meterRegistry, String name, Object obj, ToDoubleFunction<Object> f) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.builder = Gauge.builder(name, obj, f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaugeBuilder tag(String key, String value) {
|
||||
this.builder.tag(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaugeBuilder description(String desc) {
|
||||
this.builder.description(desc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GaugeFacade build() {
|
||||
return new MicroGauge(this.builder.register(this.meterRegistry));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MicroGauge implements GaugeFacade {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Gauge gauge;
|
||||
|
||||
MicroGauge(Gauge gauge) {
|
||||
this.gauge = gauge;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,21 +22,16 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.support.management.AbstractMessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.AbstractMessageHandlerMetrics;
|
||||
import org.springframework.integration.support.management.DefaultMessageChannelMetrics;
|
||||
import org.springframework.integration.support.management.DefaultMessageHandlerMetrics;
|
||||
import org.springframework.integration.support.management.MessageSourceMetrics;
|
||||
import org.springframework.integration.support.management.MessageSourceMetricsConfigurer;
|
||||
import org.springframework.integration.support.management.MetricsCaptor;
|
||||
import org.springframework.integration.support.management.MetricsFactory;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import io.micrometer.core.instrument.Gauge;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
/**
|
||||
* Micrometer implementation of a {@link MetricsFactory}. Configures the resulting
|
||||
* channel, and handler metrics to use Micrometer metrics instead of the legacy Spring
|
||||
@@ -56,52 +51,20 @@ import io.micrometer.core.instrument.MeterRegistry;
|
||||
public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMetricsConfigurer,
|
||||
ApplicationContextAware, SmartInitializingSingleton {
|
||||
|
||||
private static final Function<String, String[]> NO_TAGS = n -> new String[0];
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private Function<String, String> timerNameProvider = n -> n + ".timer";
|
||||
|
||||
private Function<String, String> counterNameProvider = n -> n + ".counter";
|
||||
|
||||
private Function<String, String> errorCounterNameProvider = n -> n + ".errorCounter";
|
||||
|
||||
private Function<String, String> receiveCounterNameProvider = n -> n + ".receive.counter";
|
||||
|
||||
private Function<String, String> receiveErrorCounterNameProvider = n -> n + ".receive.errorCounter";
|
||||
|
||||
private Function<String, String[]> timerTagProvider = NO_TAGS;
|
||||
|
||||
private Function<String, String[]> counterTagProvider = NO_TAGS;
|
||||
|
||||
private Function<String, String[]> errorCounterTagProvider = NO_TAGS;
|
||||
|
||||
private Function<String, String[]> receiveCounterTagProvider = NO_TAGS;
|
||||
|
||||
private Function<String, String[]> receiveErrorCounterTagProvider = NO_TAGS;
|
||||
|
||||
private Function<String, String[]> componentCountTagProvider = NO_TAGS;
|
||||
|
||||
/**
|
||||
* Construct an instance with the provided {@link MeterRegistry}.
|
||||
* @param meterRegistry the registry.
|
||||
* Construct an instance with the provided {@link MetricsCaptor}.
|
||||
* @param captor the registry.
|
||||
*/
|
||||
public MicrometerMetricsFactory(MeterRegistry meterRegistry) {
|
||||
Assert.notNull(meterRegistry, "'meterRegistry' cannot be null");
|
||||
this.meterRegistry = meterRegistry;
|
||||
public MicrometerMetricsFactory(MetricsCaptor captor) {
|
||||
Assert.notNull(captor, "'meterRegistry' cannot be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
Assert.notNull(this.applicationContext, "An application context is required");
|
||||
registerComponentGauges();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +74,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setTimerNameProvider(Function<String, String> timerNameProvider) {
|
||||
Assert.notNull(timerNameProvider, "'timerNameProvider' cannot be null");
|
||||
this.timerNameProvider = timerNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +83,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setCounterNameProvider(Function<String, String> counterNameProvider) {
|
||||
Assert.notNull(counterNameProvider, "'counterNameProvider' cannot be null");
|
||||
this.counterNameProvider = counterNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +92,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setErrorCounterNameProvider(Function<String, String> errorCounterNameProvider) {
|
||||
Assert.notNull(errorCounterNameProvider, "'errorCounterNameProvider' cannot be null");
|
||||
this.errorCounterNameProvider = errorCounterNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +101,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setReceiveCounterNameProvider(Function<String, String> counterNameProvider) {
|
||||
Assert.notNull(counterNameProvider, "'counterNameProvider' cannot be null");
|
||||
this.receiveCounterNameProvider = counterNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +110,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setReceiveErrorCounterNameProvider(Function<String, String> errorCounterNameProvider) {
|
||||
Assert.notNull(errorCounterNameProvider, "'errorCounterNameProvider' cannot be null");
|
||||
this.receiveErrorCounterNameProvider = errorCounterNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +119,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setTimerTagProvider(Function<String, String[]> timerTagProvider) {
|
||||
Assert.notNull(timerTagProvider, "'timerTagProvider' cannot be null");
|
||||
this.timerTagProvider = timerTagProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,7 +128,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setCounterTagProvider(Function<String, String[]> counterTagProvider) {
|
||||
Assert.notNull(counterTagProvider, "'counterTagProvider' cannot be null");
|
||||
this.counterTagProvider = counterTagProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +137,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setErrorCounterTagProvider(Function<String, String[]> counterTagProvider) {
|
||||
Assert.notNull(counterTagProvider, "'counterTagProvider' cannot be null");
|
||||
this.errorCounterTagProvider = counterTagProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +146,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setReceiveCounterTagProvider(Function<String, String[]> counterTagProvider) {
|
||||
Assert.notNull(counterTagProvider, "'counterTagProvider' cannot be null");
|
||||
this.receiveCounterTagProvider = counterTagProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +155,6 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
*/
|
||||
public void setReceiveErrorCounterTagProvider(Function<String, String[]> counterTagProvider) {
|
||||
Assert.notNull(counterTagProvider, "'counterTagProvider' cannot be null");
|
||||
this.receiveErrorCounterTagProvider = counterTagProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,61 +163,25 @@ public class MicrometerMetricsFactory implements MetricsFactory, MessageSourceMe
|
||||
* @param componentCountTagProvider the componentCountTagProvider to set
|
||||
*/
|
||||
public void setComponentCountTagProvider(Function<String, String[]> componentCountTagProvider) {
|
||||
this.componentCountTagProvider = componentCountTagProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractMessageChannelMetrics createChannelMetrics(String name) {
|
||||
return new DefaultMessageChannelMetrics(name,
|
||||
this.meterRegistry.timer(this.timerNameProvider.apply(name), this.timerTagProvider.apply(name)),
|
||||
this.meterRegistry.counter(this.errorCounterNameProvider.apply(name),
|
||||
this.errorCounterTagProvider.apply(name)), null, null);
|
||||
return new DefaultMessageChannelMetrics(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractMessageChannelMetrics createPollableChannelMetrics(String name) {
|
||||
return new DefaultMessageChannelMetrics(name,
|
||||
this.meterRegistry.timer(this.timerNameProvider.apply(name), this.timerTagProvider.apply(name)),
|
||||
this.meterRegistry.counter(this.errorCounterNameProvider.apply(name),
|
||||
this.errorCounterTagProvider.apply(name)),
|
||||
this.meterRegistry.counter(this.receiveCounterNameProvider.apply(name),
|
||||
this.receiveCounterTagProvider.apply(name)),
|
||||
this.meterRegistry.counter(this.receiveErrorCounterNameProvider.apply(name),
|
||||
this.receiveErrorCounterTagProvider.apply(name)));
|
||||
return new DefaultMessageChannelMetrics(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractMessageHandlerMetrics createHandlerMetrics(String name) {
|
||||
return new DefaultMessageHandlerMetrics(name,
|
||||
this.meterRegistry.timer(this.timerNameProvider.apply(name), this.timerTagProvider.apply(name)),
|
||||
this.meterRegistry.counter(this.errorCounterNameProvider.apply(name),
|
||||
this.errorCounterTagProvider.apply(name)));
|
||||
return new DefaultMessageHandlerMetrics(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(MessageSourceMetrics metrics, String name) {
|
||||
metrics.setCounter(this.meterRegistry.counter(this.counterNameProvider.apply(name),
|
||||
this.counterTagProvider.apply(name)));
|
||||
}
|
||||
|
||||
private void registerComponentGauges() {
|
||||
Gauge.Builder<?> builder = Gauge.builder("spring.integration.channels", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageChannel.class).size());
|
||||
builder.tags(this.componentCountTagProvider.apply("channels"))
|
||||
.description("The Number of Message Channels")
|
||||
.register(this.meterRegistry);
|
||||
|
||||
builder = Gauge.builder("spring.integration.handlers", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageHandler.class).size());
|
||||
builder.tags(this.componentCountTagProvider.apply("handlers"))
|
||||
.description("The Number of Message Handlers")
|
||||
.register(this.meterRegistry);
|
||||
|
||||
builder = Gauge.builder("spring.integration.sources", this,
|
||||
(c) -> this.applicationContext.getBeansOfType(MessageSource.class).size());
|
||||
builder.tags(this.componentCountTagProvider.apply("sources"))
|
||||
.description("The number of Message Sources")
|
||||
.register(this.meterRegistry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -101,8 +101,10 @@ Starting with _version 5.0.2_, the framework will automatically detect if there
|
||||
Starting with _version 5.0.3_, the presence of a https://micrometer.io/[Micrometer] `MeterRegistry` in the application context will trigger support for Micrometer metrics in addition to the inbuilt metrics (inbuilt metrics will be removed in a future release).
|
||||
|
||||
IMPORTANT: Micrometer was first supported in _version 5.0.2_, but changes were made to the Micrometer `Meters` in _version 5.0.3_ to make them more suitable for use in dimensional systems.
|
||||
Further changes were made in 5.0.4; if using Micrometer, a minimum of version 5.0.4 is recommended since some of the changes in 5.0.4 were breaking API changes.
|
||||
|
||||
Simply add a `MeterRegistry` bean of choice to the application context.
|
||||
If the `IntegrationManagementConfigurer` detects exactly one `MeterRegistry` bean, it will configure a `MicrometerMetricsCaptor` bean with name `integrationMicrometerMetricsCaptor`.
|
||||
|
||||
For each `MessageHandler` and `MessageChannel`, timers are registered.
|
||||
For each `MessageSource`, a counter is registered.
|
||||
|
||||
@@ -308,6 +308,7 @@ http://micrometer.io/[Micrometer] application monitoring is now supported (since
|
||||
See <<micrometer-integration>> for more information.
|
||||
|
||||
IMPORTANT: Changes were made to the Micrometer `Meters` in _version 5.0.3_ to make them more suitable for use in dimensional systems.
|
||||
Further changes were made in 5.0.4; if using Micrometer, a minimum of version 5.0.4 is recommended.
|
||||
|
||||
|
||||
==== @EndpointId Annotations
|
||||
|
||||
Reference in New Issue
Block a user