 
 The CMS MessageLogger Service is meant to allow code to log messages to a unified message logging and statistics facility. While reasonable default behaviors are provided, the behavior of the MessageLogger can be adjusted via lines in the job's configuration file (.cfg).
 
The typical user may not be interested in specifying limits of how many times
messages of types will be displayed.  
 By default, the MessageLogger service
will impose a limit of 5 occurrences of each category of 
LogInfo messages, except for framework event messages which will be 
unlimited. 
output to each destination every messages meeting the severity threshold 
criteria specific for that destination.  In fact, the user need not specify
any thresholds; then every message will be output.  And if the user does not
specify any destinations, then a single destination of cerr is assumed.
 
In the near future, concepts for establishing and/or controlling a destination
involving the  log4cplus  service may also
be listed here.
 
Even if LogDebug messages are not rapidly discarded, destination have
a default threshold of  
This user, however, desires more selectivity.
The next two lines establish that for any category of messages 
without its own limit specification, if the message has severity 
INFO or DEBUG, use a limit of zero (which means don't report those
messages).  Finally, the .cfg file overrides this for messages in the
category interestingToMe, permitting messages of
that category to be reported.
 
 
The .cfg file contains not only a list of files, but also a list of message 
ID's that the author wishes to control individually.
 
If this is not the desired behavior (for example, if the output file will be 
processed by an automated parsing tool which prefers each message to be on a
single line) then this can be controled in the .cfg file:
 
       Message Logging Concepts 
To understand what sort of flexibility is available, it is useful to 
be familiar with the following concepts:
    The MessageLogger is capable of routing messages to multiple 
    Destinations.  
    The behavior -- the nature of which messages would appear 
    and which would be ignored -- can be controlled for each destination.  
    At present, two types of destinations are supported:  
    
    
  Each message is given a category when issued.  This is intended to represent
  what this message is about.  For example, several messages
  with different detailed content could all be of type tracking.
  Limits can be imposed on the reporting of messages in a given category,
  and statistics can be obtained by category.
  
  LogDebug, 
  edm::LogWarning, 
  edm::LogInfo, and
  edm::LogError produce messages with severity 
   DEBUG, 
   WARNING, 
  INFO, and
  ERROR respectively.  
  These are ordered with DEBUG as the lowest
  severity and ERROR as the highest.  
  
  For any given destination, the .cfg file can specify that every
  message with a severity lower than a given threshold
  shall be ignored.  
  By default, a destination will have a threshold of
  INFO; responses to messages issued via LogDebug
  can be enabled by setting a threshold to DEBUG.
   
  
  For each message category, 
  or for messages in general, or for a specified severity
  level, the .cfg file can instruct the logger to ignore messages after some
  number (the limit) have been encountered.  
  (Actually, beyond the applicable limit, an occasional further message will
  appear, based on an exponential backoff.  Thus, if the a limit is set at 
  5, and 100 messages of that id are issued, then that destination will react
  to the messages number 1, 2, 3, 4, 5, 10, 15, 25, 45, and 85.)  A limit of
  zero will disable reporting that category of messages.
  
  When a limit is set, it is possible to specify that if no occurrences of that
  type of message are seen in some number of seconds (the 
  timespan), then the count toward that limit is to 
  be reset.  Thus if you wish to suppress most of the thousands of warnings of
  some type expected at startup, but would like to know if another one happens
  after a gap of ten minutes, this can be specified as a timespan of 600.
  
 Routine MessageLogger Parameters 
The following is a portion of a .cfg file requesting the MessageLogger
Service, and setting up setting a destination which will write messages
to the file messages.txt.  The default threshold
and limits will apply:  No LogDebug messages will be reported, and 
only the first five messages of each category will be reported.
process TEST = 
{
  service = MessageLoggger { vstring destinations = { "messages.txt" } }
}
 Example .cfg File Exercising Some Options 
The following is an example .cfg file, requesting the MessageLogger
Service, setting up some destinations, and specifying some thresholds
for how "severe" a message must be in order for it to appear in each
destination.
process TEST = {
  service = MessageLogger {
    vstring destinations = {   "detailedInfo.txt"
                             , "critical.txt"
                             , "cout"
                             , "cerr"
                      }
    PSet critical.txt     = { string threshold = "ERROR"   }
    PSet detailedInfo.txt = { string threshold = "INFO"    } 
    PSet cerr             = { string threshold = "WARNING" }
  }
  untracked PSet maxEvents = {untracked int32 input = 5}
  path p = { myAnalysisModule }
  module myAnalysisModule = ModuleThatIssuesMessages { }
  source = EmptySource { }
}
 Enabling LogDebug Messages 
