FesaLogger.h

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 #ifndef __FesaLogger__H__
00003 #define __FesaLogger__H__
00004 
00005 #include <unistd.h>
00006 #include <stdio.h>
00007 #include <string>
00008 #include <fstream>
00009 #include <iomanip>
00010 #include <signal.h>
00011 
00012 #include <fesa-core/Diagnostic/TimeStampCounter.h>
00013 #include <fesa-core/Diagnostic/UdpLogger.h>
00014 #include <fesa-core/Utilities/Mutex.h>
00015 #include <fesa-core/DataStore/AbstractDevice.h>
00016 
00017 /* -------------------------------------------------------------------------
00018  * Names used to instantiate Error reporting loggers
00019  * Logging message format:
00020  * Sender|Type|Source|Class|Thread|Count|Time|Name|Action|<message>
00021  *
00022  * Static information (used as FesaLogger identification):
00023  * Sender       : which code the logging comes from (FWK, USR) - insert by macro
00024  * Type         : type of the logging (ERROR, TRACE)
00025  * Source       : logging category (MAIN, RT, SRV, EVT, NOTIF)
00026  * Class        : name of the concerned class (used for shared server)
00027  * Thread       : identification of running thread
00028  *
00029  * Dynamic information:
00030  * Count        : log counting, one individual counter per FesaLogger
00031  * Time         : time-stamping (RTSC ys) of the logged message
00032  * Name         : name of the event, action, ..
00033  * Action       : standard action (CREATE, DELETE, START, STOP, ..)
00034  * <message>: extra message, debug, ..
00035  */
00036 
00037 /* -------------------------------------------------------------------------
00038  */
00039 // to log a error (without condition)......................................
00040 #define LOGERROR(severity) pLog->logError(fesa::FesaLogger::severity)
00041 #define FWK_LOGERROR(severity) pLog->logError(FesaLogger::severity, FesaLogger::FWK_SENDER)
00042 
00043 // to log a trace for a particular TOPIC ...................................
00044 #define LOGTRACE(topic) if (pLog->isEnabledFor(topic)) *pLog
00045 #define FWK_LOGTRACE(topic)     if (pLog->isEnabledFor(FesaLogger::topic)) *pLog
00046 
00047 // to log a trace for a particular TOPIC and particular device .............
00048 #define LOGTRACE_DEVICE(topic, pdev) if (pLog->isEnabledFor(topic, pdev)) *pLog
00049 #define FWK_LOGTRACE_DEVICE(topic, pdev) if (pLog->isEnabledFor(FesaLogger::topic, pdev)) *pLog
00050 
00051 namespace fesa
00052 {
00053 
00054     // //Diagnostic State counting information
00055     // typedef struct
00056     // {
00057     //         unsigned long last_;
00058     //         unsigned long current_;
00059     //         unsigned long max_;
00060     // } DiagStateCounter;
00061 
00062     const std::string defaultLogName = "DLT";
00063     const std::string rtLogName = "RT";
00064     const std::string srvLogName = "SRV";
00065     const std::string evtLogName = "EVT";
00066     const std::string notifLogName = "NOTIF";
00067     const std::string bgrNotifLogName = "BGR_NOTIF";
00068     const std::string rdaLogName = "RDA";
00069     const std::string persLogName = "PSTCY";
00070 
00071     const std::string undefinedClassName = std::string("-");
00072     const std::string undefinedThreadName = std::string("-");
00073     const std::string undefinedFunctionName = std::string("-");
00074 
00075     class FesaLoggerBuffer;
00076 
00077     /* -------------------------------------------------------------------------
00078      */
00079     class FesaLogger: public std::ostream
00080     {
00081 
00082         public:
00083             /* Define the log sender: first part of the message header
00084              * FWK: message coming from Framework code
00085              * USR: message coming from custom code
00086              */
00087             static const std::string fwkSender;
00088             static const std::string usrSender;
00089 
00090             // enum DiagState
00091             // {
00092             //     //Define specific action to be activated on RT process during Diagnostic setting (diag
00093             //         initDiag = 1 << 0,
00094             //         startDiag = 1 << 1,
00095             //         stopDiag = 1 << 2,
00096             //         requestState = 1 << 3,
00097             //         updateFwkTopic = 1 << 4,
00098             //         updateCustomTopic = 1 << 5,
00099             //         updateTsPeriod = 1 << 6
00100             // };
00101 
00102             enum DIAG_FWK_TOPIC
00103             { // 32 bits available
00104                     getActionProfiling = 1 << 0,
00105                     setActionProfiling = 1 << 1,
00106                     rtActionProfiling = 1 << 2,
00107                     eventProfiling = 1 << 3,
00108                     notificationProfiling = 1 << 4,
00109                     getActionTracking = 1 << 5,
00110                     setActionTracking = 1 << 6,
00111                     rtActionTracking = 1 << 7,
00112                     eventTracking = 1 << 8,
00113                     notificationTracking = 1 << 9,
00114                     persistencyTracking = 1 << 10,
00115                     transactionTracking = 1 << 11,
00116                     subscriptionTracking = 1 << 12,
00117                     signalHandlerTracking = 1 << 13,
00118                     rdaTracking = 1 << 15,
00119                     startUpTracking = 1 << 31
00120             };
00121 
00122             /* Define the type of logger:
00123              * ERROR for Error and warning reporting
00124              * TRACE for Trace and debugging
00125              * Different type allow to use appropriate communication channel (syslog Logging, udp logging, ..)
00126              */
00127             enum LogType
00128             {
00129                 errorType = 0,
00130                 traceType = 1
00131             };
00132 
00133             /* Define the type of logger:
00134              * ERROR for Error and warning reporting
00135              * TRACE for Trace and debugging
00136              * Different type allow to use appropriate communication channel (syslog Logging, udp logging, ..)
00137              */
00138             enum LogSeverity
00139             {
00140                 //absolute value used beacause of rda redefinition conflict (to be fixed from RDA)
00141                 //all these LogSeverity are from the syslog() standard!!
00142                 fatal = 0, //LOG_EMERG     -system crashed
00143                 alert = 1,              //LOG_ALERT: urgently to do some actions.Only use in worst case !! Since the log messages is spreaded to all open consoles of the system
00144                 critical = 2,   //LOG_CRIT: critical error, from syslog() standard
00145                 error = 3,              //LOG_ERR: error, from syslog() standard
00146                 warning = 4,    //LOG_WARNING: warning from syslog() standard
00147                 notice = 5,     //LOG_NOTICE: important Message
00148                 none = 6,               //LOG_INFO: for Trace logging. Normal message
00149                 debug = 7
00150             };
00151 
00152             //Define action for USR traces to be displayed in the profiler
00153             //In case of modification, don't forget to update 'logActionStr' string-table.
00154             enum LogAction
00155             {
00156                 undefined = 0,  //"|-|"
00157                     start = 1,  //"|START|"
00158                     stop = 2    //"|STOP|"
00159             };
00160 
00161             //set ERROR header without condition for general purpose ........................
00162             inline FesaLogger & logError(LogSeverity severity, const std::string& sender);
00163 
00164             //set TRACE header for topic-conditionned logging ...............................
00165             inline bool isEnabledFor(int32_t topic, const std::string& name, LogAction action);
00166 
00167             //FWK interface
00168             inline bool isEnabledFor(DIAG_FWK_TOPIC topic);
00169 
00170             //set TRACE header for topic-conditionned logging upon particular device ........
00171             inline bool isEnabledFor(int32_t topic, AbstractDevice* pdev, const std::string& name, LogAction action);
00172 
00173             static bool isEnabled();
00174 
00178             FesaLogger(const FesaLogger&);
00179 
00183             ~FesaLogger();
00184 
00185             static void init(char *bname);
00186             static void enableConsoleOutput();
00187             static void disableConsoleOutput();
00188             static void reinit();
00189             static void destroy();
00190 
00191             /* Instantiate or just retrieve a logger object (logger-name = source+thread)
00192              * source: domain of the logging (MAIN, RT, SRV, .. look at definition above)
00193              * thread: prevents concurrent logger access and allow visualization of the
00194              * different layer in the diagnostic scope (Framework instrumentation only).
00195              */
00196             // this signature is used for the Framework instrumentation
00197             static FesaLogger* getLogger(const std::string& source, const std::string& thread, const std::string& cname);
00198 
00199             // this signature is used for the Framework instrumentation
00200             static FesaLogger* getLogger(const std::string& source, const std::string& thread);
00201 
00202             // returns a unique instance
00203             static FesaLogger* getDefaultLogger();
00204 
00205             // Set Diagnostic mode for all Loggers of the process.
00206             static void setDiagnosticMode(bool mode);
00207 
00208             // Set custom topic for all the log instances belonging to that class.
00209             static void setCustomTopic(int32_t customTopic, const std::string& cname);
00210 
00211             //send the message using the appropriate channel
00212             void send(const char* msg, LogType type);
00213 
00214             // public attributes used by the framework
00215             static int32_t fwkTopic_; // Topics' state of the Framework Modediagnostic
00216             int32_t customTopic_; // Custom' state of the Framework diagnostic
00217 
00218             //process goes to diagnostic mode if logging channel has been set (enableDiagnosticMode = true)
00219             static bool modeDiagnostic_;
00220 
00221             //Message couting (allow to detect messages loss)
00222             static uint32_t logCount_;
00223 
00224             //TSC counter for Logging time-stamping
00225             static TsCounter logTsc_;
00226 
00227             /* Diagnostic is done for one class only even in SharedServer process.
00228              * In order to limit the CPU overload during logging process, configuration
00229              * of the current class diagnostic is stored into the FesaLogger.
00230              * These Global data are set by the Diagnostic setting property.
00231              */
00232             //used for one interface at a time, can be static.
00233             static std::string connectedHostName_;
00234             static int32_t connectedPortNumber_;
00235 
00236             std::string className_;
00237             std::string logSource_;
00238             std::string logThread_;
00239             std::string logName_;
00240 
00241 
00242         private:
00243 
00244             friend class FesaLoggerBuffer;
00245 
00246             FesaLogger(FesaLoggerBuffer* pBuf);
00247 
00248             /* For the Trace logging, topic filtering is done by the source
00249              * We just need to define one logging channel and maintain it globally.
00250              */
00251             static UdpLogger* pUDPLog_;
00252 
00253             /* Name of the FesaLogger object which is used as message header
00254              * Must be unique per concurrent thread. Format: <source>|<thread>, exp: "EVT|RTLayer1"
00255              */
00256             //Maintain the logging severity (FATAL, ERROR, WARNING)
00257             LogSeverity errSeverity_;
00258 
00259             //Maintain the logger type (ERROR or TRACE)
00260             LogType logType_;
00261 
00262             //Save the last Error (client connection lost in particular) in order
00263             //to not fill the syslogger with the same message.
00264             int32_t lastError_;
00265 
00266             //flag used to root logging to standard 'cout <<' during the process start-up
00267             static bool isInitPhase_; //init-phase=true ==> logging means 'std::cout'
00268 
00269             static FesaLogger* errLog_; //shared Logger used for Error reporting
00270 
00271 
00272             //Define action for USR traces to be displayed in the profiler
00273             //In case of modification, don't forget to update 'LogAction' enumeration.
00274             static const char* logActionStr_[];
00275 
00276             // Map to register logger objects
00277             static std::map<std::string, FesaLogger *> logFactoryMap_;
00278             // Maintains a reference to the default one to avoid
00279             // map lookup for retrieving the default logger instance
00280             static FesaLogger* defaultLog_;
00281 
00282             // Mutex used to protect the logFactoryMap
00283             static Mutex mutex_;
00284 
00285             //Buffer and stream object for each logger instance
00286             FesaLoggerBuffer* logBuffer_;
00287     };
00288 
00289     /* -------------------------------------------------------------------------
00290      */
00291     class FesaLoggerBuffer: public std::streambuf
00292     {
00293         public:
00294             FesaLoggerBuffer()
00295             {
00296                 setp(buffer_, buffer_ + (bufferSize_ - 1));
00297             }
00298 
00299             void setFesaLogger(FesaLogger* pLogger)
00300             {
00301                 logger_ = pLogger;
00302             }
00303             ;
00304 
00305         protected:
00306             virtual int32_t sync();
00307             virtual int32_t overflow(int32_t);
00308 
00309         private:
00310             /* For perfomance aspect, the ouput message should be limited to the
00311              * network MTU: 1480 bytes for Ethernet.
00312              */
00313             static const int32_t bufferSize_ = 1479; //reserve 1 char for string termination
00314             char buffer_[bufferSize_];
00315             //FesaLogger owner of that buffer
00316             FesaLogger* logger_;
00317     };
00318 
00322     inline FesaLogger* FesaLogger::getDefaultLogger()
00323     {
00324         return defaultLog_;
00325     }
00326 
00327 #define SET_TRACE_HEADER(sender)        \
00328         logType_ = traceType;                   \
00329         errSeverity_ = none;                            \
00330         *this << sender << "|TRACE|" << logSource_ << className_ << logThread_ << logCount_++ << "|" << std::setprecision(20) << logTsc_.getValue(YS_UNIT) << "|"
00331 
00332     inline FesaLogger & FesaLogger::logError(LogSeverity severity, const std::string& sender = FesaLogger::usrSender)
00333     {
00334         logType_ = errorType;
00335         errSeverity_ = severity;
00336         *this << sender << "|ERROR|";
00337         return *this;
00338     }
00339 
00340     inline bool FesaLogger::isEnabledFor(int32_t topic, const std::string& name = undefinedFunctionName, LogAction action =
00341                     undefined)
00342     {
00343 
00344         if (modeDiagnostic_ && (topic & customTopic_))
00345         {
00346             //function name and action attributes can be defined for USR profiling traces purpose,
00347             //otherwise "-" string will be automatically set in the trace header.
00348             SET_TRACE_HEADER("USR") << name << logActionStr_[action];
00349             return true;
00350         }
00351         return false;
00352     }
00353 
00354     inline bool FesaLogger::isEnabledFor(DIAG_FWK_TOPIC topic)
00355     {
00356 
00357         if (modeDiagnostic_ && (topic & fwkTopic_))
00358         {
00359             //explicit (name,action) attributes to be added with FWK trace
00360             SET_TRACE_HEADER("FWK");
00361             return true;
00362         }
00363         return false;
00364     }
00365 
00366     inline bool FesaLogger::isEnabledFor(int32_t topic, AbstractDevice* pdev, const std::string& name =
00367                     undefinedFunctionName, LogAction action = undefined)
00368     {
00369         if (modeDiagnostic_ && (topic & customTopic_) && pdev->isLoggable_)
00370         {
00371             //function name and action attributes can be defined for USR profiling traces purpose,
00372             //otherwise "-" string will be automatically set in the trace header.
00373             SET_TRACE_HEADER("USR") << name << logActionStr_[action];
00374             return true;
00375         }
00376         return false;
00377     }
00378 
00379 }
00380 
00381 #endif // __FesaLogger__H__

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1