742ad2095cf9bc35664acb140cdcbf3eec80fa19
[anna.git] / TraceLevelChecker.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_core_tracing_TraceLevelChecker_hpp
10 #define anna_core_tracing_TraceLevelChecker_hpp
11
12
13
14 #include <anna/core/tracing/Logger.hpp>
15
16 // STL
17 #include <string>
18
19
20
21 namespace anna {
22
23 namespace tracing {
24
25
26
27 /**
28 * Helper class used for selective tracing
29 */
30 class TraceLevelChecker {
31
32
33   anna::Logger::Level a_previousLevel; // backup level to be restored at destructor
34   std::string a_contextData;
35
36 public:
37
38
39   /**
40   * Constructs one class instance providing the context data to be compared with current configuration
41   * trigger references. Depending on changeLevelCondition(), certain trace level will be assigned. Trace level is
42   * preconfigured on global Configuration class for each trigger item, but changeLevelCondition() re-implementation
43   * could modify this behaviour (i.e. fix to debug level for all situations).
44   * That easy... just like that: build instance wherever you want to check context to decide a trace level change.
45   *
46   * Is possible to detect several concepts with a little imagination. For example, if you want to change
47   * trace level when MSISDN is 609555555 and ServiceId is greater than 3, you could do something like this:
48   *
49   * <pre>
50   *    1) Set the trigger (usually this is done at general configuration, oam commands, etc):
51   *    (Configuration::instantiate()).activateTraceTrigger("609555555#3"); // only one trigger item (more didactic)
52   *
53   *    Triggers are strings, then multi-concept contexts requires token management or something similar.
54   *
55   *    2) Create the child class with specific condition method:
56   *    2.1) MyTraceLevelChecker_WithMsisdnAndserviceIdLessThanValue inherit from TraceLevelChecker
57   *    2.2) MyTraceLevelChecker_WithMsisdnAndserviceIdLessThanValue::changeLevelCondition() reimplementation:
58   *          Tokenize ('#' separator) both context data and reference trigger item:
59   *          a) extract 'contextMSISDN' from 'contextData'
60   *          b) extract 'contextSERVICEID' from 'contextData'
61   *          c) extract 'MSISDNreference' (see Configuration::getTraceTriggerMap())
62   *          d) extract 'SERVICEIDreference' (idem)
63   *          e) Return condition: (contextMSISDN == MSISDNreference) && (atoi(contextSERVICEID) > atoi(SERVICEIDreference))
64   *
65   *    3) Plan selective trace on application handler (data receive, context expiration, etc.):
66   *    std::string contextChain = msisdn; contextChain += "#"; contextChain += anna::functions::asString(serviceId);
67   *    MyTraceLevelChecker_WithMsisdnAndserviceIdLessThanValue tlc (contextChain);
68   *
69   *    Normally, only one concept like MSISDN is compared, and the list of triggers references has only one item.
70   * </pre>
71   *
72   * @param contextData String to be compared. If NULL provided, no checkings will be done now (use load() instead)
73   * and empty string will be prepared for future load() calls without context data specification.
74   *
75   * @see load()
76   */
77   TraceLevelChecker(const char * contextData = NULL) {
78     a_previousLevel = anna::Logger::getLevel(); // protection (si por error no se usara el load() nunca, el destructor podria alterar el nivel de traceo del proceso)
79     a_contextData = contextData ? contextData : "";
80
81     if(contextData) load(contextData);
82   }
83
84
85   /**
86   * Destructor restores initial context trace level
87   *
88   * This apply when application finish the execution scope or when exceptions are launched anywhere.
89   *
90   * @see restore()
91   */
92   ~TraceLevelChecker() { restore(); }
93
94
95   /**
96   * Defines the condition between the context information and global Configuration class trigger references.
97   * Target trace level when condition is true, is preconfigured for each trigger reference, but this method
98   * could be reimplemented to fix to debug level ignoring global Configuration class trigger preferences.
99   *
100   * Default implementation check incoming context data to be the same as any of the global Configuration
101   * class trigger references registered. Specific implementation could check that context data contains
102   * any of the trigger reference, or perhaps use regular expressions to be more flexible.
103   *
104   * @param contextData String to be compared
105   * @param targetLevel Desired target level configured for each trigger item at global Configuration class
106   */
107   virtual bool changeLevelCondition(const std::string & contextData, anna::Logger::Level & targetLevel) const throw();
108
109
110   /**
111   * Performs trace level checkings for context data provided.
112   * Gives higher control over the funtionality: using with restore(), application can fix tracing
113   * zones, but in most cases constructor & destructor are enough for normal behaviour (more simply and secure).
114   *
115   * Multiple calls to this method could provide OR operation regarding trace level changes with context data
116   * strings loaded, but this is unusual because implies assume same nature for different context indicators.
117   * Then, be careful if data passed is not sure to be the same when application manage different tracing zones
118   * with restore().
119   *
120   * @param contextData String to be compared. If NULL provided (default-missing parameter call), last valid
121   * assignment (within constructor or former load() call) will be used.
122   *
123   * @return Boolean about trace level change because of condition result
124   */
125   bool load(const char * contextData = NULL) throw();
126
127
128   /**
129   * Do the same than destructor.
130   * Gives higher control over the funtionality: using with load(), application can fix tracing
131   * zones, but in most cases constructor & destructor are enough for normal behaviour.
132   *
133   * @return Boolean about Trace level change because restore proceed
134   */
135   bool restore(void) throw();
136 };
137
138 }
139 }
140
141 #endif