📄 logger.cpp
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <log4cxx/logstring.h>
#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 <log4cxx/helpers/synchronized.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/appenderattachableimpl.h>
#include <log4cxx/helpers/exception.h>
#if !defined(LOG4CXX)
#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/aprinitializer.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
IMPLEMENT_LOG4CXX_OBJECT(Logger)
Logger::Logger(Pool& p, const LogString& name1)
: pool(&p), name(), level(), parent(), resourceBundle(),
repository(), aai(), mutex(p)
{
synchronized sync(mutex);
name = name1;
additive = true;
}
Logger::~Logger()
{
}
void Logger::addRef() const {
ObjectImpl::addRef();
}
void Logger::Log_Hexdump( ::log4cxx::helpers::MessageBuffer & oss, const char *buffer, size_t size, const char *text /*= 0*/ )
{
Log_Hexdump(oss,(const unsigned char*)buffer,size,text);
}
void Logger::Log_Hexdump( ::log4cxx::helpers::MessageBuffer & oss, const unsigned char *buffer, size_t size, const char *text /*= 0*/ )
{
synchronized sync(mutex);
char *msg_buf;
// 58 for the HEXDUMP header;
size_t text_sz = text ? strlen(text) : 0;
int len = size;
if (size > 512)
{
len = 512;
}
text_sz += 3*size+ (size/10) +1;
msg_buf = new char[text_sz+58];
memset(msg_buf,0,58+text_sz);
int sz = 0;
if (text)
sz = sprintf (msg_buf,
("%s - "),
text);
if (len < size)
sprintf (msg_buf + sz,(" HEXDUMP %u bytes showing first %u bytes\n"),size,len);
else
sz += sprintf (msg_buf + sz,(" HEXDUMP %u bytes \n"),size);
int nCurLen = strlen(msg_buf);
for (int i = 0; i < len;i++)
{
if ((i+1)%10 == 0)
{
sprintf(&msg_buf[nCurLen],"%02x ",buffer[i]);
nCurLen +=4;
}else
{
sprintf(&msg_buf[nCurLen],"%02x ",buffer[i]);
nCurLen +=3;
}
}
oss << msg_buf;
delete [] msg_buf;
}
int Logger::Format_hexdump( const char *buffer, size_t size, char *obuf, size_t obuf_sz )
{
unsigned char c;
char textver[16 + 1];
// We can fit 16 bytes output in text mode per line, 4 chars per byte.
size_t maxlen = (obuf_sz / 68) * 16;
if (size > maxlen)
size = maxlen;
size_t i;
size_t lines = size / 16;
for (i = 0; i < lines; i++)
{
size_t j;
for (j = 0 ; j < 16; j++)
{
c = (unsigned char) buffer[(i << 4) + j]; // or, buffer[i*16+j]
sprintf (obuf,
("%02x "),
c);
obuf += 3;
if (j == 7)
{
sprintf (obuf,
(" "));
obuf++;
}
textver[j] = isprint (c) ? c : '.';
}
textver[j] = 0;
sprintf (obuf,
(" %s\n"),
textver);
while (*obuf != '\0')
obuf++;
}
if (size % 16)
{
for (i = 0 ; i < size % 16; i++)
{
c = (unsigned char) buffer[size - size % 16 + i];
sprintf (obuf,
("%02x "),
c);
obuf += 3;
if (i == 7)
{
sprintf (obuf,
(" "));
obuf++;
}
textver[i] = isprint (c) ? c : '.';
}
for (i = size % 16; i < 16; i++)
{
sprintf (obuf,
(" "));
obuf += 3;
if (i == 7)
{
sprintf (obuf,
(" "));
obuf++;
}
textver[i] = ' ';
}
textver[i] = 0;
sprintf (obuf,
(" %s\n"),
textver);
}
return size;
}
void Logger::releaseRef() const {
ObjectImpl::releaseRef();
}
void Logger::addAppender(const AppenderPtr& newAppender)
{
synchronized sync(mutex);
if (aai == 0)
{
aai = new AppenderAttachableImpl(*pool);
}
aai->addAppender(newAppender);
if (repository != 0) {
repository->fireAddAppenderEvent(this, newAppender);
}
}
void Logger::callAppenders(const spi::LoggingEventPtr& event, Pool& p) const
{
int writes = 0;
for(LoggerPtr logger(const_cast<Logger*>(this));
logger != 0;
logger = logger->parent)
{
// Protected against simultaneous call to addAppender, removeAppender,...
synchronized sync(logger->mutex);
if (logger->aai != 0)
{
writes += logger->aai->appendLoopOnAppenders(event, p);
}
if(!logger->additive)
{
break;
}
}
if(writes == 0 && repository != 0)
{
repository->emitNoAppenderWarning(const_cast<Logger*>(this));
}
}
void Logger::closeNestedAppenders()
{
AppenderList appenders = getAllAppenders();
for(AppenderList::iterator it=appenders.begin(); it!=appenders.end(); ++it)
{
(*it)->close();
}
}
void Logger::forcedLog(const LevelPtr& level1, const std::string& message,
const LocationInfo& location) const
{
Pool p;
LOG4CXX_DECODE_CHAR(msg, message);
LoggingEventPtr event(new LoggingEvent(name, level1, msg, location));
callAppenders(event, p);
}
void Logger::forcedLog(const LevelPtr& level1, const std::string& message) const
{
Pool p;
LOG4CXX_DECODE_CHAR(msg, message);
LoggingEventPtr event(new LoggingEvent(name, level1, msg,
LocationInfo::getLocationUnavailable()));
callAppenders(event, p);
}
void Logger::forcedLogLS(const LevelPtr& level1, const LogString& message,
const LocationInfo& location) const
{
Pool p;
LoggingEventPtr event(new LoggingEvent(name, level1, message, location));
callAppenders(event, p);
}
bool Logger::getAdditivity() const
{
return additive;
}
AppenderList Logger::getAllAppenders() const
{
synchronized sync(mutex);
if (aai == 0)
{
return AppenderList();
}
else
{
return aai->getAllAppenders();
}
}
AppenderPtr Logger::getAppender(const LogString& name1) const
{
synchronized sync(mutex);
if (aai == 0 || name1.empty())
{
return 0;
}
return aai->getAppender(name1);
}
const LevelPtr& Logger::getEffectiveLevel() const
{
for(const Logger * l = this; l != 0; l=l->parent)
{
if(l->level != 0)
{
return l->level;
}
}
throw NullPointerException(LOG4CXX_STR("No level specified for logger or ancestors."));
#if LOG4CXX_RETURN_AFTER_THROW
return this->level;
#endif
}
LoggerRepositoryPtr Logger::getLoggerRepository() const
{
return repository;
}
ResourceBundlePtr Logger::getResourceBundle() const
{
for (LoggerPtr l(const_cast<Logger*>(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;
}
LogString Logger::getResourceBundleString(const LogString& 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 LogString();
}
else
{
try
{
return rb->getString(key);
}
catch (MissingResourceException&)
{
logLS(Level::getError(), LOG4CXX_STR("No resource is associated with key \"") +
key + LOG4CXX_STR("\"."), LocationInfo::getLocationUnavailable());
return LogString();
}
}
}
LoggerPtr Logger::getParent() const
{
return parent;
}
LevelPtr Logger::getLevel() const
{
return level;
}
bool Logger::isAttached(const AppenderPtr& appender) const
{
synchronized sync(mutex);
if (appender == 0 || aai == 0)
{
return false;
}
else
{
return aai->isAttached(appender);
}
}
bool Logger::isTraceEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::TRACE_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::TRACE_INT;
}
bool Logger::isDebugEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::DEBUG_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::DEBUG_INT;
}
bool Logger::isEnabledFor(const LevelPtr& level1) const
{
if(repository == 0 || repository->isDisabled(level1->toInt()))
{
return false;
}
return level1->isGreaterOrEqual(getEffectiveLevel());
}
bool Logger::isInfoEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::INFO_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::INFO_INT;
}
bool Logger::isErrorEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::ERROR_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::ERROR_INT;
}
bool Logger::isWarnEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::WARN_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::WARN_INT;
}
bool Logger::isFatalEnabled() const
{
if(repository == 0 || repository->isDisabled(Level::FATAL_INT))
{
return false;
}
return getEffectiveLevel()->toInt() <= Level::FATAL_INT;
}
/*void Logger::l7dlog(const LevelPtr& level, const String& key,
const char* file, int line)
{
if (repository == 0 || 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& level1, const LogString& key,
const LocationInfo& location, const std::vector<LogString>& params) const
{
if (repository == 0 || repository->isDisabled(level1->toInt()))
{
return;
}
if (level1->isGreaterOrEqual(getEffectiveLevel()))
{
LogString pattern = getResourceBundleString(key);
LogString msg;
if (pattern.empty())
{
msg = key;
}
else
{
msg = StringHelper::format(pattern, params);
}
forcedLogLS(level1, msg, location);
}
}
void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
const LocationInfo& location) const {
LOG4CXX_DECODE_CHAR(lkey, key);
std::vector<LogString> values(0);
l7dlog(level1, lkey, location, values);
}
void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
const LocationInfo& location, const std::string& val1) const {
LOG4CXX_DECODE_CHAR(lkey, key);
LOG4CXX_DECODE_CHAR(lval1, val1);
std::vector<LogString> values(1);
values[0] = lval1;
l7dlog(level1, lkey, location, values);
}
void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
const LocationInfo& location,
const std::string& val1, const std::string& val2) const {
LOG4CXX_DECODE_CHAR(lkey, key);
LOG4CXX_DECODE_CHAR(lval1, val1);
LOG4CXX_DECODE_CHAR(lval2, val2);
std::vector<LogString> values(2);
values[0] = lval1;
values[1] = lval2;
l7dlog(level1, lkey, location, values);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -