***************************************************************
     ***************************************************************
     ****                    STAR logger:                       ****  
     ****     The STAR offline logger-based message manager     ****
     ***************************************************************
     ***************************************************************
STAR logger is a the logger-based implementation of STAR message manager interface

Table of Contents:

Integration log4j package for STAR framework

Integration of the log4j packages and STAR offline framework was straightforward due to an already existing OO design for processing message streams. For the STAR C++ production code the C++ version of the logger, so-called log4cxx was chosen.

Most (if not all) components of the STAR production framework send their log messages to the abstract STAR messenger. To merge the STAR existing framework with the log4j package, it was only a matter of creating another implementation of the STAR messenger interface - StLoggerManager. Additionally, to meet the STAR production needs, a standard set of the logger appender and filter features were either developed or enhanced. We added one extra appender to communicate with the STAR production MySQL database, namely StMySQLAppender, and created a custom logger filter, StarOptionFilter. to be able to select/suspend the messages according to the STAR production manager's criteria. Once again, and due to the already existing OO messenger implementation in the STAR production system, enabling the new scheme does not require modifying any existing piece of the STAR code. It is sufficient to dynamically load the new implementation (see LoadLogger.C macro and provide an external XML configuration file for the logger as needed.

"Loggers" for STAR Makers

With the new implementation, the STAR framework initiates two common loggers: "BFC" and "QA" and each STAR StMaker subclass instantiates its own logger. The logger name is the subclass class name. This allows to set the logger list of appenders, filters and level of the severity for entire production chain or / and for each STAR maker subclass separately. The end user code is not to worry about the proper selection of the appropriated logger. The user via set of the CPP macro or via the gMessMgr global pointer communicate with the so-called "current logger". The base StMaker class internally governs the logger selection to make sure the current logger matches the logger of the current active StMaker instance.

Global "Loggers": "BFC" and "QA"

The STAR software infrastructure provides two default global loggers. Since both "QA" as well as "BFC" are the normal loggers it can be provided with the dedicated filters, layouts, and appenders to customize it output.

The STAR logger default parameters

By default The default values for the logger components can be set via the optional logger configuration XML file also.

New macros

The base STAR message manager abstract interface was improved to provide better performance. It is recommended now instead of the direct using of the Messager global pointer one should apply the CPP macros as follows: are followed by the C++ output "stream" elements and ended up with the "endm" object. For example, to direct the message to the "error" logger on needs:
   { LOG_ERROR << "My error message" << endm; }
Attention !!! Keep in mind the LOG_ERROR is a CPP macro with if C++ statement inside. This means you should surround it with the curly brackets if the macro is used inside of another if statement.

For example:

    if ( a > 0)
       LOG_ERROR << "the variable is positive" << endm;
     else 
       LOG_INFO << "the variable is Ok" << endm;
will not work as one expects. To get the desirable effect you need
    if ( a > 0) {
       LOG_ERROR << "the variable is positive" << endm;
    } else {
       LOG_INFO << "the variable is Ok" << endm;
    }
instead.

Are you curious why very this implementation was chosen? Please, read some extra pages.

The macros above provide an extra benefit to develop and use your code with no logger at all. Just add into your implementation the lines as follows:

or something like this.

How to use the manager

To use the STAR message manager your code has to contain the STAR message manager interface header file:
    #include "StMessMgr.h" 
  
and use that interface CPP macros

By default STAR "root4star" framework works with the old STAR message manager implementation.

To turn the new one one should load the extra shared library. The ROOT macros LoadLogger.C does just that. This means to instantiate the new logger it is enough to call "LoadLogger.C" followed by you your ROOT macro invocation.

However for bfc.C the new interface is set as "default". To tune it off and use the old version one should apply "-logger" option

     >root4star
     root4star[0] .x bfc.C(1, ". . . -logger", . . .  )
   

As soon as the new logger is loaded the output files, format and level of the verbosity may be defined by the external Logger configuration file. It recommended to avoid using any method of the STAR message manager describing with document and use the macros mentioned above only. This is to make the ocde free of the run-time and compilation time parameters this can be defined via the logger configuration file.

In the other words the author of the code should not apply the "Advanced methods" described by "Section II" from the use code as soon as this can be done outside of the code at run-time.

It is enough to define the desirable messages and its level. All other features can be ordered with the configuration file at run-time without any needs to change and re-compile the code.

How to configure

To overwrite the STAR default output logger configuration one can provide the custom configuration with the file in XML format, "log4j.xml", in the current working directory. The custom name and directory for the logger configuration file can be provided via ROOT resource file. One may add to his/her ".rootrc" file the line:
   Logger.Configuration     $STAR/StRoot/StStarLogger/doc/HardQuota.xml
