The Blog http://blog.jyore.com/?p=234
Introduction
When it comes down to it, logging is one of the most important parts of an application. Logging, when done correctly, allows us to monitor code behavior and find bugs for example.
JBoss has its own implementation of the popular logging frameworks [log4j, apache commons, slf4j] that it lumps into a package called JBoss logging. The application platform utilizes a logging subsystem that manages your logs, instead of the traditional log4j.properties/log4j.xml files that the vast majority of Enterprise Java developers are acquainted with. So, how can logging be configured to accomplish the logging behavior we desire? Is it possible to still use a log4j.properties? The short answer is read on and you will be able to correctly work with JBoss Logging, or if you want a traditional approach, then you will learn how you can bypass JBoss Logging and work with your own configuration as well.
This article will take a look at two logging strategies:
- Logging with JBoss Logging
- Logging without JBoss Logging [Traditional Logging Approach]
Logging with JBoss Logging
At the core, JBoss logging is log4j, so if you are familiar with log4j configuration, it should be a relatively easy transition to the new JBoss Logging. The main difference, other than syntax of course, is that the appenders from log4j are handlers in JBoss.
So, why convert to using the JBoss Logging, especially considering the next sections show how to avoid using JBoss Logging? Well, the short answer is, your logging becomes much easier to manage and interact with. JBoss logging configuration goes into the standalone/domain xml files as all EAP 6 and AS 7 configuration does. The web console and the command line interface (CLI) tools both give you the ability to create and manage your logs. What’s more is, most all logging configuration happens on the fly, which means, you can crank your logs down to DEBUG to capture more information on an error state and turn it back to INFO without having to bounce your server.
Log Handlers
The log handlers are the appenders of JBoss logging. You can add a console, periodic rotating file, and size rotating file handlers. Each type (covered below) has some specific configuration required, some optional, and some that default to certain values if not set.
Console Handler
The console handler is used for logging out to the console as the name suggests. The configuration for a console handler is pretty straight forward.
Property | Required | Default | Description |
autoflush | No | true | Automatically flush after each write |
encoding | No | undefined | Character encoding to use |
filter | No | undefined | Filter to use |
formatter | No | %d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n | Defines a formatter |
level | No | INFO | The log level to set the handler to |
target | No | System.out | The target output |
A command line example for adding a default console handler is as follows:
Which would correspond to the following XML in the server xml configuration:
Another example that changes some of the defaults is as follows:
/subsystem=logging/console-handler=MyConsoleHandler2:add(autoflush=true,level=DEBUG,formatter="%-5p %d{yyMMdd HHmmss,SSS} %X{sessId} %c: %m%n")
<console-handler name="MyConsoleHandler2" autoflush="true">
<level name="DEBUG"/>
<formatter>
<pattern-formatter pattern="%-5p %d{yyMMdd HHmmss,SSS} %X{sessId} %c: %m%n"/>
</formatter>
</console-handler>
Periodic Rotating File Handler
Size Rotating File Handler
Traditional Logging Approach
So, let’s say you decide that JBoss Logging is not for you, and there are a number of reasons that you may decide this. If you strive to keep your code container agnostic and would rather keep a traditional approach that will work on other platforms is one of the best reasons. Or, if you are migrating your application from a previous version of JBoss, WebLogic, WebSphere, etc to EAP 6, for example, then you may not want to reconfigure all of your logging. Maybe you just don’t like the container controlling your Logging. Whatever the reason, you can pretty easily get your logging configuration working in a couple steps.
NOTE: The following will go over the basic steps FIRST, which will apply to just single deployments. EAR deployments are slightly different in that it expands upon the single deployment steps and are covered in the last section below.
Disable JBoss Logging
In this step, the JBoss Logging jars are removed from the application. The JBoss jar’s have their own Log Manager which will not correctly pick up and will not use your logging configuration. In fact, you will likely get errors without this step.
Disabling JBoss Logging is done on an application basis in the jboss-deployment-structure.xml file. This does allow for you to have some apps using JBoss Logging and some using their own Log Manager, however, I strongly suggest using one strategy or another for all applications.
As before, we will stick with Log4j and Apache Commons Logging, however, you can use SLF4j or similar with the same basic approach.
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.log4j"/>
<module name="org.apache.commons.logging"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
If you are using an EAR, then please skip to the section below discussing EAR deployments. If you are using a WAR, then this file is placed in your WEB-INF directory.
Package the Logging JARs and Configuration
You will now package your logging JARs inside of your application. This would be inside your lib directory of your EAR or your WEB-INF/lib directory of a WAR as normal.
You will also place your log4j.properties/log4j.xml on your classpath as normal.
Add a JAVA_OPT to Startup
Now, when starting the application server, you will need to add a JAVA_OPT. This flag will make sure that the JBoss Log Manager does not pick up your logging configuration and your own logging JARs will work as normal.
./standalone.sh -Dorg.jboss.as.logging.per-deployment=false
And now your application will now log using the packaged JARs, effectively bypassing JBoss Logging.
EAR Deployments
Now, the above example is all fine and good if you are deploying a WAR, however, Enterprise applications typically have multiple deployments packaged in an EAR. If you try the above method, then the JBoss Log Manager will ignore your configuration and use the containers logging subsystem.
For EAR packages, the jboss-deployment-structure.xml, first of all be in the EAR’s META-INF directory. Additionally, you must add exclusions for the deployment AND each sub-deployment. The logging jars should be in the EAR/lib directory. You should create a module that you can use to bring in the log4j.properties file so all sub-deployments can reference it. Finally, you must start with the JAVA_OPT as noted above.
Example jboss-deployment-structure.xml file:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment name="logging-war-1.0.war">
<dependencies>
<module name="com.jyore.logging" export="true"/>
</dependencies>
<exclusions>
<module name="org.apache.log4j"/>
<module name="org.slf4j"/>
</exclusions>
</deployment>
<sub-deployment name="logging-war-1.0.war">
<exclusions>
<module name="org.apache.log4j"/>
<module name="org.slf4j"/>
</exclusions>
</sub-deployment>
</jboss-deployment-structure>
Example module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.jyore.logging">
<resources>
<resource-root path="."/>
</resources>
<dependencies>
<module name="org.apache.log4j"/>
</dependencies>
</module>
Example module layout:
EAP_HOME
`-- modules
`-- com
`-- jyore
`-- logging
`-- main
|-- module.xml
`-- log4j.properties
I included a project and the module for your own testing. Enjoy!
Downloads: logging-example.zip | modules.zip