[[metrics-management]]
= Metrics and Management

This section describes how to capture metrics for Spring Integration.
In recent versions, we have relied more on Micrometer (see https://micrometer.io), and we plan to use Micrometer even more in future releases.

[[disabling-logging-in-high-volume-environments]]
== 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:

[tabs]
======
Java::
+
[source, java, role="primary"]
----
@Configuration
@EnableIntegration
@EnableIntegrationManagement(
    defaultLoggingEnabled = "true" <1>)

public static class ContextConfiguration {
...
}
----

XML::
+
[source, xml, role="secondary"]
----
<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`.

IMPORTANT: `defaultLoggingEnabled` is applied only if you have not explicitly configured the corresponding setting in a bean definition.

[[micrometer-integration]]
== Micrometer Integration

[[overview]]
=== Overview

Starting with version 5.0.3, the presence of a https://micrometer.io/[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 of `MessageChannels` in the application.
* `spring.integration.handlers`: The number of `MessageHandlers` in the application.
* `spring.integration.sources`: The number of `MessageSources` 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 https://github.com/spring-projects/spring-integration/blob/main/spring-integration-core/src/test/java/org/springframework/integration/support/management/micrometer/MicrometerCustomMetricsTests.java[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]]
=== 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 https://micrometer.io/docs/concepts#_meter_filters[Meter Filters] in the Micrometer documentation for more information.

For example, given:

[source, java]
----
@Bean
public QueueChannel noMeters() {
    return new QueueChannel(10);
}
----

You can suppress registration of meters for just this channel with:

[source, java]
----
registry.config().meterFilter(MeterFilter.deny(id ->
        "channel".equals(id.getTag("type")) &&
        "noMeters".equals(id.getTag("name"))));
----

[[micrometer-observation]]
== Micrometer Observation

Starting with version 6.0, Spring Integration utilizes a Micrometer Observation abstraction which can handle metrics as well as https://micrometer.io/docs/tracing[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.

IMPORTANT: 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 a `CONSUMER` span type and uses the `IntegrationObservation.HANDLER` API;
* MessagingGatewaySupport` is an inbound request-reply endpoint, and is considered as a `SERVER` span type.
It uses the `IntegrationObservation.GATEWAY` API;
* An `AbstractMessageChannel.send()` operation is the only Spring Integration API where it produces messages.
So, it is treated as a `PRODUCER` span type and uses the `IntegrationObservation.PRODCUER` API.
This makes more sense when a channel is a distributed implementation (e.g. `PublishSubscribeKafkaChannel` or `ZeroMqChannel`) and trace information has to be added to the message.
So, the `IntegrationObservation.PRODUCER` observation is based on a `MessageSenderContext` where Spring Integration supplies a `MutableMessage` to allow a subsequent tracing `Propagator` to add headers, so they are available to the consumer;
* An `AbstractMessageHandler` is a `CONSUMER` span type and uses the `IntegrationObservation.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:

include::partial$metrics.adoc[]

include::partial$spans.adoc[]

include::partial$conventions.adoc[]


[[observation-propagation]]
== 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]]
== Spring Integration JMX Support

Also see xref:jmx.adoc[JMX Support].
