INT-4418: Micrometer docs and polishing
JIRA: https://jira.spring.io/browse/INT-4418 Add docs for the rework and optimize `Meter` creation. Polishing * Polishing according PR comments * Fix typo in `dsl.adoc`
This commit is contained in:
committed by
Artem Bilan
parent
cb0d43db6b
commit
82a8982857
@@ -92,6 +92,10 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
|
||||
private Timer successTimer;
|
||||
|
||||
private Timer failureTimer;
|
||||
|
||||
public AbstractMessageChannel() {
|
||||
this.interceptors = new ChannelInterceptorList(logger);
|
||||
}
|
||||
@@ -445,7 +449,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
logger.debug("preSend on channel '" + this + "', message: " + message);
|
||||
}
|
||||
if (interceptors.getSize() > 0) {
|
||||
interceptorStack = new ArrayDeque<ChannelInterceptor>();
|
||||
interceptorStack = new ArrayDeque<>();
|
||||
message = interceptors.preSend(message, this, interceptorStack);
|
||||
if (message == null) {
|
||||
return false;
|
||||
@@ -458,13 +462,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
sent = doSend(message, timeout);
|
||||
if (sample != null) {
|
||||
sample.stop(Timer.builder(SEND_TIMER_NAME)
|
||||
.tag("type", "channel")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", sent ? "success" : "failure")
|
||||
.tag("exception", "none")
|
||||
.description("Subflow process time")
|
||||
.register(this.meterRegistry));
|
||||
sample.stop(sendTimer(sent));
|
||||
}
|
||||
channelMetrics.afterSend(metrics, sent);
|
||||
metricsProcessed = true;
|
||||
@@ -485,13 +483,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
catch (Exception e) {
|
||||
if (countsEnabled && !metricsProcessed) {
|
||||
if (sample != null) {
|
||||
sample.stop(Timer.builder(SEND_TIMER_NAME)
|
||||
.tag("type", "channel")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", "failure")
|
||||
.tag("exception", e.getClass().getSimpleName())
|
||||
.description("Subflow process time")
|
||||
.register(this.meterRegistry));
|
||||
sample.stop(buildSendTimer(false, e.getClass().getSimpleName()));
|
||||
}
|
||||
channelMetrics.afterSend(metrics, false);
|
||||
}
|
||||
@@ -506,6 +498,31 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
|
||||
}
|
||||
}
|
||||
|
||||
private Timer sendTimer(boolean sent) {
|
||||
if (sent) {
|
||||
if (this.successTimer == null) {
|
||||
this.successTimer = buildSendTimer(true, "none");
|
||||
}
|
||||
return this.successTimer;
|
||||
}
|
||||
else {
|
||||
if (this.failureTimer == null) {
|
||||
this.failureTimer = buildSendTimer(false, "none");
|
||||
}
|
||||
return this.failureTimer;
|
||||
}
|
||||
}
|
||||
|
||||
private Timer buildSendTimer(boolean success, String exception) {
|
||||
return Timer.builder(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);
|
||||
}
|
||||
|
||||
private Message<?> convertPayloadIfNecessary(Message<?> message) {
|
||||
// first pass checks if the payload type already matches any of the datatypes
|
||||
for (Class<?> datatype : this.datatypes) {
|
||||
|
||||
@@ -42,6 +42,8 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
|
||||
private volatile int executorInterceptorsSize;
|
||||
|
||||
private Counter receiveCounter;
|
||||
|
||||
@Override
|
||||
public int getReceiveCount() {
|
||||
return getMetrics().getReceiveCount();
|
||||
@@ -107,13 +109,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
Message<?> message = this.doReceive(timeout);
|
||||
if (countsEnabled && message != null) {
|
||||
if (getMeterRegistry() != null) {
|
||||
Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName())
|
||||
.tag("type", "channel")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(getMeterRegistry()).increment();
|
||||
incrementReceiveCounter();
|
||||
}
|
||||
getMetrics().afterReceive();
|
||||
counted = true;
|
||||
@@ -134,12 +130,13 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
if (countsEnabled && !counted) {
|
||||
if (getMeterRegistry() != null) {
|
||||
Counter.builder(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()).increment();
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("type", "channel")
|
||||
.tag("result", "failure")
|
||||
.tag("exception", e.getClass().getSimpleName())
|
||||
.description("Messages received")
|
||||
.register(getMeterRegistry())
|
||||
.increment();
|
||||
}
|
||||
getMetrics().afterError();
|
||||
}
|
||||
@@ -150,6 +147,19 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
|
||||
}
|
||||
}
|
||||
|
||||
private void incrementReceiveCounter() {
|
||||
if (this.receiveCounter == null) {
|
||||
this.receiveCounter = Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName())
|
||||
.tag("type", "channel")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(getMeterRegistry());
|
||||
}
|
||||
this.receiveCounter.increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInterceptors(List<ChannelInterceptor> interceptors) {
|
||||
super.setInterceptors(interceptors);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -45,6 +45,7 @@ import io.micrometer.core.instrument.Timer;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artyem Bilan
|
||||
*/
|
||||
@IntegrationManagedResource
|
||||
public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
@@ -66,6 +67,8 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
|
||||
private Timer successTimer;
|
||||
|
||||
@Override
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
@@ -221,6 +224,11 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
return this.managementOverrides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean send(Message<?> message, long timeout) {
|
||||
return send(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean send(Message<?> message) {
|
||||
if (this.loggingEnabled && this.logger.isDebugEnabled()) {
|
||||
@@ -228,22 +236,24 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
|
||||
}
|
||||
if (this.countsEnabled) {
|
||||
if (this.meterRegistry != null) {
|
||||
Timer.builder(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).record(0, TimeUnit.MILLISECONDS);
|
||||
sendTimer().record(0, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
this.channelMetrics.afterSend(this.channelMetrics.beforeSend(), true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean send(Message<?> message, long timeout) {
|
||||
return this.send(message);
|
||||
private Timer sendTimer() {
|
||||
if (this.successTimer == null) {
|
||||
this.successTimer = Timer.builder(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);
|
||||
}
|
||||
return this.successTimer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,14 +60,14 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
|
||||
private String managedName;
|
||||
|
||||
private Counter counter;
|
||||
|
||||
private volatile boolean countsEnabled;
|
||||
|
||||
private volatile boolean loggingEnabled = true;
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
|
||||
private Counter receiveCounter;
|
||||
|
||||
public void setHeaderExpressions(Map<String, Expression> headerExpressions) {
|
||||
this.headerExpressions = (headerExpressions != null)
|
||||
? headerExpressions : Collections.emptyMap();
|
||||
@@ -130,11 +130,6 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
this.managementOverrides.loggingConfigured = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCounter(Counter counter) {
|
||||
this.counter = counter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.messageCount.set(0);
|
||||
@@ -200,19 +195,26 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
|
||||
}
|
||||
if (this.countsEnabled && message != null) {
|
||||
if (this.meterRegistry != null) {
|
||||
Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("type", "source")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(this.meterRegistry).increment();
|
||||
incrementReceiveCounter();
|
||||
}
|
||||
this.messageCount.incrementAndGet();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private void incrementReceiveCounter() {
|
||||
if (this.receiveCounter == null) {
|
||||
this.receiveCounter = Counter.builder(RECEIVE_COUNTER_NAME)
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("type", "source")
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Messages received")
|
||||
.register(this.meterRegistry);
|
||||
}
|
||||
this.receiveCounter.increment();
|
||||
}
|
||||
|
||||
private Map<String, Object> evaluateHeaders() {
|
||||
Map<String, Object> results = new HashMap<>();
|
||||
for (Map.Entry<String, Expression> entry : this.headerExpressions.entrySet()) {
|
||||
|
||||
@@ -50,11 +50,12 @@ import reactor.core.CoreSubscriber;
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@IntegrationManagedResource
|
||||
public abstract class AbstractMessageHandler extends IntegrationObjectSupport implements MessageHandler,
|
||||
MessageHandlerMetrics, ConfigurableMetricsAware<AbstractMessageHandlerMetrics>, TrackableComponent, Orderable,
|
||||
CoreSubscriber<Message<?>> {
|
||||
public abstract class AbstractMessageHandler extends IntegrationObjectSupport
|
||||
implements MessageHandler, MessageHandlerMetrics, ConfigurableMetricsAware<AbstractMessageHandlerMetrics>,
|
||||
TrackableComponent, Orderable, CoreSubscriber<Message<?>> {
|
||||
|
||||
private final ManagementOverrides managementOverrides = new ManagementOverrides();
|
||||
|
||||
@@ -76,6 +77,8 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
|
||||
|
||||
private MeterRegistry meterRegistry;
|
||||
|
||||
private Timer successTimer;
|
||||
|
||||
@Override
|
||||
public boolean isLoggingEnabled() {
|
||||
return this.loggingEnabled;
|
||||
@@ -147,19 +150,13 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
|
||||
}
|
||||
try {
|
||||
if (this.shouldTrack) {
|
||||
message = MessageHistory.write(message, this, this.getMessageBuilderFactory());
|
||||
message = MessageHistory.write(message, this, getMessageBuilderFactory());
|
||||
}
|
||||
if (countsEnabled) {
|
||||
start = handlerMetrics.beforeHandle();
|
||||
handleMessageInternal(message);
|
||||
if (this.meterRegistry != null) {
|
||||
sample.stop(Timer.builder(SEND_TIMER_NAME)
|
||||
.tag("type", "handler")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", "success")
|
||||
.tag("exception", "none")
|
||||
.description("Subflow process time")
|
||||
.register(this.meterRegistry));
|
||||
sample.stop(sendTimer());
|
||||
}
|
||||
handlerMetrics.afterHandle(start, true);
|
||||
}
|
||||
@@ -169,13 +166,7 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (sample != null) {
|
||||
sample.stop(Timer.builder(SEND_TIMER_NAME)
|
||||
.tag("type", "handler")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", "failure")
|
||||
.tag("exception", e.getClass().getSimpleName())
|
||||
.description("Subflow process time")
|
||||
.register(this.meterRegistry));
|
||||
sample.stop(buildSendTimer(false, e.getClass().getSimpleName()));
|
||||
}
|
||||
if (countsEnabled) {
|
||||
handlerMetrics.afterHandle(start, false);
|
||||
@@ -187,6 +178,23 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
|
||||
}
|
||||
}
|
||||
|
||||
private Timer 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)
|
||||
.tag("type", "handler")
|
||||
.tag("name", getComponentName() == null ? "unknown" : getComponentName())
|
||||
.tag("result", success ? "success" : "failure")
|
||||
.tag("exception", exception)
|
||||
.description("Send processing time")
|
||||
.register(this.meterRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Subscription subscription) {
|
||||
Assert.notNull(subscription, "'subscription' must not be null");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-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.
|
||||
@@ -20,14 +20,14 @@ 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;
|
||||
|
||||
/**
|
||||
* A {@link MessageSourceMetrics} that exposes in addition the {@link Lifecycle} interface. The lifecycle methods can
|
||||
* be used to start and stop polling endpoints, for instance, in a live system.
|
||||
* A {@link MessageSourceMetrics} that exposes in addition the {@link Lifecycle} interface.
|
||||
* The lifecycle methods can be used to start and stop polling endpoints, for instance, in a live system.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
@IntegrationManagedResource
|
||||
@@ -126,9 +126,4 @@ public class LifecycleMessageSourceMetrics implements MessageSourceMetrics, Life
|
||||
return this.delegate.getOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCounter(Counter counter) {
|
||||
this.delegate.setCounter(counter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import io.micrometer.core.instrument.Counter;
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface MessageSourceMetrics extends IntegrationManagement {
|
||||
@@ -53,7 +55,10 @@ public interface MessageSourceMetrics extends IntegrationManagement {
|
||||
* Set a micrometer counter to count messages produced.
|
||||
* @param counter the counter.
|
||||
* @since 5.0.2
|
||||
* @deprecated in favor of built-in counter registration via {@code MeterRegistry} callbacks.
|
||||
* Will be remove in the next release.
|
||||
*/
|
||||
@Deprecated
|
||||
default void setCounter(Counter counter) {
|
||||
// no op
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.channel.AbstractPollableChannel;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.config.EnableIntegrationManagement;
|
||||
@@ -75,6 +76,9 @@ public class MicrometerMetricsTests {
|
||||
@Autowired
|
||||
private PollableChannel badPoll;
|
||||
|
||||
@Autowired
|
||||
private NullChannel nullChannel;
|
||||
|
||||
@Test
|
||||
public void testSend() {
|
||||
GenericMessage<String> message = new GenericMessage<>("foo");
|
||||
@@ -97,6 +101,7 @@ public class MicrometerMetricsTests {
|
||||
catch (RuntimeException e) {
|
||||
assertThat(e.getMessage()).isEqualTo("badPoll");
|
||||
}
|
||||
nullChannel.send(message);
|
||||
MeterRegistry registry = this.meterRegistry;
|
||||
assertThat(registry.get("spring.integration.channels").gauge().value()).isEqualTo(5);
|
||||
assertThat(registry.get("spring.integration.handlers").gauge().value()).isEqualTo(2);
|
||||
@@ -137,6 +142,11 @@ public class MicrometerMetricsTests {
|
||||
.tag("result", "success")
|
||||
.counter().count()).isEqualTo(1);
|
||||
|
||||
assertThat(registry.get("spring.integration.send")
|
||||
.tag("name", "nullChannel")
|
||||
.tag("result", "success")
|
||||
.timer().count()).isEqualTo(1);
|
||||
|
||||
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) this.context.getBeanFactory();
|
||||
beanFactory.registerBeanDefinition("newChannel",
|
||||
BeanDefinitionBuilder.genericBeanDefinition(DirectChannel.class).getRawBeanDefinition());
|
||||
|
||||
@@ -124,7 +124,7 @@ public MessageChannel priorityChannel() {
|
||||
}
|
||||
----
|
||||
|
||||
The same `MessageChannels` builder factory can be used in the `channel()` EIP-method from `IntegrationFlowBuilder` to wire endpoints similar to an`input-channel`/`output-channel` pair in the XML configuration.
|
||||
The same `MessageChannels` builder factory can be used in the `channel()` EIP-method from `IntegrationFlowBuilder` to wire endpoints similar to an `input-channel`/`output-channel` pair in the XML configuration.
|
||||
By default endpoints are wired via `DirectChannel` s where the bean name is based on the pattern: `[IntegrationFlow.beanName].channel#[channelNameIndex]`.
|
||||
This rule is applied for unnamed channels produced by inline `MessageChannels` builder factory usage, too.
|
||||
However all `MessageChannels` methods have a `channelId` -aware variant to create the bean names for `MessageChannel` s.
|
||||
|
||||
@@ -63,7 +63,6 @@ Default `false`.
|
||||
|
||||
<3> Enable or disable statistical metrics for components not matching one of the patterns in <5>.
|
||||
Only applied if you have not explicitly configured the setting in a bean definition.
|
||||
Ignored if <<micrometer-integration, Micrometer>> is being used.
|
||||
Default 'false'.
|
||||
|
||||
<4> A comma-delimited list of patterns for beans for which counts should be enabled; negate the pattern with `!`.
|
||||
@@ -76,7 +75,6 @@ with `!`.
|
||||
First match wins (positive or negative).
|
||||
In the unlikely event that you have a bean name starting with `!`, escape the `!` in the pattern: `\!foo` positively
|
||||
matches a bean named `!foo`.
|
||||
Ignored if <<micrometer-integration, Micrometer>> is being used.
|
||||
Stats implies counts.
|
||||
|
||||
<6> A reference to a `MetricsFactory`.
|
||||
@@ -100,31 +98,62 @@ Starting with _version 5.0.2_, the framework will automatically detect if there
|
||||
[[micrometer-integration]]
|
||||
==== Micrometer Integration
|
||||
|
||||
Starting with _version 5.0.2_, adding a `MicrometerMetricsFactory` to the application context will switch to using https://micrometer.io/[Micrometer] metrics instead of the inbuilt metrics.
|
||||
Simply add the bean, configured with a `MeterRegistry` implementation.
|
||||
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).
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@Bean
|
||||
public MicrometerMetricsFactory metricsFactory(MeterRegistry meterRegistry) {
|
||||
return new MicrometerMetricsFactory(meterRegistry);
|
||||
}
|
||||
----
|
||||
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.
|
||||
|
||||
For each `MessageHandler` and `MessageChannel`, a timer and errorCounter are registered.
|
||||
Simply add a `MeterRegistry` bean of choice to the application context.
|
||||
|
||||
For each `MessageHandler` and `MessageChannel`, timers are registered.
|
||||
For each `MessageSource`, a counter is registered.
|
||||
|
||||
This only applies to objects that extend `AbstractMessageHandler`, `AbstractMessageChannel` and `AbstractMessageSource` respectively (which is the case for most framework components).
|
||||
|
||||
The factory provides mechanisms to customize the `Meter` names and tags; refer to the Javadocs for more information.
|
||||
|
||||
With Micrometer metrics, the `statsEnabled` flag takes no effect, since statistics capture is delegated to Micrometer.
|
||||
The `countsEnabled` flag controls whether the Micrometer `Meter` s are updated when processing each message.
|
||||
|
||||
The `Timer` Meters for send operations on message channels have the following name/tags:
|
||||
|
||||
- `name` : `spring.integration.send`
|
||||
- `tag` : `type:channel`
|
||||
- `tag` : `name:<componentName>`
|
||||
- `tag` : `result:(success|failure)`
|
||||
- `tag` : `exception:(none|exception simple class name)`
|
||||
- `description` : `Send processing time`
|
||||
|
||||
(A `failure` result with a `none` exception means the channel `send()` operation returned `false`).
|
||||
|
||||
The `Counter` Meters for receive operations on pollable message channels have the following names/tags:
|
||||
|
||||
- `name` : `spring.integration.receive`
|
||||
- `tag` : `type:channel`
|
||||
- `tag` : `name:<componentName>`
|
||||
- `tag` : `result:(success|failure)`
|
||||
- `tag` : `exception:(none|exception simple class name)`
|
||||
- `description` : `Messages received`
|
||||
|
||||
The `Timer` Meters for operations on message handlers have the following name/tags:
|
||||
|
||||
- `name` : `spring.integration.send`
|
||||
- `tag` : `type:handler`
|
||||
- `tag` : `name:<componentName>`
|
||||
- `tag` : `result:(success|failure)`
|
||||
- `tag` : `exception:(none|exception simple class name)`
|
||||
- `description` : `Send processing time`
|
||||
|
||||
The `Counter` meters for message sources have the following names/tags:
|
||||
|
||||
- `name` : `spring.integration.receive`
|
||||
- `tag` : `type:source`
|
||||
- `tag` : `name:<componentName>`
|
||||
- `tag` : `result:success`
|
||||
- `tag` : `exception:none`
|
||||
- `description` : `Messages received`
|
||||
|
||||
[[mgmt-channel-features]]
|
||||
==== MessageChannel Metric Features
|
||||
|
||||
This only applies if <<micrometer-integration, Micrometer>> is not being used.
|
||||
These legacy metrics will be removed in a future release; see <<micrometer-integration>>.
|
||||
|
||||
Message channels report metrics according to their concrete type.
|
||||
If you are looking at a `DirectChannel`, you will see statistics for the send operation.
|
||||
@@ -174,7 +203,7 @@ Error ratio is 1 - success ratio.
|
||||
[[mgmt-handler-features]]
|
||||
==== MessageHandler Metric Features
|
||||
|
||||
This only applies if <<micrometer-integration, Micrometer>> is not being used.
|
||||
These legacy metrics will be removed in a future release; see <<micrometer-integration>>.
|
||||
|
||||
The following table shows the statistics maintained for message handlers.
|
||||
Some metrics are simple counters (message count and error count), and one is an estimate of averages of send duration.
|
||||
|
||||
@@ -306,3 +306,5 @@ See <<jdbc>> for more information.
|
||||
|
||||
http://micrometer.io/[Micrometer] application monitoring is now supported (since _version 5.0.2_).
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user