Advanced features

Logging

SmallRye Reactive Messaging uses JBoss Logging as logging API. This section explains how to configure the loggers for various logging backends.

If you are developing SmallRye Reactive Messaging and wonder about how the logs are managed, it uses JBoss Logging Tools.

Logging Backends

SmallRye Reactive Messaging uses the JBoss Logging library to write messages to a log file. This library is a logging bridge that integrates different log frameworks. You can decide which of the following frameworks you want to use for your application:

  • JBoss LogManager (jboss)

  • Log4j 2 (log4j2)

  • Log4j 1 (log4j)

  • Slf4j (slf4j)

  • JDK logging (jul)

You only need to add the chosen framework to the classpath, and the JBoss Logging library will pick it up. If there are multiple frameworks available on the classpath, it picks the first found (in the order from the list). Alternatively, you can set the org.jboss.logging.provider system property is one of the values given above.

The concepts and log categories are the same for all frameworks. However, the format of the configuration file and the names of the log levels differ. Check the documentation of your logging library to find out which dependencies are required, the exact name of the log levels, and where the configuration should be written.

Log Categories

As all applications and frameworks, SmallRye Reactive Messaging writes log messages in different categories and log levels. The categories group messages from specific connectors, classes or components. The following table shows the essential log categories used by SmallRye Reactive Messaging:

Category Description

io.smallrye.reactive.messaging

This category contains all the messages written by SmallRye Reactive Messaging.

io.smallrye.reactive.messaging.provider

This category contains all the messages generated by the core (provider).

io.smallrye.reactive.messaging.kafka

This category contains all the messages generated by the Kafka Connector.

io.smallrye.reactive.messaging.amqp

This category contains all the messages generated by the AMQP Connector.

io.smallrye.reactive.messaging.jms

This category contains all the messages generated by the JMS Connector.

io.smallrye.reactive.messaging.camel

This category contains all the messages generated by the Camel Connector.

io.smallrye.reactive.messaging.mqtt

This category contains all the messages generated by the MQTT (Client) Connector.

io.smallrye.reactive.messaging.mqtt-server

This category contains all the messages generated by the MQTT (Server) Connector.

The names of the log levels are defined by your logging framework and determine the amount and granularity of the log messages. You can assign a log level to each category. If you do not specify a specific category’s log level, it will inherit the level from its parent category. Thus, setting the log level of io.smallrye.reactive.messaging influences every loggers from SmallRye Reactive Messaging.

Code

Each message has an identifier code. They are all prefixed with SRMSG, followed with the numeric code.

In the following output, the code is SRMSG00229:

[2020-06-15 13:35:07] [INFO   ] SRMSG00229: Channel manager initializing...

Development

Log4J 1

log4j.properties
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n

log4j.rootLogger=info, stdout
log4j.logger.io.smallrye.reactive.messaging=info
log4j.logger.org.jboss.weld=warn

Log4J 2

log4j2.xml
<Configuration monitorInterval="60">
  <Properties>
    <Property name="log-path">PropertiesConfiguration</Property>
  </Properties>
  <Appenders>
    <Console name="Console-Appender" target="SYSTEM_OUT">
      <PatternLayout>
        <pattern>
          [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
        </pattern>>
      </PatternLayout>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="io.smallrye.reactive.messaging" level="info" additivity="false">
      <AppenderRef ref="Console-Appender"/>
    </Logger>
    <Logger name="org.jboss.weld" level="warn" additivity="false">
      <AppenderRef ref="Console-Appender"/>
    </Logger>
    <Root level="info">
      <AppenderRef ref="Console-Appender"/>
    </Root>
  </Loggers>
</Configuration>

JDK (JUL)

logging.properties
handlers=java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$-7s] %5$s %n

.level=INFO
io.smallrye.reactive.messaging.level=INFO
org.jboss.weld.level=WARNING

LogBack via SLF4J

logback.xml
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <Pattern>
        %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
      </Pattern>
    </encoder>
  </appender>
  <logger name="io.smallrye.reactive.messaging" level="info" additivity="false">
    <appender-ref ref="STDOUT"/>
  </logger>
  <logger name="org.jboss.weld" level="warn" additivity="false">
    <appender-ref ref="STDOUT"/>
  </logger>
  <root level="info">
    <appender-ref ref="STDOUT"/>
  </root>
</configuration>

Production

Log4J 1

log4j.properties
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n

log4j.rootLogger=info, stdout
log4j.logger.io.smallrye.reactive.messaging=warn
log4j.logger.org.jboss.weld=error

Log4J 2

log4j2.xml
<Configuration monitorInterval="60">
  <Properties>
    <Property name="log-path">PropertiesConfiguration</Property>
  </Properties>
  <Appenders>
    <Console name="Console-Appender" target="SYSTEM_OUT">
      <PatternLayout>
        <pattern>
          [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
        </pattern>>
      </PatternLayout>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="io.smallrye.reactive.messaging" level="warn" additivity="false">
      <AppenderRef ref="Console-Appender"/>
    </Logger>
    <Logger name="org.jboss.weld" level="error" additivity="false">
      <AppenderRef ref="Console-Appender"/>
    </Logger>
    <Root level="info">
      <AppenderRef ref="Console-Appender"/>
    </Root>
  </Loggers>
</Configuration>

JDK (JUL)

logging.properties
handlers=java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$-7s] %5$s %n

.level=INFO
io.smallrye.reactive.messaging.level=WARNING
org.jboss.weld.level=SEVERE
logback.xml
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <Pattern>
        %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
      </Pattern>
    </encoder>
  </appender>
  <logger name="io.smallrye.reactive.messaging" level="warn" additivity="false">
    <appender-ref ref="STDOUT"/>
  </logger>
  <logger name="org.jboss.weld" level="error" additivity="false">
    <appender-ref ref="STDOUT"/>
  </logger>
  <root level="info">
    <appender-ref ref="STDOUT"/>
  </root>
</configuration>

Strict Binding Mode

By default, SmallRye Reactive Messaging does not enforce whether all mediators are connected. It just prints a warning message. The strict mode fails the deployment if some "incomings" are not bound to "outgoings". To enable this mode, you can pass the -Dsmallrye-messaging-strict-binding=true via the command line, or you can set the smallrye-messaging-strict-binding attribute to true in the configuration:

smallrye-messaging-strict-binding=true

Disabling channels

You can disable a channel in the configuration by setting the enabled attribute to false:

mp.messaging.outgoing.dummy-sink.connector=dummy
mp.messaging.outgoing.dummy-sink.enabled=false # Disable this channel

SmallRye Reactive Messaging does not register disabled channels, so make sure the rest of the application does not rely on them.

Publisher metrics

SmallRye Reactive Messaging integrates MicroProfile Metrics and Micrometer for registering counter metrics (named mp.messaging.message.count) of published messages per channel.

Both MicroProfile and Micrometer publisher metrics are enabled by default if found on the classpath. They can be disabled with smallrye.messaging.metrics.mp.enabled and smallrye.messaging.metrics.micrometer.enabled properties respectively.