OW_Logger.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2003-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #include "OW_config.h"
00036 #include "OW_Logger.hpp"
00037 #include "OW_ExceptionIds.hpp"
00038 #include "OW_LogMessage.hpp"
00039 #include "OW_Assertion.hpp"
00040 #include "OW_Array.hpp"
00041 #include "OW_ConfigFile.hpp"
00042 #include "OW_LogMessagePatternFormatter.hpp"
00043 #include "OW_AppenderLogger.hpp"
00044 #include "OW_LogAppender.hpp"
00045 #include "OW_ConfigOpts.hpp"
00046 #include "OW_Format.hpp"
00047 #include "OW_Mutex.hpp"
00048 #include "OW_MutexLock.hpp"
00049 #include "OW_ThreadOnce.hpp"
00050 #include "OW_NullLogger.hpp"
00051 
00052 namespace OW_NAMESPACE
00053 {
00054 
00055 OW_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 Logger::~Logger()
00067 {
00068 }
00069 
00071 Logger::Logger()
00072    : m_logLevel(E_ERROR_LEVEL)
00073    , m_defaultComponent(STR_DEFAULT_COMPONENT)
00074 {
00075 }
00076 
00078 Logger::Logger(const ELogLevel l)
00079    : m_logLevel(l)
00080    , m_defaultComponent(STR_DEFAULT_COMPONENT)
00081 {
00082 }
00083 
00085 Logger::Logger(const String& defaultComponent, const ELogLevel l)
00086    : m_logLevel(l)
00087    , m_defaultComponent(defaultComponent)
00088 {
00089    OW_ASSERT(m_defaultComponent != "");
00090 }
00091 
00093 void
00094 Logger::processLogMessage(const LogMessage& message) const
00095 {
00096    OW_ASSERT(!message.component.empty());
00097    OW_ASSERT(!message.category.empty());
00098    OW_ASSERT(!message.message.empty());
00099 
00100    doProcessLogMessage(message);
00101 }
00102 
00104 void
00105 Logger::setLogLevel(const String& l)
00106 {
00107    if (l.equalsIgnoreCase(STR_INFO_CATEGORY))
00108    {
00109       setLogLevel(E_INFO_LEVEL);
00110    }
00111    else if (l.equalsIgnoreCase(STR_DEBUG_CATEGORY))
00112    {
00113       setLogLevel(E_DEBUG_LEVEL);
00114    }
00115    else if (l.equalsIgnoreCase(STR_ERROR_CATEGORY))
00116    {
00117       setLogLevel(E_ERROR_LEVEL);
00118    }
00119    else if (l.equalsIgnoreCase(STR_ALL_CATEGORY))
00120    {
00121       setLogLevel(E_ALL_LEVEL);
00122    }
00123    else if (l.equalsIgnoreCase(STR_NONE_CATEGORY))
00124    {
00125       setLogLevel(E_NONE_LEVEL);
00126    }
00127    else
00128    {
00129       setLogLevel(E_FATAL_ERROR_LEVEL);
00130    }
00131 }
00132 
00134 void
00135 Logger::logFatalError(const String& message, const char* filename, int fileline, const char* methodname) const
00136 {
00137    if (m_logLevel >= E_FATAL_ERROR_LEVEL)
00138    {
00139       processLogMessage( LogMessage(m_defaultComponent, STR_FATAL_CATEGORY, message, filename, fileline, methodname) );
00140    }
00141 }
00142 
00144 void
00145 Logger::logError(const String& message, const char* filename, int fileline, const char* methodname) const
00146 {
00147    if (m_logLevel >= E_ERROR_LEVEL)
00148    {
00149       processLogMessage( LogMessage(m_defaultComponent, STR_ERROR_CATEGORY, message, filename, fileline, methodname) );
00150    }
00151 }
00152 
00154 void
00155 Logger::logInfo(const String& message, const char* filename, int fileline, const char* methodname) const
00156 {
00157    if (m_logLevel >= E_INFO_LEVEL)
00158    {
00159       processLogMessage( LogMessage(m_defaultComponent, STR_INFO_CATEGORY, message, filename, fileline, methodname) );
00160    }
00161 }
00162 
00164 void
00165 Logger::logDebug(const String& message, const char* filename, int fileline, const char* methodname) const
00166 {
00167    if (m_logLevel >= E_DEBUG_LEVEL)
00168    {
00169       processLogMessage( LogMessage(m_defaultComponent, STR_DEBUG_CATEGORY, message, filename, fileline, methodname) );
00170    }
00171 }
00172    
00174 void
00175 Logger::logMessage(const String& component, const String& category, const String& message) const
00176 {
00177    processLogMessage(LogMessage(component, category, message, 0, -1, 0));
00178 }
00179 
00181 void
00182 Logger::logMessage(const String& component, const String& category, const String& message, const char* filename, int fileline, const char* methodname) const
00183 {
00184    processLogMessage(LogMessage(component, category, message, filename, fileline, methodname));
00185 }
00186 
00188 void
00189 Logger::logMessage(const String& category, const String& message) const
00190 {
00191    processLogMessage(LogMessage(m_defaultComponent, category, message, 0, -1, 0));
00192 }
00193 
00195 void
00196 Logger::logMessage(const String& category, const String& message, const char* filename, int fileline, const char* methodname) const
00197 {
00198    processLogMessage(LogMessage(m_defaultComponent, category, message, filename, fileline, methodname));
00199 }
00200 
00202 void
00203 Logger::logMessage(const LogMessage& message) const
00204 {
00205    processLogMessage(message);
00206 }
00207 
00209 bool
00210 Logger::categoryIsEnabled(const String& category) const
00211 {
00212    return doCategoryIsEnabled(category);
00213 }
00214 
00216 bool
00217 Logger::componentAndCategoryAreEnabled(const String& component, const String& category) const
00218 {
00219    return doComponentAndCategoryAreEnabled(component, category);
00220 }
00221 
00223 bool
00224 Logger::doComponentAndCategoryAreEnabled(const String& component, const String& category) const
00225 {
00226    return true;
00227 }
00228 
00230 bool
00231 Logger::doCategoryIsEnabled(const String& category) const
00232 {
00233    return true;
00234 }
00235 
00237 void
00238 Logger::setDefaultComponent(const String& component)
00239 {
00240    OW_ASSERT(component != "");
00241    m_defaultComponent = component;
00242 }
00243 
00245 String
00246 Logger::getDefaultComponent() const
00247 {
00248    return m_defaultComponent;
00249 }
00250    
00252 void
00253 Logger::setLogLevel(ELogLevel logLevel)
00254 {
00255    m_logLevel = logLevel;
00256 }
00257 
00259 LoggerRef
00260 Logger::createLogger( const String& type, bool debug )
00261 {
00262    LogAppender::ConfigMap configItems;
00263 
00264    Array<LogAppenderRef> appenders;
00265    String name("");
00266    if (type == LogAppender::TYPE_SYSLOG || type == LogAppender::TYPE_STDERR || type == LogAppender::TYPE_NULL)
00267    {
00268       appenders.push_back(LogAppender::createLogAppender(name, LogAppender::ALL_COMPONENTS, LogAppender::ALL_CATEGORIES,
00269          LogMessagePatternFormatter::STR_DEFAULT_MESSAGE_PATTERN, type, configItems));
00270    }
00271    else
00272    {
00273       // we need a special case for filenames in the type, since createLogAppender only handles types it knows about
00274       String configItem = Format(ConfigOpts::LOG_1_LOCATION_opt, name);
00275       String filename = type;
00276       configItems[configItem] = filename;
00277       appenders.push_back(LogAppender::createLogAppender(name, LogAppender::ALL_COMPONENTS, LogAppender::ALL_CATEGORIES,
00278          LogMessagePatternFormatter::STR_DEFAULT_MESSAGE_PATTERN, LogAppender::TYPE_FILE, configItems));
00279    }
00280 
00281    if ( debug )
00282    {
00283       appenders.push_back(LogAppender::createLogAppender(name, LogAppender::ALL_COMPONENTS, LogAppender::ALL_CATEGORIES,
00284          LogMessagePatternFormatter::STR_DEFAULT_MESSAGE_PATTERN, LogAppender::TYPE_STDERR, configItems));
00285 
00286    }
00287 
00288    return LoggerRef(new AppenderLogger(STR_DEFAULT_COMPONENT, appenders));
00289 
00290 }
00291 
00293 LoggerRef
00294 Logger::clone() const
00295 {
00296    return doClone();
00297 }
00298 
00300 Logger::Logger(const Logger& x)
00301    : IntrusiveCountableBase(x)
00302    , m_logLevel(x.m_logLevel)
00303    , m_defaultComponent(x.m_defaultComponent)
00304 
00305 {
00306 }
00307 
00309 Logger&
00310 Logger::operator=(const Logger& x)
00311 {
00312    m_logLevel = x.m_logLevel;
00313    m_defaultComponent = x.m_defaultComponent;
00314    return *this;
00315 }
00316 
00318 void
00319 Logger::swap(Logger& x)
00320 {
00321    std::swap(m_logLevel, x.m_logLevel);
00322    m_defaultComponent.swap(x.m_defaultComponent);
00323 }
00324 
00326 // we're passing a pointer to this to pthreads, it has to have C linkage.
00327 extern "C" 
00328 {
00329 static void freeThreadLogger(void *ptr)
00330 {
00331    delete static_cast<LoggerRef *>(ptr);
00332 }
00333 } // end extern "C"
00334 
00336 namespace
00337 {
00338 
00339 OnceFlag         g_onceGuard  = OW_ONCE_INIT;
00340 Mutex           *g_mutexGuard = NULL;
00341 pthread_key_t    g_loggerKey; // FIXME: port me :)
00342 LoggerRef        g_defaultLogger;
00343 
00344 
00346 void initGuardAndKey()
00347 {
00348    g_mutexGuard = new Mutex();
00349    int ret = pthread_key_create(&g_loggerKey, freeThreadLogger);
00350    OW_ASSERTMSG(ret == 0, "failed create a thread specific key");
00351 }
00352 
00353 
00354 } // end unnamed namespace
00355 
00357 // STATIC
00358 bool
00359 Logger::setDefaultLogger(const LoggerRef &ref)
00360 {
00361    if (ref)
00362    {
00363       callOnce(g_onceGuard, initGuardAndKey);
00364       MutexLock lock(*g_mutexGuard);
00365 
00366       g_defaultLogger = ref;
00367       return true;
00368    }
00369    return false;
00370 }
00371 
00372 
00374 // STATIC
00375 bool
00376 Logger::setThreadLogger(const LoggerRef &ref)
00377 {
00378 
00379    if (ref)
00380    {
00381       callOnce(g_onceGuard, initGuardAndKey);
00382       LoggerRef *ptr = new LoggerRef(ref);
00383 
00384       freeThreadLogger(pthread_getspecific(g_loggerKey));
00385 
00386       int ret = pthread_setspecific(g_loggerKey, ptr);
00387       if (ret)
00388       {
00389          delete ptr;
00390       }
00391       OW_ASSERTMSG(ret == 0, "failed to set a thread specific logger");
00392       return true;
00393    }
00394    return false;
00395 }
00396 
00397 
00399 // STATIC
00400 LoggerRef
00401 Logger::getDefaultLogger()
00402 {
00403    callOnce(g_onceGuard, initGuardAndKey);
00404    MutexLock lock(*g_mutexGuard);
00405    if (!g_defaultLogger)
00406    {
00407       g_defaultLogger = LoggerRef(new NullLogger());
00408    }
00409    return g_defaultLogger;
00410 }
00411 
00412 
00414 // STATIC
00415 LoggerRef
00416 Logger::getCurrentLogger()
00417 {
00418    callOnce(g_onceGuard, initGuardAndKey);
00419    LoggerRef *ptr = static_cast<LoggerRef *>(pthread_getspecific(g_loggerKey));
00420    if(ptr)
00421    {
00422       return *ptr;
00423    }
00424    else
00425    {
00426       return getDefaultLogger();
00427    }
00428 }
00429 
00431 bool
00432 Logger::levelIsEnabled(const ELogLevel level)
00433 {
00434    return (getLogLevel() >= level);
00435 }
00436 
00437 } // end namespace OW_NAMESPACE
00438 

Generated on Thu Feb 9 08:48:03 2006 for openwbem by  doxygen 1.4.6