Phoenix
Object-oriented orthogonally persistent operating system
log.h
Go to the documentation of this file.
00001 /*
00002  * /phoenix/include/log.h
00003  *
00004  * This file is a part of Phoenix operating system.
00005  * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com>
00006  * All rights reserved.
00007  * See COPYING file for copyright details.
00008  */
00009 
00014 #ifndef LOG_H_
00015 #define LOG_H_
00016 
00017 #ifdef UNITTEST
00018 
00019 void __ut_trace(const char *file, int line, const char *msg, ...);
00020 
00021 #define TRACE_FMT(...) __ut_trace(__FILE__, __LINE__, __VA_ARGS__)
00022 
00023 #elif defined(KERNEL)
00024 
00025 namespace log {
00026 
00027 class DbgSerialPort;
00028 extern DbgSerialPort *dbgSerialPort;
00029 extern text_stream::OTextStream<DbgSerialPort> *dbgStream;
00030 
00031 } /* namespace log */
00032 
00033 #define TRACE_FMT(...) log::dbgStream->Format(__VA_ARGS__)
00034 
00035 #elif defined(EFI_APP)
00036 
00037 #define TRACE_FMT(...)
00038 
00039 #endif
00040 
00046 #ifdef DEBUG
00047 #define TRACE(msg, ...) \
00048     TRACE_FMT("[TRACE] %s:%d <%s>: " msg "\n", __FILE__, __LINE__, __func__, ## __VA_ARGS__)
00049 #else /* DEBUG */
00050 #define TRACE(msg, ...)
00051 #endif /* DEBUG */
00052 
00054 namespace log {
00055 
00059 class SysLogBase : public text_stream::OTextStream<SysLogBase> {
00060 public:
00062     enum Level {
00063         LOG_ALERT, 
00064         LOG_CRITICAL, 
00065         LOG_ERROR, 
00066         LOG_WARNING, 
00067         LOG_NOTICE, 
00068         LOG_INFO, 
00069         LOG_DEBUG 
00070     };
00071 
00072     inline SysLogBase() : text_stream::OTextStream<SysLogBase>(this) {
00073         _curLevel = LOG_DEBUG;
00074 #ifdef DEBUG
00075         _maxLevel = LOG_DEBUG;
00076 #else /* DEBUG */
00077         _maxLevel = LOG_NOTICE;
00078 #endif /* DEBUG */
00079     }
00080 
00088     virtual SysLogBase &operator <<(log::SysLogBase::Level level) = 0;
00089 
00090     template <typename T>
00091     inline SysLogBase &operator <<(T value) {
00092         if (UNLIKELY(_curLevel <= _maxLevel)) {
00093             text_stream::OTextStream<SysLogBase>::operator <<(value);
00094         }
00095         return *this;
00096     }
00097 
00099     template <typename... Args>
00100     inline SysLogBase &Format(const char *fmt, Args... args) {
00101         if (UNLIKELY(_curLevel <= _maxLevel)) {
00102             text_stream::OTextStream<SysLogBase>::Format(fmt, args...);
00103         }
00104         return *this;
00105     }
00106 
00113     inline SysLogBase &Format(const char *fmt) {
00114         if (UNLIKELY(_curLevel <= _maxLevel)) {
00115             text_stream::OTextStream<SysLogBase>::Format(fmt);
00116         }
00117         return *this;
00118     }
00119 
00120     inline SysLogBase &FormatV(const char *fmt, va_list args) {
00121         if (UNLIKELY(_curLevel <= _maxLevel)) {
00122             text_stream::OTextStream<SysLogBase>::FormatV(fmt, args);
00123         }
00124         return *this;
00125     }
00126 
00128     template <typename... Args>
00129     SysLogBase &Alert(const char *fmt, Args... args)
00130     {
00131         *this << LOG_ALERT;
00132         Format(fmt, args...);
00133         return *this;
00134     }
00135 
00137     template <typename... Args>
00138     SysLogBase &Critical(const char *fmt, Args... args)
00139     {
00140         *this << LOG_CRITICAL;
00141         Format(fmt, args...);
00142         return *this;
00143     }
00144 
00146     template <typename... Args>
00147     SysLogBase &Error(const char *fmt, Args... args)
00148     {
00149         *this << LOG_ERROR;
00150         Format(fmt, args...);
00151         return *this;
00152     }
00153 
00155     template <typename... Args>
00156     SysLogBase &Warning(const char *fmt, Args... args)
00157     {
00158         *this << LOG_WARNING;
00159         Format(fmt, args...);
00160         return *this;
00161     }
00162 
00164     template <typename... Args>
00165     SysLogBase &Notice(const char *fmt, Args... args)
00166     {
00167         *this << LOG_NOTICE;
00168         Format(fmt, args...);
00169         return *this;
00170     }
00171 
00173     template <typename... Args>
00174     SysLogBase &Info(const char *fmt, Args... args)
00175     {
00176         *this << LOG_INFO;
00177         Format(fmt, args...);
00178         return *this;
00179     }
00180 
00182     template <typename... Args>
00183     SysLogBase &Debug(const char *fmt, Args... args)
00184     {
00185         *this << LOG_DEBUG;
00186         Format(fmt, args...);
00187         return *this;
00188     }
00189 
00198     virtual bool Putc(char c, void *arg) = 0;
00199 protected:
00201     Level _curLevel;
00203     Level _maxLevel;
00204 };
00205 
00206 #ifdef KERNEL
00207 
00209 class KSysLog : public SysLogBase {
00210 public:
00211     KSysLog();
00212 
00213     virtual SysLogBase &operator <<(log::SysLogBase::Level level);
00214 
00215     virtual bool Putc(char c, void *arg = 0);
00216 private:
00217     bool lastNewLine;
00218 };
00219 
00221 typedef KSysLog SysLog;
00222 
00223 extern SysLog *sysLog;
00224 
00233 #define LOG     (*log::sysLog)
00234 
00235 #elif defined(EFI_APP) /* KERNEL */
00236 
00237 /* Stub for EFI environment. */
00238 typedef void *SysLog;
00239 
00240 #else /* EFI_APP */
00241 
00242 // XXX user space log
00243 
00244 #endif /* KERNEL/EFI_APP */
00245 
00247 void InitLog();
00248 
00256 #define LL(level) __CONCAT(log::SysLogBase::LOG_, level)
00257 
00258 } /* namespace log */
00259 
00260 #endif /* LOG_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines