How to set up Log4j Appenders for your Mule apps


As we’ve seen in previous posts, Mule uses the Log4j framework to define the different destinations for our logs. 

Log4j Appenders are essential components in the logging infrastructure of mule apps.
An appender determines where the log messages are sent, whether it's a file, console, database, a remote server or a logging system like Splunk, ELK, Datadog... Understanding and configuring appenders effectively in MuleSoft allows for greater flexibility in how logs are handled, stored, and analyzed.

In this post, we will see in detail what Log4j appenders are, how they work and how we can use them for our mule apps.

What are Log4j Appenders?

In Log4j, an appender is a component of the Log4j framework that defines the destination of log messages. When a log event is generated, it is passed to one or more appenders that determine where and how that log event is recorded.

Common destinations, in general, include:
  • ConsoleAppender: Logs to the console (standard output).
  • FileAppender: Logs to a specified file. It’s ideal for environments where logs need to be preserved for auditing, monitoring, or later analysis.
  • RollingFileAppender: Logs to a file and rolls over when it reaches a certain size or at certain time intervals.
  • SocketAppender: Sends logs over the network to a remote server.
  • SMTPAppender: Sends logs via email.
However, in Mule scenarios, is very common to use log appenders to send logs to logging systems like Splunk, ELK or Datadog.

Configuration of Log4j Appenders

To configure Log4j appenders in Mule, we need to adjust the log4j2.xml configuration file, located at src/main/resources folder of our mule project. The file comes with a standard configuration so that our app will provide logs even if we don’t do anything.

Here below you can see the default configuration for mule apps. As you can see the Appenders configuration has a dedicated section in the XML, where you’d be adding each appender you want to use. In the default configuration you can see the default appender, the Rollingfile. The RollingFile is just a file where your app will be writing the log entries and that will get a rotation policy applied. Based on that policy the file rolls over when the file gets to a certain size or number of days. That’s exactly the default behaviour we see in Cloudhub apps - the logs rotate for a period of 30 days and a maximum of 100MB. This is the underlying config.



There are many appenders, of multiple types, depending on where and how you want to send your logs. For an initial list (there are more) of available appenders in Log4j you can start by having a look at the Log4j web site. 

Log4j allows multiple appenders to be attached to a logger, meaning that the same log message can be sent to several different destinations.

The configuration of the appenders is located in the dedicated Appenders XML item of the log4j2.xml. The appender’s configuration will include the necessary details for our app to connect to the external system and send the logs. The configuration is specific to each appender so there’s no a unique configuration for all. But, nevertheless, here are some examples of the most common scenarios so that you can get familiar with appenders configurations:

Configuration examples

File Appender

<Appenders>
<File name="File" fileName="logs/mule.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
</File>
</Appenders>
Where:
  • fileName: Specifies the file where logs will be written.
  • PatternLayout: Defines the log message format.


RollingFileAppender

The RollingFileAppender is similar to FileAppender but with the added capability of log file rotation. It’s particularly useful in production environments where log files can grow large over time. Example:

<Appenders>
<RollingFile name="RollingFile" fileName="logs/mule.log" filePattern="logs/mule-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>

Where:

  • filePattern: Defines the naming pattern for rolled-over log files (e.g., based on date).
  • TimeBasedTriggeringPolicy: Rolls over logs based on time intervals (e.g., daily).
  • SizeBasedTriggeringPolicy: Rolls over logs based on file size (e.g., every 10MB).
  • DefaultRolloverStrategy: Limits the number of backup files (e.g., keep the last 10 files).


SocketAppender

The SocketAppender sends log messages to a remote server via TCP or UDP. It’s useful for centralized logging where logs from multiple applications are collected and analyzed in a single place. Example:
<Appenders>
<Socket name="Socket" host="logserver.company.com" port="4560">
<SerializedLayout/>
</Socket>
</Appenders>

Where:

  • host: The remote server where logs are sent.
  • port: The port on the remote server where logs are received.
  • SerializedLayout: Serializes log messages for transmission over the network.


SMTPAppender

The SMTPAppender sends log messages via email, often used for alerting on critical or fatal errors.
<Appenders>
<SMTP name="SMTP" to="admin@company.com" from="mule@company.com" subject="Mule Error Alert" smtpHost="smtp.company.com">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</SMTP>
</Appenders>
Where:
  • to: The recipient of the email.
  • from: The sender’s email address.
  • subject: The subject line of the email.
  • ThresholdFilter: Ensures only log messages at or above a certain level (e.g., ERROR) trigger the email.


Appenders for Logging Aggregation Systems

In Mule, it’s very common to externalize our mule apps logs to logging aggregation systems like Splunk, ELK or Datadog. We’ve dedicated specific posts for each of them. Have a look at the list and go to the one you’d like to know how to set up:
  • HTTP Appender for Splunk
  • Splunk Appender
  • (We’ll be updating this list, as more projects come to our backlog :))

Linking the Appender to a Logger

The Appenders section of the log4j2.xml defines the different locations and how to connect to them for our logging framework. However, that’s not enough for our app to start sending logs. For that it’s necessary to declare the appender within one of our loggers.

As we saw recently in a previous post, a logger is associated with a specific part of the application, usually identified by a name (which typically corresponds to the package or class it logs messages for). Each logger can define a log level and an appender. To do so, each logger defined within the Loggers of the log4j2.xml section can, optionally, include an appender.
In other words, linking an appender to a logger means that we can have parts of our application with a different log level and sending logs to a specific destination.

For example, we could define a logger for a specific connector and send only the logs of the connector to a different location. Look at this example:

<Appenders>
<RollingFile name="file"
fileName="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}logging-tests-2.log"
filePattern="${sys:mule.home}${sys:file.separator}logs${sys:file.separator}logging-tests-2-%i.log">
<PatternLayout
pattern="%-5p %d [%t] [processor: %X{processorPath}; event: %X{correlationId}] %c: %m%n" />
<SizeBasedTriggeringPolicy size="10 MB" />
<DefaultRolloverStrategy max="10" />
</RollingFile>
<Http name="Splunk"
url="http://[splunk_hostname]:8088/services/collector/raw">
<Property name="Authorization"
value="Splunk xxxx-xxxx-xxx-xxxx"></Property>
<PatternLayout pattern="%m%n" />

</Http>
</Appenders>

<Loggers>
<AsyncLogger
name="org.mule.service.http.impl.service.HttpMessageLogger"
level="DEBUG">
<AppenderRef ref="Splunk" />

</AsyncLogger>

<AsyncRoot level="INFO">
<AppenderRef ref="file" />
</AsyncRoot>
</Loggers>

This configuration:

  • The Appenders section defines two appenders, that is, two locations available for sending logs: a file and a Splunk instance.
  • The Loggers section defines two loggers:
    • The root logger, AsyncRoot, which is mandatory - This specifies that ALL logs are sent to the file location
    • The HTTP connector logger, identify by its package name org.mule.service.http.impl.service.HttpMessageLogger - This specifies that ONLY logs generated by the HTTP connector are sent to Splunk
    • The loggers also specified different log levels
  • It might not make sense to send only HTTP connector logs to Splunk, this was just an example. The important thing to understand is that with the association between loggers and appenders we have the ability of being granular and send only logs of specific parts of our application to a location different from the one defined for the rest of the app.
  • Lastly, notice that, if we don’t specify any appender for a logger, that logger will use the appender of the root logger.

Previous Post Next Post