00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00037 #include "blocxx/BLOCXX_config.h"
00038 #include "blocxx/Logger.hpp"
00039 #include "blocxx/ExceptionIds.hpp"
00040 #include "blocxx/LogMessage.hpp"
00041 #include "blocxx/Assertion.hpp"
00042 #include "blocxx/Array.hpp"
00043 #include "blocxx/LogMessagePatternFormatter.hpp"
00044 #include "blocxx/AppenderLogger.hpp"
00045 #include "blocxx/LogAppender.hpp"
00046 #include "blocxx/Format.hpp"
00047 #include "blocxx/Mutex.hpp"
00048 #include "blocxx/MutexLock.hpp"
00049 #include "blocxx/ThreadOnce.hpp"
00050 #include "blocxx/NullLogger.hpp"
00051
00052 namespace BLOCXX_NAMESPACE
00053 {
00054
00055 BLOCXX_DEFINE_EXCEPTION_WITH_ID(Logger);
00056
00057 const String Logger::STR_NONE_CATEGORY("NONE");
00058 const String Logger::STR_FATAL_CATEGORY("FATAL");
00059 const String Logger::STR_ERROR_CATEGORY("ERROR");
00060 const String Logger::STR_INFO_CATEGORY("INFO");
00061 const String Logger::STR_DEBUG_CATEGORY("DEBUG");
00062 const String Logger::STR_ALL_CATEGORY("ALL");
00063 const String Logger::STR_DEFAULT_COMPONENT("none");
00064
00066
00067 String
00068 Logger::getConfigItem(
00069 const LoggerConfigMap& map,
00070 const String &itemName,
00071 const String& defaultValue)
00072 {
00073 LoggerConfigMap::const_iterator i = map.find(itemName);
00074 return (i != map.end()) ? i->second : defaultValue;
00075 }
00076
00078
00079 void
00080 Logger::setConfigItem(
00081 LoggerConfigMap& map,
00082 const String& itemName,
00083 const String& value,
00084 EOverwritePreviousConfigItemFlag overwritePrevious)
00085 {
00086 LoggerConfigMap::iterator it = map.find(itemName);
00087 if (it == map.end() || overwritePrevious)
00088 {
00089 map[itemName] = value;
00090 }
00091 }
00092
00094 Logger::~Logger()
00095 {
00096 }
00097
00099 Logger::Logger(
00100 const String& defaultComponent,
00101 const ELogLevel level)
00102 : m_logLevel(level)
00103 , m_defaultComponent(defaultComponent)
00104 {
00105 BLOCXX_ASSERT(m_defaultComponent != "");
00106 }
00107
00109 void
00110 Logger::processLogMessage(
00111 const LogMessage& message) const
00112 {
00113 BLOCXX_ASSERT(!message.component.empty());
00114 BLOCXX_ASSERT(!message.category.empty());
00115 BLOCXX_ASSERT(!message.message.empty());
00116
00117 doProcessLogMessage(message);
00118 }
00119
00121 void
00122 Logger::setLogLevel(
00123 const String& level)
00124 {
00125 if (level.equalsIgnoreCase(STR_INFO_CATEGORY))
00126 {
00127 setLogLevel(E_INFO_LEVEL);
00128 }
00129 else if (level.equalsIgnoreCase(STR_DEBUG_CATEGORY))
00130 {
00131 setLogLevel(E_DEBUG_LEVEL);
00132 }
00133 else if (level.equalsIgnoreCase(STR_ERROR_CATEGORY))
00134 {
00135 setLogLevel(E_ERROR_LEVEL);
00136 }
00137 else if (level.equalsIgnoreCase(STR_ALL_CATEGORY))
00138 {
00139 setLogLevel(E_ALL_LEVEL);
00140 }
00141 else if (level.equalsIgnoreCase(STR_NONE_CATEGORY))
00142 {
00143 setLogLevel(E_NONE_LEVEL);
00144 }
00145 else
00146 {
00147 setLogLevel(E_FATAL_ERROR_LEVEL);
00148 }
00149 }
00150
00152 void
00153 Logger::logFatalError(
00154 const String& message,
00155 const char* filename,
00156 int fileline,
00157 const char* methodname) const
00158 {
00159 if (m_logLevel >= E_FATAL_ERROR_LEVEL)
00160 {
00161 processLogMessage( LogMessage(m_defaultComponent,
00162 STR_FATAL_CATEGORY, message, filename, fileline, methodname));
00163 }
00164 }
00165
00167 void
00168 Logger::logError(
00169 const String& message,
00170 const char* filename,
00171 int fileline,
00172 const char* methodname) const
00173 {
00174 if (m_logLevel >= E_ERROR_LEVEL)
00175 {
00176 processLogMessage( LogMessage(m_defaultComponent, STR_ERROR_CATEGORY, message, filename, fileline, methodname) );
00177 }
00178 }
00179
00181 void
00182 Logger::logInfo(
00183 const String& message,
00184 const char* filename,
00185 int fileline,
00186 const char* methodname) const
00187 {
00188 if (m_logLevel >= E_INFO_LEVEL)
00189 {
00190 processLogMessage( LogMessage(m_defaultComponent, STR_INFO_CATEGORY, message, filename, fileline, methodname) );
00191 }
00192 }
00193
00195 void
00196 Logger::logDebug(
00197 const String& message,
00198 const char* filename,
00199 int fileline,
00200 const char* methodname) const
00201 {
00202 if (m_logLevel >= E_DEBUG_LEVEL)
00203 {
00204 processLogMessage( LogMessage(m_defaultComponent, STR_DEBUG_CATEGORY, message, filename, fileline, methodname) );
00205 }
00206 }
00207
00209 void
00210 Logger::logMessage(
00211 const String& component,
00212 const String& category,
00213 const String& message) const
00214 {
00215 processLogMessage(LogMessage(component, category, message, 0, -1, 0));
00216 }
00217
00219 void
00220 Logger::logMessage(
00221 const String& component,
00222 const String& category,
00223 const String& message,
00224 const char* filename,
00225 int fileline,
00226 const char* methodname) const
00227 {
00228 processLogMessage(LogMessage(component, category, message, filename, fileline, methodname));
00229 }
00230
00232 void
00233 Logger::logMessage(
00234 const String& category,
00235 const String& message) const
00236 {
00237 processLogMessage(LogMessage(m_defaultComponent, category, message, 0, -1, 0));
00238 }
00239
00241 void
00242 Logger::logMessage(
00243 const String& category,
00244 const String& message,
00245 const char* filename,
00246 int fileline,
00247 const char* methodname) const
00248 {
00249 processLogMessage(LogMessage(m_defaultComponent, category, message, filename, fileline, methodname));
00250 }
00251
00253 void
00254 Logger::logMessage(
00255 const LogMessage& message) const
00256 {
00257 processLogMessage(message);
00258 }
00259
00261 bool
00262 Logger::categoryIsEnabled(
00263 const String& category) const
00264 {
00265 return doCategoryIsEnabled(category);
00266 }
00267
00269 bool
00270 Logger::componentAndCategoryAreEnabled(
00271 const String& component,
00272 const String& category) const
00273 {
00274 return doComponentAndCategoryAreEnabled(component, category);
00275 }
00276
00278 bool
00279 Logger::doComponentAndCategoryAreEnabled(
00280 const String& component,
00281 const String& category) const
00282 {
00283 return true;
00284 }
00285
00287 bool
00288 Logger::doCategoryIsEnabled(
00289 const String& category) const
00290 {
00291 return true;
00292 }
00293
00295 void
00296 Logger::setDefaultComponent(
00297 const String& component)
00298 {
00299 BLOCXX_ASSERT(component != "");
00300 m_defaultComponent = component;
00301 }
00302
00304 String
00305 Logger::getDefaultComponent() const
00306 {
00307 return m_defaultComponent;
00308 }
00309
00311 void
00312 Logger::setLogLevel(
00313 ELogLevel logLevel)
00314 {
00315 m_logLevel = logLevel;
00316 }
00317
00319 LoggerRef
00320 Logger::clone() const
00321 {
00322 return doClone();
00323 }
00324
00326 Logger::Logger(
00327 const Logger& x)
00328 : IntrusiveCountableBase(x)
00329 , m_logLevel(x.m_logLevel)
00330 , m_defaultComponent(x.m_defaultComponent)
00331
00332 {
00333 }
00334
00336 Logger&
00337 Logger::operator=(
00338 const Logger& x)
00339 {
00340 m_logLevel = x.m_logLevel;
00341 m_defaultComponent = x.m_defaultComponent;
00342 return *this;
00343 }
00344
00346 void
00347 Logger::swap(Logger& x)
00348 {
00349 std::swap(m_logLevel, x.m_logLevel);
00350 m_defaultComponent.swap(x.m_defaultComponent);
00351 }
00352
00354
00355 extern "C"
00356 {
00357 static void freeThreadLogger(void *ptr)
00358 {
00359 delete static_cast<LoggerRef *>(ptr);
00360 }
00361 }
00362
00364 namespace
00365 {
00366
00367 OnceFlag g_onceGuard = BLOCXX_ONCE_INIT;
00368 Mutex *g_mutexGuard = NULL;
00369 pthread_key_t g_loggerKey;
00370 LoggerRef g_defaultLogger;
00371
00372
00374 void initGuardAndKey()
00375 {
00376 g_mutexGuard = new Mutex();
00377 int ret = pthread_key_create(&g_loggerKey, freeThreadLogger);
00378 BLOCXX_ASSERTMSG(ret == 0, "failed create a thread specific key");
00379 }
00380
00381
00382 }
00383
00385
00386 bool
00387 Logger::setDefaultLogger(const blocxx::LoggerRef &ref)
00388 {
00389 if (ref)
00390 {
00391 callOnce(g_onceGuard, initGuardAndKey);
00392 MutexLock lock(*g_mutexGuard);
00393
00394 g_defaultLogger = ref;
00395 return true;
00396 }
00397 return false;
00398 }
00399
00400
00402
00403 bool
00404 Logger::setThreadLogger(const blocxx::LoggerRef &ref)
00405 {
00406
00407 if (ref)
00408 {
00409 callOnce(g_onceGuard, initGuardAndKey);
00410 LoggerRef *ptr = new LoggerRef(ref);
00411
00412 freeThreadLogger(pthread_getspecific(g_loggerKey));
00413
00414 int ret = pthread_setspecific(g_loggerKey, ptr);
00415 if (ret)
00416 {
00417 delete ptr;
00418 }
00419 BLOCXX_ASSERTMSG(ret == 0, "failed to set a thread specific logger");
00420 return true;
00421 }
00422 return false;
00423 }
00424
00425
00427
00428 LoggerRef
00429 Logger::getDefaultLogger()
00430 {
00431 callOnce(g_onceGuard, initGuardAndKey);
00432 MutexLock lock(*g_mutexGuard);
00433 if (!g_defaultLogger)
00434 {
00435 g_defaultLogger = LoggerRef(new NullLogger());
00436 }
00437 return g_defaultLogger;
00438 }
00439
00440
00442
00443 LoggerRef
00444 Logger::getCurrentLogger()
00445 {
00446 callOnce(g_onceGuard, initGuardAndKey);
00447 LoggerRef *ptr = static_cast<LoggerRef *>(pthread_getspecific(g_loggerKey));
00448 if(ptr)
00449 {
00450 return *ptr;
00451 }
00452 else
00453 {
00454 return getDefaultLogger();
00455 }
00456 }
00457
00459 bool
00460 Logger::levelIsEnabled(const ELogLevel level)
00461 {
00462 return (getLogLevel() >= level);
00463 }
00464
00465
00466 }
00467