The following is a portion of a .cfg file appropriate for a job that will
run code instrumented with many LogDebug messages.  This hypothetical user
cares only about those LogDebug messages in the category 
interestingToMe and, in this file, prefers not
to see any other LogDebug or LogInfo messages.
process TEST = 
{
  service = MessageLoggger 
  {
  vstring destinations   = { "debugmessages.txt" }
  vstring categories     = { "interestingToMe" }
  vstring debugModules   = { "*" }
  PSet debugmessages.txt = { string threshold = "DEBUG"
                             PSet INFO  = { int32 limit = 0 }
                             PSet DEBUG = { int32 limit = 0 }
			     PSet interestingToMe = {int32 limit = 10000000}
  } 
}
By default, all LogDebug messages issued from any modules would be
rapidly discarded.  This user chooses to enable the LogDebug messages
issued by all modules, via  
vstring debugModules   = { "*" }.  (Instead,
LogDebugs from a set of specific modules could be enabled; see
 
Controlling LogDebug Behavior: Enabling LogDebug Messages  for details.
INFO, so no LogDebug messages would be
reported.  
Here, for the debugmessages.txt destination, 
the user causes LogDebug messages to be reported by 
string threshold = "DEBUG".
If the PSet for debugmessages.txt were to end there,
all LogDebug messages would be reported by this destination.
 Routing Messages to log4cplus 
The MessageLogger will route messages to log4cplus
if the .cfg file requests the MLlog4cplus service.
The following is an example .cfg file, requesting the 
MLlog4cplus
service, and specifying a threshold
for how "severe" a message must be in order for it to be routed to 
log4cplus.
process TEST = {
  service = MLlog4cplus
  service = MessageLogger {
    vstring destinations = {   "detailedInfo.txt"  }
    PSet log4cplus     = { string threshold = "ERROR"   }
  }
  untracked PSet maxEvents = {untracked int32 input = 5}
  path p = { myAnalysisModule }
  module myAnalysisModule = ModuleThatIssuesMessages { }
  source = EmptySource { }
}
The four severities of MessageLogger messages correspond to the four 
directives for issuing to log4cplus.  For instance,
LogWarning("category") leads to a LOG4CPLUS_WARN(...)
call.
log4cplus dispatches to "appenders". For example, a 
fileAppender may be established to write the text to 
a file, or a consoleAppender to write to the job console.
It is up to the user code or configuration file to establish which
appenders are wanted.
In the current implementation, 
the MLlog4cplus service automatically
establishes a fileAppender writing log4cplus.ouput.
 Examples of Limits and Timespan Parameters  
The following is an example .cfg file, requesting the MessageLogger
Service, setting up some destinations, and specifying some  
choices for thresholds, and for limits and timespans applicable 
to severities, to specific
message ID's, and to all non-specified (default) message ID's.
process TEST = {
  service = MessageLogger {
    vstring destinations = { "detailedInfo.txt"
			   , "critical.txt"
			   , "jobdebug.txt"
			   , "anotherfile.txt"
			   , "cout"
			   , "cerr"
			   }
    vstring categories = { "unimportant"
			 , "trkwarning"
 			 , "serious_matter"
                         }
    PSet critical.txt = { string threshold = "ERROR"
                              PSet default = { int32 limit    = 10
			                       int32 timespan = 180
					     }
			      PSet serious_matter = { int32 limit = 100000 }
                        }
    PSet detailedInfo.txt = { string threshold = "INFO"
			      PSet default        = { int32 limit    =  10
					              int32 timespan =  60
					            }
			      PSet WARNING        = { int32 limit    = 100
			                              int32 timespan =  60 
					            }
			      PSet ERROR          = { int32 limit    = 100
			                              int32 timespan =  60 
					            }
			      PSet trkwarning     = { int32 limit    = 20
			                              int32 timespan = 1200
						    }
			      PSet unimportant    = { int32 limit    = 5 }
			      PSet serious_matter = { int32 limit    = 1000000 }
                            }
    PSet cerr     = { string threshold = "WARNING" }
    PSet jobdebug.txt =     { PSet default        = { int32 limit    = 1000000 }
                            }
    PSet anotherfile.txt =  { PSet serious_matter = { int32 limit    = 1000 } 
                            }
    PSet default = { int32 limit    = 10
                     int32 timespan = 60
		   }
  }
  untracked PSet maxEvents = {untracked int32 input = 10}
  path p = { sendSomeMessages }
  module sendSomeMessages = MessageLoggerClient { }
  source = EmptySource { }
}
 Adjusting Linebreak Policy  
By default, output destinations format the message, breaking the text (at
boundaries where there was a new item of information or an operator<<)
to avoid lines of greater than 80 columns.
process TEST = {
 service = MessageLogger {
    vstring destinations = {   "detailedInfo.txt"
                             , "critical.txt"
                           }
    PSet critical.txt     = { bool noLineBreaks = true   }
    PSet detailedInfo.txt = { int32  lineLength = 132    } 
  }
  untracked PSet maxEvents = {untracked int32 input = 5}
  path p = { myAnalysisModule }
  module myAnalysisModule = ModuleThatIssuesMessages { }
  source = EmptySource { }
}

      Mark Fischler
Last modified: December 1, 2005