HowTo: Add your Two Cents' Worth to the Log (log4j and Userapp)

 
0 Likes
User application uses its own effective mechanism for logging and reporting on important events. Among other frameworks it relies on logging with Apache's log4j API set.

Log your workflows



Here's how you can easily create log entries from workflow activities, and add your own custom entries into the log files.

This can be extremely helpful during workflow development, but will come in handy when troubleshooting user actions and provisioning activities.

You can inject logging into existing workflow activities like mapping activities, condition activities, Log activities ... basically every place in the workflow that can handle ECMAscript.

Here, for demonstration purposes, we insert a new Log activity and add the call to log4j there.

How to add your two pennies' worth



Start by adding a log activity, and in the "Message" or "Comment" property, add this code snippet:



function log( id )
{
var logger = Packages.org.apache.log4j.Logger.getLogger( id );
var result = id;
try
{
result = " initiator=" initiator;
// add some more relevant flowdata stuff, here
// logger.debug( "FYI: " result );
logger.info( "FYI: " result );
}
catch (e)
{
result = ' ERROR: ' e.toString();
// logger.warn( result );
logger.error( result );
}
return( result );
}

log( "ACME Workflow" );



The call to "Packages.org.apache.log4j.Logger.getLogger( id )" creates a handle into the logging engine and gives it a custom name, so it can be identified in the log output. This ID ("ACME Workflow") is also used as prefix in the log entries.

Later (see below), we can use such prefixes for log filtering.

Subsequently you can add log entries, which is typically done with one of these method calls:


  • logger.debug(): fine-grained informational events that are most useful to debug an application

  • logger.info(): informational messages that highlight the progress of the application at coarse-grained level

  • logger.warn(): potentially harmful situations

  • logger.error(): error events that might still allow the application to continue running

  • logger.fatal(): very severe error events that will presumably lead the application to abort



See the JavaDoc at http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Logger.html for more info. For an intro into log4j, check also http://logging.apache.org/log4j/1.2/manual.html

That's it


To check the effects of your code, deploy and start your workflow, and view the server.log ($JBOSS_HOME/server/IDMProv/log/server.log) to see the new log entries.

To add more logging, simply get your log4j handle with Packages.org.apache.log4j.Logger.getLogger( "yourID" ) and add the calls to create your debug/info/warning messages.


Where to go next?



The next step may include separating your custom log entries from the bulk of the other server.log entries. There are many possible options that you can setup in the log4j configuration, too many to be covered here. See http://docs.jboss.org/jbossas/logging/JBossLog4j.pdf or http://docs.jboss.org/process-guide/en/html/logging.html


Your personal appender



log4j uses the term "appender": An appender is a logical message destination that takes care of rendering log messages into strings and forwarding it to log destinations (like files or SMTP)

We will configure a new appender in $JBOSS_HOME/server/IDMProv/conf/jboss-log4j.xml to store your log entries into a separate file.

For our demo, we ask log4j to put every log entry that contains the string "ACME" (see "StringToMatch") into a separate log file (acme.log); we have named that new appender "myLog".

For safety, create a backup of the jboss-log4j.xml file.

In this configuration file, locate the CONSOLE appender


<appender name="CONSOLE"
...
</appender>


After the "</appender>" tag, add this new appender


<!-- daily local file -->
<appender name="myLog" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/acme.log"/>
<param name="ImmediateFlush" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n" />
</layout>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="ACME"/>
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>



Then, activate this new "myLog"-appender:

Locate these lines, probably close to the end of jboss-log4j.xml

<root>
<priority value="INFO"/>
<appender-ref ref="CONSOLE"/>
</root>



Note: in our sample, the default logging level is set to "INFO", meaning that log messages with lower severity (like "logger.debug()" will be filtered and will never show up in the logs.

It can be useful to use a low default logging level during development, then raise the threshold in production.

Inject the "myLog" appender:

<root>
<priority value="INFO"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="myLog" />
</root>


Finally, restart jBoss to activate the modified log configuration and start your sample workflow with the ACME-log calls outlined above.

Need more?



Besides such FileAppenders, the log4j framework also offers cool stuff like an JMSAppender, SMTPAppender, SocketAppender, SyslogAppender, or TelnetAppender

Documentation of these more advanced appenders can be found at http://logging.apache.org

More advanced?



Check Novell's logging products at http://www.novell.com/products/sentinel-log-manager - there currently are free entry level log management solutions that can handle up to 25 events per second.

Labels:

How To-Best Practice
Comment List
  • Addendum: Tomcat uses a slightly different approach for logging than JBoss.


    Instead of using the more recent log4j.xml configuration, tomcat relies on the older setup based on log4j.properties.
    In IDM 4.5.x you will find the configuration in [..]/tomcat/lib/log4j.properties

    Instructions to convert the above log4j.xml configuration into log4j.properties:

    # Create a backup copy of your original log4j.properties

    # In the log4j.properties main section insert these lines to add your custom appender:

    log4j.appender.myLog = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.myLog.File = /opt/netiq/idm/apps/tomcat/logs/acme.log
    log4j.appender.myLog.layout = org.apache.log4j.PatternLayout
    log4j.appender.myLog.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
    log4j.appender.myLog.filter.1 = org.apache.log4j.varia.StringMatchFilter
    log4j.appender.myLog.filter.1.StringToMatch = ACME
    log4j.appender.myLog.filter.1.AcceptOnMatch = true
    log4j.appender.myLog.filter.2 = org.apache.log4j.varia.DenyAllFilter


    # In the log4j.properties top section add the name of your appender - replace the original rootLogger line
    log4j.rootLogger = INFO, CATALINA, myLog


    # Optional: For troubleshooting the log4j setup, insert this line
    log4j.debug=true


    # In the bottom section insert this line to add your log level filter. Do not edit the original lines.
    log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost] = INFO, myLog


    # restart tomcat
Related
Recommended