|
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 |
|
|
| 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 |
|