<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Hi guys,<br>
    <br>
    All System.out calls in drools production code have been replace by
    sl4j-api logging calls.<br>
    The unit tests and the examples use logback (which is the standard
    slf4j-api implementation) to output those calls to the console.<br>
    <br>
    For example:<br>
    2012-08-08 21:23:41,101 [main] INFO  DroolsExamplesApp started.<br>
    <br>
    <b>Where can I configure the logging?</b><br>
    <ul>
      <li>Production code (such as drools-core/src/main/java) isn't
        executed directly and therefor has no logging configuration.<br>
      </li>
      <li>For a unit test, configure your logging desires in
        src/test/resources/logback-test.xml</li>
      <li>For an example application, configure your logging desires in
        src/main/resources/logback.xml</li>
      <li>For a war, configure your logging desires in
        src/main/resources/logback.xml</li>
    </ul>
    <p>Notice that drools-core does not depend on logback (unlike it's
      tests) or any other logging implementation:<br>
      the user can easily bridge the drools logs to his favorite logging
      system (for example with slf4j-jcl).<br>
    </p>
    <b>What can I display in my log?</b><br>
    <br>
    Everything that gets logged, not just from drools, but <i>also from
      any other dependency</i> (*).<br>
    (*) if they don't use slf4j, logging can be unified by bridges (for
    example with jcl-over-slf4j).<br>
    <br>
    Here's an example that logs on debug level of drools and
    springframework and on warn level for all other dependencies:<br>
    <br>
    &lt;configuration&gt;<br>
      &lt;logger name="org.drools" level="debug"/&gt;<br>
      &lt;logger name="org.springframework" level="debug"/&gt;<br>
      &lt;logger name="org.drools.foo.bar.MyReallyVerboseDebugClass"
    level="info"/&gt;<br>
    <br>
      &lt;root level="warn"&gt;<br>
        &lt;appender-ref ref="consoleAppender" /&gt;<br>
      &lt;/root&gt;<br>
    &lt;/configuration&gt;<br>
    <br>
    <b>How do I use logging in my classes?</b><br>
    <br>
    public class MyFoo {<br>
    <br>
        protected static transient Logger logger =
    LoggerFactory.getLogger(MyFoo.class);<br>
    <br>
        public void bar() {<br>
             logger.trace("Something in a loop happened."); <br>
             logger.debug("Something happened"); <br>
             logger.info("DroolsExamplesApp started.");<br>
             logger.warn("That rule is pointless.");<br>
             logger.error("Don't divide by zero.", myException); // it's
    probably better to only throw a RuntimeException to the user code
    and let him log it<br>
        }<br>
    <br>
    }<br>
    <b><br>
      How do I make logging fast?</b><br>
    <br>
    1) Keep the Logger a static field: that way it's creation cost is
    independent of how many instances of your class are created<br>
    <br>
    2) Avoid String concatenating when trace is disabled:<br>
    Slower:<br>
      logger.trace("String a is " + a + " and string b is " + b + ".");
    // slow<br>
    Faster:<br>
      logger.trace("String a is {} and string b is {}.", a, b);<br>
    Because it checks if trace is enabled first, before concatenating
    the String.<br>
    When performance matters, trace logging will be very likely
    disabled.<br>
    <br>
    3) Don't use System.out or System.err.<br>
    Such an operation always synchronizes on a printstream and the user
    is unable to disable that performance cost.<br>
    Use logging instead, so the user can configure it to discard the
    messages and their performance cost.<br>
    <br>
    <b>What best practices should I follow?</b><br>
    <br>
    1) Don't use custom flags to disable/enable logging:<br>
                        boolean hideWarnings = Boolean.getBoolean(
    "drools.schema.hidewarnings" );<br>
                        if ( !hideWarnings ) {<br>
                            System.out.println( "Your SAX parser is not
    JAXP 1.2 compliant - turning off validation." );<br>
                        }<br>
    Just do this instead:<br>
        logger.warn( "Your SAX parser is not JAXP 1.2 compliant -
    turning off validation." );<br>
    which outputs as for example:<br>
       ... org.drools.MySaxParserClass WARN Your SAX parser is not JAXP
    1.2 compliant - turning off validation.<br>
    Now, the user can easily hide that warning in the typical log
    configuration way:<br>
      &lt;logger name="org.drools.MySaxParserClass" level="error"/&gt;<br>
    Instead of having to learn about "drools.schema.hidewarnings" and
    set that parameter somewhere.<br>
    <br>
    2) Prefer logger.debug() (or logger.trace()) instead of
    logger.info().<br>
    Most log messages are not interesting enough to get the level info.
    Fight verbosity.<br>
    A good rule of thumb: Running your code for an hour should not
    output more than 10 info messages if nothing failed.<br>
    <br>
    <b>The logging is too big for my console</b><br>
    <br>
    Use a fileAppender temporary for yourself, but don't add it to the
    default logback-test.xml configuration:<br>
    <br>
      &lt;appender name="fileAppender"
    class="ch.qos.logback.core.rolling.RollingFileAppender"&gt;<br>
        &lt;file&gt;local/log/drools.log&lt;/file&gt;<br>
        &lt;rollingPolicy
    class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"&gt;<br>
         
&lt;fileNamePattern&gt;local/log/drools.%i.log.zip&lt;/fileNamePattern&gt;<br>
          &lt;minIndex&gt;1&lt;/minIndex&gt;<br>
          &lt;maxIndex&gt;3&lt;/maxIndex&gt;<br>
        &lt;/rollingPolicy&gt;<br>
        &lt;triggeringPolicy
    class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"&gt;<br>
          &lt;maxFileSize&gt;5MB&lt;/maxFileSize&gt;<br>
        &lt;/triggeringPolicy&gt;<br>
        &lt;encoder&gt;<br>
          &lt;pattern&gt;%d [%t] %-5p %m%n&lt;/pattern&gt;<br>
        &lt;/encoder&gt;<br>
      &lt;/appender&gt;<br>
    <br>
      &lt;root level="warn"&gt;<br>
        &lt;appender-ref ref="consoleAppender" /&gt;<br>
        &lt;appender-ref ref="fileAppender" /&gt;<br>
      &lt;/root&gt;<br>
    <pre class="moz-signature" cols="72">-- 
With kind regards,
Geoffrey De Smet</pre>
  </body>
</html>