Functions | Variables
messagefacility/messagefacility/MessageService/doc/Design_and_maintenance.txt File Reference

Functions

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a LogInfo (for example) is that an error object is formed and sent to the ErrorLog
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends<< x to the MessageSender.In the line LogInfo("myCategory")<< x;one has created a **temporary **instance of LogInfo--this getsdestructed upon completion of the statement.The whole working of LogInfois in that destruction:Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender.The destructor of MessageSender is whereall the action--at the client side--happens.The MessageSender instance owns an ErrorObj on the heap;this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<.The ctor of MessageSender makes a newErrorObj--AND MessageSender NEVER DELETES THAT ErrorObj!!--Instead, the destructor of MessageSender[which, we will remember, isinvoked as soon as the LogInfo("myCategory")<< x;statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side.The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context.[There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode, operand) call on theMessageLoggerQ.The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue(consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj.log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj.(This is necessarysince the run/event of the message issuer is known to the client thread, having been provided by the before-module and before-event callbacks of themessage **service **running in the **client **thread, so this information hadneeded to cross the client/server boundary.) log() then parses the categories string and(if there are multiple categories) invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code;we are not documenting this code here.The effect is to shop the ErrorObj to every destination;in each case thecode for that destination(normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj--completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued.The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID(which contains the run and event numbers) or the list(preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules.Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly.MessageDrop is athread-specific singleton.The following files interact with MessageDrop:In the MessageLogger package:MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package:MessageLogger.ccMessageDrop.h defines a singleton pattern.The(private) default ctor initializes the public data:ModuleName is""runEvent is"pre-events"debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern.This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr< MessageDrop > The latter is a object that may contain several but only one is accessible in this thread The instance () method calls drops.get() to obtain that pointer.Just as for a usual singleton
 
these are all universal (that is, not thread-specific) and are established when the MessageLogger object in MessageService is const ructed
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for MessageLogger (in MessageLogger.cc) if debugModules is empty
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The configure_dest () member of MessageLoggerScribe is invoked(when the CONFIGURE opcode is received) for each destination.In the end
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling under (1) or(2).4-If no information is available at all
 
it is straightforward in comparison to establishing limits The setup for limits (and intervals and timespans) is influenced by the following.cfg information(all of which is optional
 
the code is simple for extract with default of NO_VALUE_SET At this if a value has been we can issue dest_ctrl setLimit (severity, limit)----------purge_mode----------What happends if the act of logging a message(on the server side) throws an exception? This logic is implemented in MessageLoggerScribe.cc. If the exception is a cms::Exception, then for the first 5 times, output is sent to cerr containing the explanation e.what(). After five such exceptions, or for any exception not inherited from cms::Exception, the system is placed into purge_mode, after which no further message processing will occur. ==================== ErrorLogger Workings ==================== Although for the most part the ErrorLogger is not a product of CMS-related work (it is instead taken to be a given starting point for the underpinning of MessageLogger) some tailoring was done in response to CMS-requested features. The workings directly impacted by this tailoring are appropriate to dilscuss in this document. ------------------------------------ Establishment and Checking of Limits ------------------------------------ Limits (and here, we also include intervals in the sense of skipping every N occurences of some type of message) are established in code involving ELadminstrator.cc (just forwarding to ELdestinations) ELdest_control.cc ELdestination.cc and at the MessageLogger level, the establishing calls are initiated by commands from the configure_dest() method in MessageLoggerScribe.cc. There is a wide variety of logical ways the limit and interval can be determined. Although in the ErrorLogger the concept of limits and thresholds is tied to individual distributions, the MessageLogger wrapping allows a configuratoin file to specify overall defaults - in each case, values specific to a destination take precedence over overall defaults. In order of precedence, the rules are: 1) If for a particular destination the category has had a specific limit (interval) set, then that limit (interval) is used. 2) If an overall default limit (interval) has been established for this specific category, then [unless (1) holds] the limit (interval) for this category is taken to be that default value. 3) If for a particular destination the severity of the message has had a specific limit (interval) set, then that limit (interval) is used. Note that for categories explicitly mentioned in the default, this case is not applied, since case (2) would take precedence. 4) If an overall default limit (interval) has been established for this severity level, then [unless (1), (2), or (3) holds] that limit (interval) is used. 5) If for a particular destination a wildcard catgory ("*") has been assigned a limit (interval) and neither the the category nor the severity of this message has had a limit (interval) set, then the limit (interval) used will be that wildcard value. 6) If (1) thru (5) do not hold for a particular destination, but a wildcard catgory has been assigned a limit (interval) in the overall default, then this is used as the wildcard limit (interval) for that destination. 7) If none of the above conditions hold, then the super-default is no limit, and an inteval that causes no skipping. Internally, a value of -1 indicates an infinte limit, and also can indicate an interval that was never given a value. One tricky point in setting up these rules: It is easily possible for a category Pset to appear inside a destination Pset, and for that category Pset to have an interval entry but not a limit entry (or vice-versa). In that case, with regards to limit, the behavior should be as if that category did not appear in this destination. One trap to avoid would be to do int limit = getAparameter<int>(&category_pset,"limit", dest_default_limit)
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate priority (2) above
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and cc (in the MessageLogger module) and ELlimitTable.h and.cc(in MessageService).The rules for deciding--given the limit
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of limits applicable to specific categories for this and counts of how many times a category has been sent to this destination (and how many have been skipped since the last reaction).Each destination owns its own ELlimitsTable
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of limits applicable to specific categories for this and counts of how many times a category has been sent to this l named limits The third type of information is kept in a map of extended ID (that is, severity and category combination) versus CountAndLimit--the latter is a class defined in ELmap.h holding the information that changes with each new message.(The ELstatistics destination also makes use of this class
 
subtleties about methods such as wipe () and zero() apply to statistics and we won't worry about them for now.) This third type of information is kept in a member of ELlimitsTable named counts
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl methods (for example, setLimit()).At first glance
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limit (and timespan and interval) information in the counts data member.This is not the case
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the id (the category, without regard to the severity level).If different default limits for different severities have been set
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established gradually (one further complication is that both are limited in size to some large tableLimit;this is unimportant for CMS).The wat this happens is that the destination derived classes(for example ELoutput) call
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each the add () method of their ELlimitsTable
 

Variables

 Design
 
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more threads
 
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any event
 
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single entity
 
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single the MessageLoggerScribe
 
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single the picks up on these messages and forwards them to the looger one at a time
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client side
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level ELinfo
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends<< x to the MessageSender.In the line LogInfo("myCategory")<< x;one has created a **temporary **instance of LogInfo--this getsdestructed upon completion of the statement.The whole working of LogInfois in that destruction:Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender.The destructor of MessageSender is whereall the action--at the client side--happens.The MessageSender instance owns an ErrorObj on the heap;this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<.The ctor of MessageSender makes a newErrorObj--AND MessageSender NEVER DELETES THAT ErrorObj!!--Instead, the destructor of MessageSender[which, we will remember, isinvoked as soon as the LogInfo("myCategory")<< x;statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side.The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context.[There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode, operand) call on theMessageLoggerQ.The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue(consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj.log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj.(This is necessarysince the run/event of the message issuer is known to the client thread, having been provided by the before-module and before-event callbacks of themessage **service **running in the **client **thread, so this information hadneeded to cross the client/server boundary.) log() then parses the categories string and(if there are multiple categories) invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code;we are not documenting this code here.The effect is to shop the ErrorObj to every destination;in each case thecode for that destination(normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj--completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued.The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID(which contains the run and event numbers) or the list(preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules.Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly.MessageDrop is athread-specific singleton.The following files interact with MessageDrop:In the MessageLogger package:MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package:MessageLogger.ccMessageDrop.h defines a singleton pattern.The(private) default ctor initializes the public data:ModuleName is""runEvent is"pre-events"debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern.This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr< MessageDrop > The latter is a object that may contain several pointers
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends<< x to the MessageSender.In the line LogInfo("myCategory")<< x;one has created a **temporary **instance of LogInfo--this getsdestructed upon completion of the statement.The whole working of LogInfois in that destruction:Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender.The destructor of MessageSender is whereall the action--at the client side--happens.The MessageSender instance owns an ErrorObj on the heap;this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<.The ctor of MessageSender makes a newErrorObj--AND MessageSender NEVER DELETES THAT ErrorObj!!--Instead, the destructor of MessageSender[which, we will remember, isinvoked as soon as the LogInfo("myCategory")<< x;statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side.The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context.[There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode, operand) call on theMessageLoggerQ.The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue(consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj.log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj.(This is necessarysince the run/event of the message issuer is known to the client thread, having been provided by the before-module and before-event callbacks of themessage **service **running in the **client **thread, so this information hadneeded to cross the client/server boundary.) log() then parses the categories string and(if there are multiple categories) invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code;we are not documenting this code here.The effect is to shop the ErrorObj to every destination;in each case thecode for that destination(normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj--completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued.The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID(which contains the run and event numbers) or the list(preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules.Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly.MessageDrop is athread-specific singleton.The following files interact with MessageDrop:In the MessageLogger package:MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package:MessageLogger.ccMessageDrop.h defines a singleton pattern.The(private) default ctor initializes the public data:ModuleName is""runEvent is"pre-events"debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern.This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr< MessageDrop > The latter is a object that may contain several but only one is accessible in this thread The if the pointer is null
 
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends<< x to the MessageSender.In the line LogInfo("myCategory")<< x;one has created a **temporary **instance of LogInfo--this getsdestructed upon completion of the statement.The whole working of LogInfois in that destruction:Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender.The destructor of MessageSender is whereall the action--at the client side--happens.The MessageSender instance owns an ErrorObj on the heap;this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<.The ctor of MessageSender makes a newErrorObj--AND MessageSender NEVER DELETES THAT ErrorObj!!--Instead, the destructor of MessageSender[which, we will remember, isinvoked as soon as the LogInfo("myCategory")<< x;statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side.The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context.[There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode, operand) call on theMessageLoggerQ.The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue(consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj.log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj.(This is necessarysince the run/event of the message issuer is known to the client thread, having been provided by the before-module and before-event callbacks of themessage **service **running in the **client **thread, so this information hadneeded to cross the client/server boundary.) log() then parses the categories string and(if there are multiple categories) invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code;we are not documenting this code here.The effect is to shop the ErrorObj to every destination;in each case thecode for that destination(normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj--completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued.The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID(which contains the run and event numbers) or the list(preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules.Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly.MessageDrop is athread-specific singleton.The following files interact with MessageDrop:In the MessageLogger package:MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package:MessageLogger.ccMessageDrop.h defines a singleton pattern.The(private) default ctor initializes the public data:ModuleName is""runEvent is"pre-events"debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern.This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr< MessageDrop > The latter is a object that may contain several but only one is accessible in this thread The if the pointer is it sets the pointer to a new MessageDrop Thus instance () will always return a pointer to the unique MessageDrop for this thread.Note that the server side has no way to influence or access the MessageDrop for a specific thread
 
thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to false
 
thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event number
 
thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for example
 
thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for finds its way accurately into that other thread even if yet other threads are also issuing messages MessageLogger cc is responsible for filling the data fields of the MessageDrop with needed information MessageLogger cc is in the MessageService
 
thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for finds its way accurately into that other thread even if yet other threads are also issuing messages MessageLogger cc is responsible for filling the data fields of the MessageDrop with needed information MessageLogger cc is in the to avoid introducing a dependency on ModuleDescription into MessageLogger But it is not part of the MessageLoggerScribe thread
 
it is part of the same thread as the issuing message Thus when it sets up information
 
it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided is
 
it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided and sets value of debugEnabled To determine the value to set for debugEnabled
 
it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided and sets value of debugEnabled To determine the value to set for two bools and a vector of module names come into play
 
these are all by getting the vString debugModules
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of MessageLogger
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In particular
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never called
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop originally
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true Also
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and severity
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of application
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these are
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default limit
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are simpler
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are having just an overall default and possible destination specific thresholds A threshold says if a message is below this severity level
 
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is *debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are having just an overall default and possible destination specific thresholds A threshold says if a message is below this severity don t even bother considering reporting it Overall thresholds could in principle even be used at the client level to obviate message preparation in cases where nobody will be reporting the message We will not discuss establishing thresholds any further in theis section
 
for brevity I omit the ubiquitous untracked directives
 
for brevity I omit the ubiquitous untracked containint an overall default limit PSet mydest
 
the naive use of default PSets would have this category assigned no limit And it does not work to just from that category_pset
 
the code is simple for that
 
the code is simple for extract with default of NO_VALUE_SET At this point
 
the code is simple for extract with default of NO_VALUE_SET At this if a value has been set
 
Althouth this seems the obvious thing to do
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this destination
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See above
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring Destinations
 
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and interval
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the however
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly controlled
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be distinct
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each message
 
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each the in a line reading
 
This add method has three purposes
 
This add method has three it adds this message xid and id to the appropriate tables
 
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as follows
 
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit struct
 
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in counts
 
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in see if the category is in limits if so
 
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in see if the category is in limits if the appropriate counts struct can be formed by using the precedence rules above to combine the limit and interval found in limits along with the severityLimits and severityIntervals arrays found in the ELlimitsTable Along the way the limits map for this category is filled in
 
that won t change even if a diffeerent severity i the same category is encountered And now the xid is in counts(unless counts has grown too large).3) Now xid will normally be in counts runEvent
 

Function Documentation

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each the add ( )
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and cc ( in the MessageLogger  module)
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The configure_dest ( )
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of limits applicable to specific categories for this and counts of how many times a category has been sent to this destination ( and how many have been skipped since the last  reaction)
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established gradually ( one further complication is that both are limited in size to some large tableLimit;this is unimportant for  CMS)
static
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of limits applicable to specific categories for this and counts of how many times a category has been sent to this l named limits The third type of information is kept in a map of extended ID ( that  is,
severity and category  combination 
)
new
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the id ( the  category,
without regard to the severity  level 
)
this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration (driven by the .cfg file) is dealt with on the server side. The path looks like this (each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends << x to the MessageSender.In the line LogInfo("myCategory") << x;one has created a **temporary** instance of LogInfo -- this getsdestructed upon completion of the statement. The whole working of LogInfois in that destruction: Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender. The destructor of MessageSender is whereall the action -- at the client side -- happens.The MessageSender instance owns an ErrorObj on the heap; this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<. The ctor of MessageSender makes a newErrorObj -- AND MessageSender NEVER DELETES THAT ErrorObj!! --Instead, the destructor of MessageSender [which, we will remember, isinvoked as soon as the LogInfo("myCategory") << x; statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side. The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context. [There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode,operand) call on theMessageLoggerQ. The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue (consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj. log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj. (This is necessarysince the run/event of the message issuer is known to the client thread,having been provided by the before-module and before-event callbacks of themessage **service** running in the **client** thread, so this information hadneeded to cross the client/server boundary.)log() then parses the categories string and (if there are multiple categories)invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code; we are not documenting this code here.The effect is to shop the ErrorObj to every destination; in each case thecode for that destination (normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj -- completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued. The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID (which contains the run and event numbers) or the list (preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules. Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly. MessageDrop is athread-specific singleton.The following files interact with MessageDrop: In the MessageLogger package: MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package: MessageLogger.ccMessageDrop.h defines a singleton pattern. The (private) default ctor initializes the public data: ModuleName is "" runEvent is "pre-events" debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern. This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr<MessageDrop> The latter is a object that may contain several but only one is accessible in this thread The instance ( )
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limit ( and timespan and  interval)
it is straightforward in comparison to establishing limits The setup for limits ( and intervals and  timespans)
operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a LogInfo ( for  example)
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for MessageLogger ( in MessageLogger.  cc)
subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl methods ( for  example,
setLimit()   
)
static
Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate priority ( )
the code is simple for extract with default of NO_VALUE_SET At this if a value has been we can issue dest_ctrl setLimit ( severity  ,
limit   
)
throws an exception? This logic is implemented in MessageLoggerScribe.cc. If the exception is a cms::Exception, then for the first 5 times, output is sent to cerr containing the explanation e.what(). After five such exceptions,
or for any exception not inherited from cms::Exception,
the system is placed into purge_mode,
after which no further message processing will occur. ==================== ErrorLogger Workings ==================== Although for the most part the ErrorLogger is not a product of CMS-related work (it is instead taken to be a given starting point for the underpinning of MessageLogger) some tailoring was done in response to CMS-requested features. The workings directly impacted by this tailoring are appropriate to dilscuss in this document. ------------------------------------ Establishment and Checking of Limits ------------------------------------ Limits (and here,
we also include intervals in the sense of skipping every N occurences of some type of message) are established in code involving ELadminstrator.cc (just forwarding to ELdestinations) ELdest_control.cc ELdestination.cc and at the MessageLogger level,
the establishing calls are initiated by commands from the configure_dest() method in MessageLoggerScribe.cc. There is a wide variety of logical ways the limit and interval can be determined. Although in the ErrorLogger the concept of limits and thresholds is tied to individual distributions,
the MessageLogger wrapping allows a configuratoin file to specify overall defaults - in each case,
values specific to a destination take precedence over overall defaults. In order of precedence,
the rules are: 1) If for a particular destination the category has had a specific limit (interval) set,
then that limit (interval) is used. 2) If an overall default limit (interval) has been established for this specific category,
then [unless (1) holds] the limit (interval) for this category is taken to be that default value. 3) If for a particular destination the severity of the message has had a specific limit (interval) set,
then that limit (interval) is used. Note that for categories explicitly mentioned in the default,
this case is not applied,
since case (2) would take precedence. 4) If an overall default limit (interval) has been established for this severity level,
then [unless (1),
(2),
or (3) holds] that limit (interval) is used. 5) If for a particular destination a wildcard catgory ("*") has been assigned a limit (interval) and neither the the category nor the severity of this message has had a limit (interval) set,
then the limit (interval) used will be that wildcard value. 6) If (1) thru (5) do not hold for a particular destination,
but a wildcard catgory has been assigned a limit (interval) in the overall default,
then this is used as the wildcard limit (interval) for that destination. 7) If none of the above conditions hold,
then the super-default is no limit,
and an inteval that causes no skipping. Internally,
a value of -1 indicates an infinte limit,
and also can indicate an interval that was never given a value. One tricky point in setting up these rules: It is easily possible for a category Pset to appear inside a destination Pset,
and for that category Pset to have an interval entry but not a limit entry (or vice-versa). In that case,
with regards to limit,
the behavior should be as if that category did not appear in this destination. One trap to avoid would be to do int limit = getAparameter<int>(&category_pset,
"limit",
dest_default_limit
)
these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling under ( )
these are all universal ( that  is,
not thread specific 
) const
subtleties about methods such as wipe ( )

Variable Documentation

Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See above

Definition at line 399 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true Also

Definition at line 191 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of application

Definition at line 216 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these are

Definition at line 216 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never called

Definition at line 191 of file Design_and_maintenance.txt.

the naive use of default PSets would have this category assigned no limit And it does not work to just from that category_pset

Definition at line 291 of file Design_and_maintenance.txt.

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly controlled

Definition at line 431 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in counts
static

Definition at line 451 of file Design_and_maintenance.txt.

it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided and sets value of debugEnabled To determine the value to set for debugEnabled

Definition at line 176 of file Design_and_maintenance.txt.

these are all by getting the vString debugModules

Definition at line 191 of file Design_and_maintenance.txt.

Design

Definition at line 1 of file Design_and_maintenance.txt.

Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of limits applicable to specific categories for this destination

Definition at line 396 of file Design_and_maintenance.txt.

Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring Destinations

Definition at line 399 of file Design_and_maintenance.txt.

for brevity I omit the ubiquitous untracked directives

Definition at line 244 of file Design_and_maintenance.txt.

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be distinct
Initial value:
{Unfortunately, the data member limits, which is an ELmap_limits,
has the same name as the limits data member of ELdestination, which
is an ELlimitsTable. There is ample potential for confusion in that.
Here, we will try to enhance clarity by using the simple name limits
to always refer to the data member of ELlimitsTable -- when we need
to talk about the data member of ELdestination we will always call it
it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided is
it is part of the same thread as the issuing message Thus when it sets up information
This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in see if the category is in limits if the appropriate counts struct can be formed by using the precedence rules above to combine the limit and interval found in limits along with the severityLimits and severityIntervals arrays found in the ELlimitsTable Along the way the limits map for this category is filled in
it is straightforward in comparison to establishing limits The setup for limits(and intervals and timespans) is influenced by the following.cfg information(all of which is optional
How the MessageService Sets Up the Module Name This document describes how the module and any suppression gets where the logger needs it
HOW TO RUN THIS CODE by
the code is simple for that
std::map< std::string, LimitAndTimespan > ELmap_limits
Definition: ELmap.h:81
debug enabled based on file_close watchPostCloseFile *AfterFile Activities having one argument in call
an exception should be thrown only if an ambiguous lookup is attempted It is an error to register more than one *factory function *for any long form name
data member for class that should not be copyable value_ptr< T > sole deep polymorphic data member

Definition at line 434 of file Design_and_maintenance.txt.

Althouth this seems the obvious thing to do

Definition at line 396 of file Design_and_maintenance.txt.

this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration (driven by the .cfg file) is dealt with on the server side. The path looks like this (each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level ELinfo

Definition at line 21 of file Design_and_maintenance.txt.

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single entity

Definition at line 14 of file Design_and_maintenance.txt.

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any event

Definition at line 14 of file Design_and_maintenance.txt.

thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for example

Definition at line 160 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to false

Definition at line 160 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as follows

Definition at line 451 of file Design_and_maintenance.txt.

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the however

Definition at line 428 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in see if the category is in limits if the appropriate counts struct can be formed by using the precedence rules above to combine the limit and interval found in limits along with the severityLimits and severityIntervals arrays found in the ELlimitsTable Along the way the limits map for this category is filled in
static

Definition at line 460 of file Design_and_maintenance.txt.

Althouth this seems the obvious thing to if limit is not present in the category PSet in this it will violate by choosing the default limit established for the destination over the specific limit for that category established overall See in Configuring for the work needed in MessageLoggerScribe to decide how to establish these limits The logic implementing these rules appears in ELmap h and timespan and then number of messages in this category already issued whether to react to a message are discussed below ELlimitTable is responsible for holding three types of information

Definition at line 176 of file Design_and_maintenance.txt.

this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration (driven by the .cfg file) is dealt with on the server side. The path looks like this (each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends << x to the MessageSender.In the line LogInfo("myCategory") << x;one has created a **temporary** instance of LogInfo -- this getsdestructed upon completion of the statement. The whole working of LogInfois in that destruction: Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender. The destructor of MessageSender is whereall the action -- at the client side -- happens.The MessageSender instance owns an ErrorObj on the heap; this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<. The ctor of MessageSender makes a newErrorObj -- AND MessageSender NEVER DELETES THAT ErrorObj!! --Instead, the destructor of MessageSender [which, we will remember, isinvoked as soon as the LogInfo("myCategory") << x; statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side. The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context. [There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode,operand) call on theMessageLoggerQ. The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue (consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj. log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj. (This is necessarysince the run/event of the message issuer is known to the client thread,having been provided by the before-module and before-event callbacks of themessage **service** running in the **client** thread, so this information hadneeded to cross the client/server boundary.)log() then parses the categories string and (if there are multiple categories)invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code; we are not documenting this code here.The effect is to shop the ErrorObj to every destination; in each case thecode for that destination (normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj -- completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued. The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID (which contains the run and event numbers) or the list (preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules. Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly. MessageDrop is athread-specific singleton.The following files interact with MessageDrop: In the MessageLogger package: MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package: MessageLogger.ccMessageDrop.h defines a singleton pattern. The (private) default ctor initializes the public data: ModuleName is "" runEvent is "pre-events" debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern. This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr<MessageDrop> The latter is a object that may contain several but only one is accessible in this thread The if the pointer is it sets the pointer to a new MessageDrop Thus instance() will always return a pointer to the unique MessageDrop for this thread.Note that the server side has no way to influence or access the MessageDrop for a specific thread

Definition at line 150 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate interval

Definition at line 405 of file Design_and_maintenance.txt.

it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided is

Definition at line 176 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are having just an overall default and possible destination specific thresholds A threshold says if a message is below this severity level

Definition at line 227 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate limit

Definition at line 216 of file Design_and_maintenance.txt.

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each message

Definition at line 445 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of MessageLogger

Definition at line 191 of file Design_and_maintenance.txt.

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single the MessageLoggerScribe

Definition at line 14 of file Design_and_maintenance.txt.

thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for finds its way accurately into that other thread even if yet other threads are also issuing messages MessageLogger cc is responsible for filling the data fields of the MessageDrop with needed information MessageLogger cc is in the MessageService

Definition at line 160 of file Design_and_maintenance.txt.

for brevity I omit the ubiquitous untracked containint an overall default limit PSet mydest

Definition at line 245 of file Design_and_maintenance.txt.

this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration (driven by the .cfg file) is dealt with on the server side. The path looks like this (each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends << x to the MessageSender.In the line LogInfo("myCategory") << x;one has created a **temporary** instance of LogInfo -- this getsdestructed upon completion of the statement. The whole working of LogInfois in that destruction: Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender. The destructor of MessageSender is whereall the action -- at the client side -- happens.The MessageSender instance owns an ErrorObj on the heap; this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<. The ctor of MessageSender makes a newErrorObj -- AND MessageSender NEVER DELETES THAT ErrorObj!! --Instead, the destructor of MessageSender [which, we will remember, isinvoked as soon as the LogInfo("myCategory") << x; statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side. The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context. [There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode,operand) call on theMessageLoggerQ. The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue (consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj. log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj. (This is necessarysince the run/event of the message issuer is known to the client thread,having been provided by the before-module and before-event callbacks of themessage **service** running in the **client** thread, so this information hadneeded to cross the client/server boundary.)log() then parses the categories string and (if there are multiple categories)invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code; we are not documenting this code here.The effect is to shop the ErrorObj to every destination; in each case thecode for that destination (normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj -- completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued. The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID (which contains the run and event numbers) or the list (preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules. Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly. MessageDrop is athread-specific singleton.The following files interact with MessageDrop: In the MessageLogger package: MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package: MessageLogger.ccMessageDrop.h defines a singleton pattern. The (private) default ctor initializes the public data: ModuleName is "" runEvent is "pre-events" debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern. This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr<MessageDrop> The latter is a object that may contain several but only one is accessible in this thread The if the pointer is null

Definition at line 149 of file Design_and_maintenance.txt.

thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event number

Definition at line 160 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop originally

Definition at line 191 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In particular

Definition at line 191 of file Design_and_maintenance.txt.

it is part of the same thread as the issuing message Thus when it sets up that info is available for stuffing into the ErrorObj or use in deciding whether to react to a LogDebug The information provided and sets value of debugEnabled To determine the value to set for two bools and a vector of module names come into play

Definition at line 176 of file Design_and_maintenance.txt.

the code is simple for extract with default of NO_VALUE_SET At this point

Definition at line 312 of file Design_and_maintenance.txt.

this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration (driven by the .cfg file) is dealt with on the server side. The path looks like this (each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends << x to the MessageSender.In the line LogInfo("myCategory") << x;one has created a **temporary** instance of LogInfo -- this getsdestructed upon completion of the statement. The whole working of LogInfois in that destruction: Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender. The destructor of MessageSender is whereall the action -- at the client side -- happens.The MessageSender instance owns an ErrorObj on the heap; this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<. The ctor of MessageSender makes a newErrorObj -- AND MessageSender NEVER DELETES THAT ErrorObj!! --Instead, the destructor of MessageSender [which, we will remember, isinvoked as soon as the LogInfo("myCategory") << x; statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side. The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context. [There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode,operand) call on theMessageLoggerQ. The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue (consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj. log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj. (This is necessarysince the run/event of the message issuer is known to the client thread,having been provided by the before-module and before-event callbacks of themessage **service** running in the **client** thread, so this information hadneeded to cross the client/server boundary.)log() then parses the categories string and (if there are multiple categories)invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code; we are not documenting this code here.The effect is to shop the ErrorObj to every destination; in each case thecode for that destination (normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj -- completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued. The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID (which contains the run and event numbers) or the list (preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules. Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly. MessageDrop is athread-specific singleton.The following files interact with MessageDrop: In the MessageLogger package: MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package: MessageLogger.ccMessageDrop.h defines a singleton pattern. The (private) default ctor initializes the public data: ModuleName is "" runEvent is "pre-events" debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern. This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr<MessageDrop> The latter is a object that may contain several pointers

Definition at line 21 of file Design_and_maintenance.txt.

This add method has three purposes

Definition at line 451 of file Design_and_maintenance.txt.

subtleties about methods such as and this is the key information static The information of the first two types is established by calls to ELdestControl it would appear that the information in ELlimitsTable s data members limits is a partial replicate of the limits is accessed by just the then for categories not explicitly these values will be and static the information in counts is established for each the in a line reading

Definition at line 448 of file Design_and_maintenance.txt.

that won t change even if a diffeerent severity i the same category is encountered And now the xid is in counts (unless counts has grown too large). 3) Now xid will normally be in counts runEvent
Initial value:
= Beforevents
preEventProcessing run/event # set up
*externals *admin sets up
unsigned int run

Definition at line 496 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are having just an overall default and possible destination specific thresholds A threshold says if a message is below this severity don t even bother considering reporting it Overall thresholds could in principle even be used at the client level to obviate message preparation in cases where nobody will be reporting the message We will not discuss establishing thresholds any further in theis section

Definition at line 227 of file Design_and_maintenance.txt.

the code is simple for extract with default of NO_VALUE_SET At this if a value has been set

Definition at line 312 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and severity

Definition at line 216 of file Design_and_maintenance.txt.

this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client side

Definition at line 21 of file Design_and_maintenance.txt.

these are all by getting the vString this is set to true if debugModules is non empty everyDebugEnabled_ is a global scope variable instantiated as false in MessageLogger cc In the ctor of this is set to true if nay one of debugModules is* debugEnabledModules_ contains the specified debugModules If debugEnabled is set to then the effect of LogDebug used during that module is to immediately return A subtlety arose concerning the MessageDrop in circumstances where the framework s event processing structure were not in play In if preModule were never then debugEnabled would remain whatever value it had on construction of the MessageDrop the value was left uninitialized Now it is initialized to true in the ctor for we change debugEnabled MessageDrop s debugEnabled to false Configuring Destinations The each destination has its own tables of what to do about each category and but we get various overall defaults fromm the cfg file as well The limit instructions at the MessageLogger level takes on forms in order of priority of these to be used for messages who have no established limit for their specific categries A default to be used for messages not falling then there is no limit and all messages of that type will be reported Thresholds are simpler

Definition at line 227 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit and there will be no need to recompute them If this xid is not yet in see if the category is in limits if so
static

Definition at line 451 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate and it updates the dynamic information in counts The sequence is as the static apppropriate and timespan will be in the mapped CountAndLimit struct
static

Definition at line 451 of file Design_and_maintenance.txt.

This add method has three it adds this message xid and id to the appropriate tables

Definition at line 451 of file Design_and_maintenance.txt.

Definition at line 312 of file Design_and_maintenance.txt.

thus any information present in the drop and needed by the server needs to be added into the ErrorObject that will cross the client server boundary MessageLogger h uses the MessageDrop in the LogDebug macro to learn the value of debugEnabled If debugEnabled is set to then the effect of LogDebug is to immediately return MessageSender cc gets the instance of MessageDrop to find out the moduleName and the runEvent It then places these into the ErrorObject it is forming to pass over to the server This is how the correct event for finds its way accurately into that other thread even if yet other threads are also issuing messages MessageLogger cc is responsible for filling the data fields of the MessageDrop with needed information MessageLogger cc is in the to avoid introducing a dependency on ModuleDescription into MessageLogger But it is not part of the MessageLoggerScribe thread

Definition at line 160 of file Design_and_maintenance.txt.

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more threads

Definition at line 14 of file Design_and_maintenance.txt.

operation and maintenance manual for MessageLogger MessageService General Work Flow of a Message The effect of a user issuing a which has been configured to filter these in some way and to dispatch the messages to one or more destinations This section will outline the steps involved The user code may be running in opne or more each of which might issue messages We will call these the client side In any a single the picks up on these messages and forwards them to the looger one at a time

Definition at line 14 of file Design_and_maintenance.txt.