to do that.
(About ".rootrc" see: ROOT User's Guide v4.04.
Chapter 2. Getting Started. Section Environment Setup, page 21.

One can alternate the default configuration file name and its location via STAR_LOGGER_PROPERTY environment variable as well.

For example, the file "log4j.xml" defines the "Console output" for entire STAR production chain and the "Debug" level of the messages.

"Jakarta log4j" is a community-supported project that includes the log4cxx, log4c, and log4perl packages (thereby supporting multiple computing languages) The output media and format and level are configured by providing the set of the different parameters via the external configuration file (of course we do provide the reasonable default. If one is happy with that no extra file is required). For all STAR StMaker subclass at once or /and for each separate subclass one may define the desirable output by combining 4 different logger components:

These four types are necessary to empower the developers with the capabilities to log messages according to message type and level, to control at runtime how these messages are formatted, and lastly to decide where they are reported.

For each logger one can define the "priority value" (message level) and the arbitrary number of the different appenders. For the standard levels, we have

DEBUG < INFO < WARN < ERROR < FATAL. 
For each appender one can specify one layout if any and arbitrary number of the filters. The different "loggers" can share the appenders explicitly as an xml "appender-ref" parameter defines. The "appenders" can be shared implicitly, since the "children" loggers inherit the "parent" appenders and other attributes "by default" (see: Short Introduction to log4j for the futher information)

The C++ version of the package provides the ready-to-eat components to choose from: See: http://logging.apache.org/log4cxx

The layout may be supplied with the custom format string.

  Formats:
     %c  - logger name %c{2} = b.c  ( a.b.c. )
     %d  - date        %d{%H:%M:%S} or %d{%d %b %Y %H:%M:%S}. 
                        a - short week date name, A - full week date name
                        b - short month name,     B - full month name  m - month number (1-12)
                        d - day of the month
                        H - hours (0-23)          I - hours ( 1 - 12)
     %F  - the file name where the logging request was issued
     %l  - location information of the caller which generated the logging event
     %L  - the line number from where the logging request was issued
   
     %m  - the application (user) supplied message associated with the logging event
   
     %n  - the platform dependent line separator character or characters ("newline" symbol)
     %p  - the level(priority) of the logging event
     %r  - the number of milliseconds elapsed since the start 
     %x  - the NDC (nested diagnostic context) 
   
"By default" STAR message manager uses the "pattern layout" with the format:
        PatternLayout("%-3c{2}:%-5p - %m%n"));
   
According the format and layout that prints out:

Examples:

      QA :INFO  - Output root file name gtrack.root
   
      BFC:INFO  - StTpcDbMaker::Using any drift velocity
   
      BFC:WARN  -  Validity:19980101/0  -----   20010710/5436
   

"Print statement" transition

To enjoy the new logger feature one should replace the "regular" C++ I/O stream output statement or C output function with that calling the loggers. This transition is simple and straightforward.

Make sure your source code contains the STAR "Message Manager Interface" header file

    #include "StMessMgr.h" 
  

"C++" output stream statements

If you use the C++ output streams like "cout", "cerr" to get an access to the logger it is enough to For example, replace of your plain C++ statement:
          cout << "DbFill: structure: " << structName << endl;
   
with
      { LOG_INFO << "DbFill: structure: " << structName << endm; }
   
It is safe to add these macro to your code. You still will be able to use and compile your code with no logger with a simple addition.

"C"output subroutines

Use the "Form" ROOT method to simplify your programs transition those contain the C-language output subroutines like "printf" or "fprintf". You may add the appropriated logger macros followed by the former printf statement followed by "endm" object and semicolon and replace the name of the C subrotuine (for example printf) with the Form method. Don't forget to remove the end-of-line symbol ( "\n" ) from the format string.

For example, to enable "logger", the line

   printf(" %d pre and %d post crossing data available\n",numberOfPreXing(),numberOfPostXing());
   
may be replaced with
 {
   LOG_DEBUG <<
      Form(" %d pre and %d post crossing data available",numberOfPreXing(),numberOfPostXing())
             << endm;
 }
   

STAR "Message Manager"

Since the "logger" is another implementation of the STAR "Message Manager" abstract interface, the existing invocations of the manager should work with the new "log4cxx" implemenation without any change. However some functions became redundand and they are deprecated. Calling others should be adjusted for the sake of the consistency.

For example, the expression

       gMessMgr->Error() << "StZdcVertexMaker::Init():  in ZdcVertexMaker did not find ZdcCalPars." << endm;
   
can be replaced with
      { LOG_ERROR << "StZdcVertexMaker::Init():  in ZdcVertexMaker did not find ZdcCalPars." << endm; }
   
and versa verse.

Run time level control

The default parameters of the loggers are provided either by default or via the logger configuration file at start time. At run-time the parameters can be changed with the log4cxx API. However the the level of the logger associated with each StMaker instance can be set with the StMaker::SetDebug method as well.

StMaker::SetDebug parameterLogger level
<-4FATAL
kFatal=-4FATAL
kError=-3ERROR
kWarning=-2WARN
kInfo=-1INFO
kDefault=0STAR default
kDebug=1DEBUG
kDebug2=2DEBUG
> 2DEBUG
StMaker::SetDEBUG method is to propagate the message level to all its child Makers as usually.

ROOT messages handling

The messages generated by the ROOT system are handled by the messagger also. ROOT distinguishes 6 levels of the messages. They are mapped to the appropriated logger level (see table) and redirected to the current active logger. This means the logger appender and filters are to handle the messages generated by ROOT classes as soon as the ROOT methods are called by the said maker.

ROOT levelLogger
InfoInfo
WarningWarning
ErrorError
Break Fatal
SysErrorFatal
FatalFatal

In addition the standard ROOT approach to define the severity of the ROOT messages is applied as well. Namely, one still can define it via "ROOT Environment" providing the line

    Root.ErrorIgnoreLevel   Info
 
alike within his/her custom ".rootrc" file. The ROOT rule is applied first.

Examples of the custom configuration files (under construction yet)

The example of the configuration files below are available to copy from $STAR/StRoot/StStarLogger/doc directory or from STAR CVS repository SkipMessages.xml

Underwater stones

Pay your attention to some non-obvious properties of the logger objects.

Deprecated methods

Some redundant functions described by
Section II. Advanced features, namely,
still remain of the part of the STAR messager interface. However they are deprecated because they do allow to change the logger functionality from within the code. This way, it may have interfered with the options ordered through the configuration file. The presence of these functions do not cause any run-time / compile error. However it does not lead to the expected behavior either. One is advised to remove the invocations of these functions from his/her code and use the "xml" configuration file instead.
You are -th visitors.

Maintainer: Valeri Fine