<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23085011</id><updated>2012-01-09T10:50:56.756+01:00</updated><title type='text'>blog of vincent harcq</title><subtitle type='html'>About Java, Compiere, etc...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://vharcq.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23085011/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://vharcq.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Vincent Harcq</name><uri>http://www.blogger.com/profile/18388927537514218509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_LBlZeaaGFQU/SyyFqoHq0eI/AAAAAAAAATs/CjVBbHJ8KYw/S220/me.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23085011.post-4956259571818686320</id><published>2009-12-19T09:47:00.017+01:00</published><updated>2009-12-21T18:10:55.716+01:00</updated><title type='text'>Compiere and Logging</title><content type='html'>&lt;b&gt;Introduction&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Recently I received the mission to provide a tool to unify logging messages from different software into one central place.&lt;br /&gt;With &lt;a href="http://logging.apache.org/"&gt;Log4j&lt;/a&gt; you can define specific appender for that.  One possibility is using Jdbc appender from the different application to a central database.  Another way is to use a SNMP appender.  Or even write my own appender.&lt;br /&gt;The problem for softwares using log4j is solved : I add the appenders that I want to the configuration file of Log4j (log4j.properties or log4j.xml).  Finding this file when running in application servers (JBoss, Tomcat,...) can be a hard piece of work in itself but I will not talk about that here.  Google can help.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compiere used Java Logging&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Then comes Compiere that do not use Log4j.  &lt;a href="http://www.compiere.com"&gt;Compiere&lt;/a&gt; uses Java Logging framework.  Java logging is like Log4j but without the possibility to do configuration through configuration file.  This was clearly not an option for me to do logging changes by programming, compilation, packaging, deployment changes.&lt;br /&gt;&lt;br /&gt;So I decided to change Compiere Logging framework to add the possibility to do Log4j logging.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compiere Logging implementation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Java Logging framework is initialized through the java class CLogMgt.java&lt;br /&gt;There are 2 different initialization methods : one if running the GUI Client Compiere, one if running Compiere in "server" mode.  The server mode is used in the accounting processor or in the web ui, but also when you use Compiere API in some specific development running in an application server (Web Service, portal, ...)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Handlers or Appenders&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;CLogConsole&lt;br /&gt;&lt;br /&gt;This is an appender that sends messages to System.out and System.err&lt;br /&gt;This the basic Console appender&lt;br /&gt;This appender is only used in Client mode&lt;br /&gt;&lt;br /&gt;CLogFile&lt;br /&gt;&lt;br /&gt;This is a File appender that looks for environment variable COMPIERE_HOME, then create a directory called log in it, then create files of the form&lt;br /&gt;&lt;br /&gt;Compiere2/log/YYYY-MM-DD_X.log where X will begin at 0 and increment &lt;br /&gt;In client Mode the file will have the form&lt;br /&gt;&lt;br /&gt;Compiere2/log/clientYYYY-MM-DD_X.log&lt;br /&gt;This file will only be used if the user, using its Tools / Preferences option, activate the Trace file.&lt;br /&gt;&lt;br /&gt;CLogErrorBuffer&lt;br /&gt;&lt;br /&gt;This a Database appender to the table AD_Issue that only go there for SEVERE and WARNING level&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Compiere Formatter&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;CLogFormatter formats the log output in a static way : date space logger name space message.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Compiere Filter&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;CLogFilter filters the logger name and avoid logging of classes in packages java.*, javax.*, sun.*&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Compiere Logger&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;CLogger is the logger class that is being used by Compiere classes.  It redirects its output to the initialized Handler/Appender defined here.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adding a Log4J Handler/Appender&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The solution I found was to add a 4th appender that will uses Log4j and its possibility to configure by file, not by programming.&lt;br /&gt;My Formatter and Filter can be defined by configuration file.&lt;br /&gt;&lt;br /&gt;Changes to CLogMgt.java - initialize()&lt;br /&gt;&lt;br /&gt;&lt;code lang="java"&gt;&lt;br /&gt;Handler audaxisHandler = new Log4JHandler();&lt;br /&gt;Filter audaxisFilter =  new Log4JFilter();&lt;br /&gt;audaxisHandler.setFilter(audaxisFilter);&lt;br /&gt;addHandler(audaxisHandler);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The Log4JHandler class :&lt;br /&gt;&lt;br /&gt;&lt;code lang="java"&gt;&lt;br /&gt;public class Log4JHandler extends java.util.logging.Handler {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void publish(LogRecord paramLogRecord) {&lt;br /&gt;Logger log4jLogger = Logger.getLogger(paramLogRecord.getLoggerName());&lt;br /&gt;boolean loggable = log4jLogger.isEnabledFor(Log4JUtil.getPriority(paramLogRecord.getLevel()));&lt;br /&gt;if (loggable) {&lt;br /&gt;log4jLogger.log(Log4JUtil.getPriority(paramLogRecord.getLevel()), &lt;br /&gt;paramLogRecord.getMessage(), &lt;br /&gt;paramLogRecord.getThrown());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Compiere does not decide of the Level, Log4J Configuration does.&lt;br /&gt;  */&lt;br /&gt; @Override&lt;br /&gt; public void setLevel(Level level) {&lt;br /&gt;  ;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Finally we have to set the Level on the Logger at the maximum Level, ALL because it is up to the different Handlers to decide if they do the log or not do the log.&lt;br /&gt;If we leave the default level on the CLogger, INFO, we will not be able to DEBUG only on Log4J.&lt;br /&gt;&lt;br /&gt;Change in CLogger.java:&lt;br /&gt;&lt;br /&gt;&lt;code lang="java"&gt;&lt;br /&gt;public static synchronized CLogger getCLogger (String className)&lt;br /&gt;{&lt;br /&gt;...&lt;br /&gt;newLogger.setLevel(Level.ALL); // here the change&lt;br /&gt;manager.addLogger(newLogger);&lt;br /&gt;return newLogger;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Using a small change to CLogMgt I am know able to configure my logging mechanism from Compiere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23085011-4956259571818686320?l=vharcq.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vharcq.blogspot.com/feeds/4956259571818686320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23085011&amp;postID=4956259571818686320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23085011/posts/default/4956259571818686320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23085011/posts/default/4956259571818686320'/><link rel='alternate' type='text/html' href='http://vharcq.blogspot.com/2009/12/compiere-and-logging.html' title='Compiere and Logging'/><author><name>Vincent Harcq</name><uri>http://www.blogger.com/profile/18388927537514218509</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_LBlZeaaGFQU/SyyFqoHq0eI/AAAAAAAAATs/CjVBbHJ8KYw/S220/me.jpeg'/></author><thr:total>0</thr:total></entry></feed>
