blob: 68a549219df2925c262e5f872332ba8da522c643 [file] [log] [blame]
/***************************************************************************
logger.cpp - class Logger
-------------------
begin : mar avr 15 2003
copyright : (C) 2003 by michael
email : mcatan@free.fr
***************************************************************************/
/***************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* *
* This software is published under the terms of the Apache Software *
* License version 1.1, a copy of which has been included with this *
* distribution in the LICENSE.txt file. *
***************************************************************************/
#include <log4cxx/logger.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/spi/loggerfactory.h>
#include <log4cxx/appender.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/helpers/stringhelper.h>
#include <stdarg.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
IMPLEMENT_LOG4CXX_OBJECT(Logger)
String Logger::FQCN = Logger::getStaticClass().getName();
Logger::Logger(const String& name)
: name(name), additive(true), repository(0)
{
}
Logger::~Logger()
{
}
void Logger::addAppender(const AppenderPtr& newAppender)
{
synchronized sync(this);
if (aai == 0)
{
aai = new AppenderAttachableImpl();
}
aai->addAppender(newAppender);
repository->fireAddAppenderEvent(this, newAppender);
}
void Logger::assertLog(bool assertion, const String& msg)
{
if(!assertion)
{
this->error(msg);
}
}
void Logger::callAppenders(const spi::LoggingEventPtr& event)
{
int writes = 0;
for(LoggerPtr logger = this; logger != 0; logger = logger->parent)
{
// Protected against simultaneous call to addAppender, removeAppender,...
synchronized sync(logger);
if (logger->aai != 0)
{
writes += logger->aai->appendLoopOnAppenders(event);
}
if(!logger->additive)
{
break;
}
}
if(writes == 0)
{
repository->emitNoAppenderWarning(this);
}
}
void Logger::closeNestedAppenders()
{
synchronized sync(this);
AppenderList appenders = getAllAppenders();
for(AppenderList::iterator it=appenders.begin(); it!=appenders.end(); ++it)
{
(*it)->close();
}
}
void Logger::debug(const String& message, const char* file, int line)
{
if(repository->isDisabled(Level::DEBUG_INT))
{
return;
}
if(Level::DEBUG->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, Level::DEBUG, message, file, line);
}
}
void Logger::error(const String& message, const char* file, int line)
{
if(repository->isDisabled(Level::ERROR_INT))
{
return;
}
if(Level::ERROR->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, Level::ERROR, message, file, line);
}
}
void Logger::fatal(const String& message, const char* file, int line)
{
if(repository->isDisabled(Level::FATAL_INT))
{
return;
}
if(Level::FATAL->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, Level::FATAL, message, file, line);
}
}
void Logger::forcedLog(const LevelPtr& level, const String& message,
const char* file, int line)
{
callAppenders(new LoggingEvent(FQCN, this, level, message, file, line));
}
void Logger::forcedLog(const String& fqcn, const LevelPtr& level, const String& message,
const char* file, int line)
{
callAppenders(new LoggingEvent(fqcn, this, level, message, file, line));
}
bool Logger::getAdditivity() const
{
return additive;
}
AppenderList Logger::getAllAppenders() const
{
synchronized sync(this);
if (aai == 0)
{
return AppenderList();
}
else
{
return aai->getAllAppenders();
}
}
AppenderPtr Logger::getAppender(const String& name) const
{
synchronized sync(this);
if (aai == 0 || name.empty())
{
return 0;
}
return aai->getAppender(name);
}
const LevelPtr& Logger::getEffectiveLevel() const
{
for(const Logger * l = this; l != 0; l=l->parent)
{
if(l->level != 0)
{
return l->level;
}
}
throw RuntimeException(_T("level is null for logger") + name);
}
LoggerRepositoryPtr Logger::getLoggerRepository() const
{
return repository;
}
ResourceBundlePtr Logger::getResourceBundle() const
{
for (LoggerPtr l = this; l != 0; l = l->parent)
{
if (l->resourceBundle != 0)
{
return l->resourceBundle;
}
}
// It might be the case that there is no resource bundle
return 0;
}
String Logger::getResourceBundleString(const String& key) const
{
ResourceBundlePtr rb = getResourceBundle();
// This is one of the rare cases where we can use logging in order
// to report errors from within log4j.
if (rb == 0)
{
return String();
}
else
{
try
{
return rb->getString(key);
}
catch (MissingResourceException&)
{
((Logger *)this)->error(_T("No resource is associated with key \"") +
key + _T("\"."));
return String();
}
}
}
const LoggerPtr& Logger::getParent() const
{
return parent;
}
const LevelPtr& Logger::getLevel() const
{
return level;
}
void Logger::info(const String& message, const char* file, int line)
{
if(repository->isDisabled(Level::INFO_INT))
{
return;
}
if(Level::INFO->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, Level::INFO, message, file, line);
}
}
bool Logger::isAttached(const AppenderPtr& appender) const
{
synchronized sync(this);
if (appender == 0 || aai == 0)
{
return false;
}
else
{
return aai->isAttached(appender);
}
}
bool Logger::isDebugEnabled() const
{
if(repository->isDisabled(Level::DEBUG_INT))
{
return false;
}
return Level::DEBUG->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isEnabledFor(const LevelPtr& level) const
{
if(repository->isDisabled(level->level))
{
return false;
}
return level->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isInfoEnabled() const
{
if(repository->isDisabled(Level::INFO_INT))
{
return false;
}
return Level::INFO->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isErrorEnabled() const
{
if(repository->isDisabled(Level::ERROR_INT))
{
return false;
}
return Level::ERROR->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isWarnEnabled() const
{
if(repository->isDisabled(Level::WARN_INT))
{
return false;
}
return Level::WARN->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isFatalEnabled() const
{
if(repository->isDisabled(Level::FATAL_INT))
{
return false;
}
return Level::FATAL->isGreaterOrEqual(getEffectiveLevel());
}
/*void Logger::l7dlog(const LevelPtr& level, const String& key,
const char* file, int line)
{
if (repository->isDisabled(level->level))
{
return;
}
if (level->isGreaterOrEqual(getEffectiveLevel()))
{
String msg = getResourceBundleString(key);
// if message corresponding to 'key' could not be found in the
// resource bundle, then default to 'key'.
if (msg.empty())
{
msg = key;
}
forcedLog(FQCN, level, msg, file, line);
}
}*/
void Logger::l7dlog(const LevelPtr& level, const String& key,
const char* file, int line, ...)
{
if (repository->isDisabled(level->level))
{
return;
}
if (level->isGreaterOrEqual(getEffectiveLevel()))
{
String pattern = getResourceBundleString(key);
String msg;
if (pattern.empty())
{
msg = key;
}
else
{
va_list params;
va_start (params, line);
msg = StringHelper::format(pattern, params);
va_end (params);
}
forcedLog(FQCN, level, msg, file, line);
}
}
void Logger::log(const LevelPtr& level, const String& message,
const char* file, int line)
{
if(repository->isDisabled(level->level))
{
return;
}
if(level->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, level, message, file, line);
}
}
void Logger::removeAllAppenders()
{
synchronized sync(this);
if(aai != 0)
{
aai->removeAllAppenders();
aai = 0;
}
}
void Logger::removeAppender(const AppenderPtr& appender)
{
synchronized sync(this);
if(appender == 0 || aai == 0)
{
return;
}
aai->removeAppender(appender);
}
void Logger::removeAppender(const String& name)
{
synchronized sync(this);
if(name.empty() || aai == 0)
{
return;
}
aai->removeAppender(name);
}
void Logger::setAdditivity(bool additive)
{
this->additive = additive;
}
void Logger::setHierarchy(spi::LoggerRepository * repository)
{
this->repository = repository;
}
void Logger::setLevel(const LevelPtr& level)
{
this->level = level;
}
void Logger::warn(const String& message, const char* file, int line)
{
if(repository->isDisabled(Level::WARN_INT))
{
return;
}
if(Level::WARN->isGreaterOrEqual(getEffectiveLevel()))
{
forcedLog(FQCN, Level::WARN, message, file, line);
}
}
LoggerPtr Logger::getLogger(const String& name)
{
return LogManager::getLogger(name);
}
LoggerPtr Logger::getRootLogger() {
return LogManager::getRootLogger();
}
LoggerPtr Logger::getLogger(const String& name,
spi::LoggerFactoryPtr factory)
{
return LogManager::getLogger(name, factory);
}