Phoenix
Object-oriented orthogonally persistent operating system
|
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_ */