IBR-DTNSuite  0.8
ibrcommon/ibrcommon/Logger.h
Go to the documentation of this file.
00001 /*
00002  * Logger.h
00003  *
00004  * Copyright 2011 Johannes Morgenroth, IBR, TU Braunschweig
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #ifndef LOGGER_H_
00020 #define LOGGER_H_
00021 
00022 //#define __IBRCOMMON_MULTITHREADED__
00023 
00024 #include <ibrcommon/thread/Queue.h>
00025 #include <ibrcommon/thread/Thread.h>
00026 #include <ibrcommon/data/File.h>
00027 #include <fstream>
00028 #include <sys/time.h>
00029 #include <iostream>
00030 #include <sstream>
00031 #include <list>
00032 
00063 #define IBRCOMMON_LOGGER_LEVEL \
00064         ibrcommon::Logger::getVerbosity()
00065 
00066 #define IBRCOMMON_LOGGER(level) \
00067         { \
00068                 ibrcommon::Logger log = ibrcommon::Logger::level(); \
00069                 log
00070 
00071 #define IBRCOMMON_LOGGER_DEBUG(verbosity) \
00072         if (ibrcommon::Logger::getVerbosity() >= verbosity) \
00073         { \
00074                 ibrcommon::Logger log = ibrcommon::Logger::debug(verbosity); \
00075                 log
00076 
00077 #define IBRCOMMON_LOGGER_ENDL \
00078                 std::flush; \
00079                 log.print(); \
00080         }
00081 
00082 #define IBRCOMMON_LOGGER_ex(level) \
00083         IBRCOMMON_LOGGER(level) << __PRETTY_FUNCTION__ << ": "
00084 
00085 #define IBRCOMMON_LOGGER_DEBUG_ex(verbosity) \
00086         IBRCOMMON_LOGGER_DEBUG(verbosity) << __FILE__ << ":" << __LINE__ << " in " << __PRETTY_FUNCTION__ << ": "
00087 
00088 namespace ibrcommon
00089 {
00095         class Logger : public std::stringstream
00096         {
00097         public:
00098                 enum LogOptions
00099                 {
00100                         LOG_NONE =              0,
00101                         LOG_DATETIME =  1 << 0, /* print date/time on log messages */
00102                         LOG_HOSTNAME =  1 << 1, /* print hostname on log messages */
00103                         LOG_LEVEL =             1 << 2, /* print the log level on log messages */
00104                         LOG_TIMESTAMP = 1 << 3  /* print timestamp on log messages */
00105                 };
00106 
00107                 enum LogLevel
00108                 {
00109                         LOGGER_EMERG =          1 << 0, /* system is unusable */
00110                         LOGGER_ALERT =          1 << 1, /* action must be taken immediately */
00111                         LOGGER_CRIT =           1 << 2, /* critical conditions */
00112                         LOGGER_ERR =            1 << 3, /* error conditions */
00113                         LOGGER_WARNING =        1 << 4, /* warning conditions */
00114                         LOGGER_NOTICE =         1 << 5, /* normal but significant condition */
00115                         LOGGER_INFO =           1 << 6, /* informational */
00116                         LOGGER_DEBUG =          1 << 7, /* debug-level messages */
00117                         LOGGER_ALL =            0xff
00118                 };
00119 
00120                 Logger(const Logger&);
00121                 virtual ~Logger();
00122 
00123                 static Logger emergency();
00124                 static Logger alert();
00125                 static Logger critical();
00126                 static Logger error();
00127                 static Logger warning();
00128                 static Logger notice();
00129                 static Logger info();
00130                 static Logger debug(int verbosity);
00131 
00136                 static void setVerbosity(const int verbosity);
00137 
00142                 static int getVerbosity();
00143 
00150                 static void addStream(std::ostream &stream, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
00151 
00158                 static void setLogfile(const ibrcommon::File &logfile, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
00159 
00167                 static void enableSyslog(const char *name, int option, int facility, const unsigned char logmask = LOGGER_INFO);
00168 
00176                 static void enableAsync();
00177 
00182                 static void enableBuffer(size_t size);
00183 
00188                 static void writeBuffer(std::ostream&);
00189 
00195                 static void stop();
00196 
00200                 void print();
00201                 
00205                 static void reload();
00206 
00207         private:
00208                 Logger(LogLevel level, int debug_verbosity = 0);
00209 
00210                 class LoggerOutput
00211                 {
00212                 public:
00213                         LoggerOutput(std::ostream &stream, const unsigned char logmask, const unsigned char options);
00214                         virtual ~LoggerOutput();
00215 
00216                         void log(const Logger &log);
00217 
00218                         std::ostream &_stream;
00219                         unsigned char _level;
00220                         unsigned char _options;
00221                 };
00222                 
00223                 class LogWriter : public ibrcommon::JoinableThread
00224                 {
00225                 public:
00226                         LogWriter();
00227                         virtual ~LogWriter();
00228 
00229                         void log(Logger &logger);
00230 
00235                         void setVerbosity(const int verbosity);
00236 
00241                         int getVerbosity();
00242 
00249                         void addStream(std::ostream &stream, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
00250 
00257                         void setLogfile(const ibrcommon::File &logfile, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
00258 
00266                         void enableSyslog(const char *name, int option, int facility, const unsigned char logmask = LOGGER_INFO);
00267 
00275                         void enableAsync();
00276 
00281                         void enableBuffer(size_t size);
00282 
00286                         void reload();
00287 
00292                         void writeBuffer(std::ostream&, const unsigned char logmask, const unsigned char options);
00293 
00294                 protected:
00295                         void flush();
00296                         void run();
00297                         void __cancellation();
00298 
00299                 private:
00303                         void flush(const Logger &logger);
00304 
00305                         int _verbosity;
00306                         bool _syslog;
00307                         unsigned char _syslog_mask;
00308 
00309                         ibrcommon::Queue<Logger> _queue;
00310                         bool _use_queue;
00311                         std::list<LoggerOutput> _logger;
00312 
00313                         ibrcommon::Mutex _buffer_mutex;
00314                         size_t _buffer_size;
00315                         std::list<Logger> *_buffer;
00316 
00317                         ibrcommon::Mutex _logfile_mutex;
00318                         ibrcommon::File _logfile;
00319                         std::ofstream _logfile_stream;
00320                         LoggerOutput *_logfile_output;
00321                         unsigned char _logfile_logmask;
00322                         unsigned char _logfile_options;
00323                 };
00324 
00325                 LogLevel _level;
00326                 int _debug_verbosity;
00327                 struct timeval _logtime;
00328 
00329                 static LogWriter _logwriter;
00330         };
00331 }
00332 
00333 #endif /* LOGGER_H_ */