This section describes how to capture metrics for Spring Integration. In recent versions, we have relied more on Micrometer (see micrometer.io), and we plan to use Micrometer even more in future releases.
Disabling Logging in High Volume Environments
You can control debug logging in the main message flow.
In very high volume applications, calls to isDebugEnabled()
can be quite expensive with some logging subsystems.
You can disable all such logging to avoid this overhead.
Exception logging (debug or otherwise) is not affected by this setting.
The following listing shows the available options for controlling logging:
-
Java
-
XML
@Configuration
@EnableIntegration
@EnableIntegrationManagement(
defaultLoggingEnabled = "true" <1>)
public static class ContextConfiguration {
...
}
<int:management default-logging-enabled="true"/> (1)
1 | Set to false to disable all logging in the main message flow, regardless of the log system category settings.
Set to 'true' to enable debug logging (if also enabled by the logging subsystem).
Only applied if you have not explicitly configured the setting in a bean definition.
The default is true . |
defaultLoggingEnabled is applied only if you have not explicitly configured the corresponding setting in a bean definition.
|
1 | Set to false to disable all logging in the main message flow, regardless of the log system category settings.
Set to 'true' to enable debug logging (if also enabled by the logging subsystem).
Only applied if you have not explicitly configured the setting in a bean definition.
The default is true . |
defaultLoggingEnabled is applied only if you have not explicitly configured the corresponding setting in a bean definition.
|
Micrometer Integration
Overview
Starting with version 5.0.3, the presence of a Micrometer MeterRegistry
in the application context triggers support for Micrometer metrics.
To use Micrometer, add one of the MeterRegistry
beans 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
(which is the case for most framework components).
The Timer
Meters for send operations on message channels have the following names or 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’s send()
operation returned false
.)
The Counter
Meters for receive operations on pollable message channels have the following names or 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 names or 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
In addition, there are three Gauge
Meters:
-
spring.integration.channels
: The number ofMessageChannels
in the application. -
spring.integration.handlers
: The number ofMessageHandlers
in the application. -
spring.integration.sources
: The number ofMessageSources
in the application.
It is possible to customize the names and tags of Meters
created by integration components by providing a subclass of MicrometerMetricsCaptor
.
The MicrometerCustomMetricsTests test case shows a simple example of how to do that.
You can also further customize the meters by overloading the build()
methods on builder subclasses.
Starting with version 5.1.13, the QueueChannel
exposes Micrometer gauges for queue size and remaining capacity:
-
name
:spring.integration.channel.queue.size
-
tag
:type:channel
-
tag
:name:<componentName>
-
description
:The size of the queue channel
and
-
name
:spring.integration.channel.queue.remaining.capacity
-
tag
:type:channel
-
tag
:name:<componentName>
-
description
:The remaining capacity of the queue channel
Disabling Meters
By default, all meters are registered when first used.
Now, with Micrometer, you can add MeterFilter
s to the MeterRegistry
to prevent some or all from being registered.
You can filter out (deny) meters by any of the properties provided, name
, tag
, etc.
See Meter Filters in the Micrometer documentation for more information.
For example, given:
@Bean
public QueueChannel noMeters() {
return new QueueChannel(10);
}
You can suppress registration of meters for just this channel with:
registry.config().meterFilter(MeterFilter.deny(id ->
"channel".equals(id.getTag("type")) &&
"noMeters".equals(id.getTag("name"))));
Micrometer Observation
Starting with version 6.0, Spring Integration utilizes a Micrometer Observation abstraction which can handle metrics as well as tracing via appropriate ObservationHandler
configuration.
The observation handling is enabled on the IntegrationManagement
components whenever an ObservationRegistry
bean is present in the application context and an @EnableIntegrationManagement
is configured.
To customize what set of components should be instrumented, an observationPatterns()
attribute is exposed on the @EnableIntegrationManagement
annotation.
See its javadocs for a pattern matching algorithm.
By default, none of the IntegrationManagement components are instrumented with an ObservationRegistry bean.
Can be configured as * to match all components.
|
The meters are not gathered in this case independently, but delegated to an appropriate ObservationHandler
configured on the provided ObservationRegistry
.
The following Spring Integration components are instrumented with observation logic each with a respective convention:
-
MessageProducerSupport
, being the inbound endpoint of the flow, is considered as aCONSUMER
span type and uses theIntegrationObservation.HANDLER
API; -
MessagingGatewaySupport` is an inbound request-reply endpoint, and is considered as a
SERVER
span type. It uses theIntegrationObservation.GATEWAY
API; -
An
AbstractMessageChannel.send()
operation is the only Spring Integration API where it produces messages. So, it is treated as aPRODUCER
span type and uses theIntegrationObservation.PRODCUER
API. This makes more sense when a channel is a distributed implementation (e.g.PublishSubscribeKafkaChannel
orZeroMqChannel
) and trace information has to be added to the message. So, theIntegrationObservation.PRODUCER
observation is based on aMessageSenderContext
where Spring Integration supplies aMutableMessage
to allow a subsequent tracingPropagator
to add headers, so they are available to the consumer; -
An
AbstractMessageHandler
is aCONSUMER
span type and uses theIntegrationObservation.HANDLER
API.
An observation production on the IntegrationManagement
components can be customized via ObservationConvention
configuration.
For example an AbstractMessageHandler
expects a MessageReceiverObservationConvention
via its setObservationConvention()
API.
The following are supported metrics, spans and conventions for Observation API:
Observability - Metrics
Below you can find a list of all metrics declared by this project.
Gateway
Observation for inbound message gateways.
Metric name spring.integration.gateway
(defined by convention class o.s.i.support.management.observation.DefaultMessageRequestReplyReceiverObservationConvention
). Type timer
.
Metric name spring.integration.gateway.active
(defined by convention class o.s.i.support.management.observation.DefaultMessageRequestReplyReceiverObservationConvention
). Type long task timer
.
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message gateway component. |
|
Outcome of the request/reply execution. |
|
Type of the component - 'gateway'. |
Handler
Observation for message handlers.
Metric name spring.integration.handler
(defined by convention class o.s.i.support.management.observation.DefaultMessageReceiverObservationConvention
). Type timer
.
Metric name spring.integration.handler.active
(defined by convention class o.s.i.support.management.observation.DefaultMessageReceiverObservationConvention
). Type long task timer
.
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'handler'. |
Producer
Observation for message producers, e.g. channels.
Metric name spring.integration.producer
(defined by convention class o.s.i.support.management.observation.DefaultMessageSenderObservationConvention
). Type timer
.
Metric name spring.integration.producer.active
(defined by convention class o.s.i.support.management.observation.DefaultMessageSenderObservationConvention
). Type long task timer
.
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'producer'. |
Observability - Spans
Below you can find a list of all spans declared by this project.
Gateway Span
Observation for inbound message gateways.
Span name spring.integration.gateway
(defined by convention class o.s.i.support.management.observation.DefaultMessageRequestReplyReceiverObservationConvention
).
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message gateway component. |
|
Outcome of the request/reply execution. |
|
Type of the component - 'gateway'. |
Handler Span
Observation for message handlers.
Span name spring.integration.handler
(defined by convention class o.s.i.support.management.observation.DefaultMessageReceiverObservationConvention
).
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'handler'. |
Producer Span
Observation for message producers, e.g. channels.
Span name spring.integration.producer
(defined by convention class o.s.i.support.management.observation.DefaultMessageSenderObservationConvention
).
Fully qualified name of the enclosing class o.s.i.support.management.observation.IntegrationObservation
.
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'producer'. |
Observability - Conventions
Below you can find a list of all GlobalObservationConvention
and ObservationConvention
declared by this project.
ObservationConvention Class Name |
Applicable ObservationContext Class Name |
|
|
|
|
|
|
|
|
|
|
|
|
By default, none of the IntegrationManagement components are instrumented with an ObservationRegistry bean.
Can be configured as * to match all components.
|
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message gateway component. |
|
Outcome of the request/reply execution. |
|
Type of the component - 'gateway'. |
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'handler'. |
KeyValues that are added after starting the Observation might be missing from the *.active metrics. |
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)
|
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'producer'. |
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message gateway component. |
|
Outcome of the request/reply execution. |
|
Type of the component - 'gateway'. |
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'handler'. |
All tags must be prefixed with spring.integration. prefix!
|
Name |
Description |
|
Name of the message handler component. |
|
Type of the component - 'producer'. |
ObservationConvention Class Name |
Applicable ObservationContext Class Name |
|
|
|
|
|
|
|
|
|
|
|
|
Observation Propagation
To supply a connected chain of spans in one trace, independently of the nature of the messaging flow, even if a MessageChannel
is persistent and distributed, the observation must be enabled on this channel and on consumers (subscribers) for this channel.
This way, the tracing information is stored in the message headers before it is propagated to a consumer thread or persisted into the database.
This is done via mentioned above MessageSenderContext
.
The consumer (a MessageHandler
) side restores tracing information from those headers using a MessageReceiverContext
and starts a new child Observation
.
Spring Integration JMX Support
Also see JMX Support.