Logger.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 // STATIC
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 // STATIC
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 // we're passing a pointer to this to pthreads, it has to have C linkage.
00355 extern "C" 
00356 {
00357 static void freeThreadLogger(void *ptr)
00358 {
00359    delete static_cast<LoggerRef *>(ptr);
00360 }
00361 } // end extern "C"
00362 
00364 namespace
00365 {
00366 
00367 OnceFlag         g_onceGuard  = BLOCXX_ONCE_INIT;
00368 Mutex           *g_mutexGuard = NULL;
00369 pthread_key_t    g_loggerKey; // FIXME: port me :)
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 } // end unnamed namespace
00383 
00385 // STATIC
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 // STATIC
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 // STATIC
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 // STATIC
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 } // end namespace BLOCXX_NAMESPACE
00467 

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6