Logger.cpp
Go to the documentation of this file.
00001 
00047 #include <iostream>
00048 #include <fstream>
00049 #include <signal.h>
00050 #include <unistd.h>
00051 
00052 using namespace std;
00053 
00054 #include "husky_base/horizon_legacy/Logger.h"
00055 
00056 namespace clearpath
00057 {
00058 
00059   const char *Logger::levelNames[] = {"ERROR", "EXCEPTION", "WARNING", "INFO", "DETAIL"};
00060 
00061   void loggerTermHandler(int signum)
00062   {
00063     Logger::instance().close();
00064 
00065     if ((signum == SIGABRT) || (signum == SIGSEGV))
00066     {
00067       /* We need to catch these so we can flush out any last messages.
00068        * having done this, probably the most consistent thing to do
00069        * is re-raise the signal.  (We certainly don't want to just
00070        * ignore these) */
00071       signal(signum, SIG_DFL);
00072       kill(getpid(), signum);
00073     }
00074   }
00075 
00076   Logger &Logger::instance()
00077   {
00078     static Logger instance;
00079     return instance;
00080   }
00081 
00082   Logger::Logger() :
00083       enabled(true),
00084       level(WARNING),
00085       stream(&cerr)
00086   {
00087     nullStream = new ofstream("/dev/null");
00088   }
00089 
00090   Logger::~Logger()
00091   {
00092     close();
00093   }
00094 
00095   void Logger::close()
00096   {
00097     // The actual output stream is owned by somebody else, we only need to flush it
00098     stream->flush();
00099 
00100     nullStream->close();
00101     delete nullStream;
00102     nullStream = 0;
00103   }
00104 
00105   std::ostream &Logger::entry(enum logLevels msg_level, const char *file, int line)
00106   {
00107     if (!enabled) { return *nullStream; }
00108     if (msg_level > this->level) { return *nullStream; }
00109 
00110     /* Construct the log entry tag */
00111     // Always the level of the message
00112     *stream << levelNames[msg_level];
00113     // If file/line information is provided, need to print it with brackets:
00114     if (file || (line >= 0))
00115     {
00116       *stream << " (";
00117       if (file) { *stream << file; }
00118       // Only want a comma if we have both items
00119       if (file && (line >= 0)) { *stream << ","; }
00120       if (line >= 0) { *stream << line; }
00121       *stream << ")";
00122     }
00123     *stream << ": ";
00124     return *stream;
00125   }
00126 
00127   void Logger::setEnabled(bool en)
00128   {
00129     enabled = en;
00130   }
00131 
00132   void Logger::setLevel(enum logLevels newLevel)
00133   {
00134     level = newLevel;
00135   }
00136 
00137   void Logger::setStream(ostream *newStream)
00138   {
00139     stream->flush();
00140     stream = newStream;
00141   }
00142 
00143   void Logger::hookFatalSignals()
00144   {
00145     signal(SIGINT, loggerTermHandler);
00146     signal(SIGTERM, loggerTermHandler);
00147     /* If there's an abort or segfault in Logger.close(), well...
00148      * we're pretty much totally screwed anyway. */
00149     signal(SIGABRT, loggerTermHandler);
00150     signal(SIGSEGV, loggerTermHandler);
00151   }
00152 
00153 }; // namespace clearpath
00154 


husky_base
Author(s): Mike Purvis , Paul Bovbel
autogenerated on Sat Jun 8 2019 18:26:01