Rev. | fd6f17aa83ef990b489a78480b1571b56a069c59 |
---|---|
Tamanho | 26,989 bytes |
Hora | 2011-11-27 02:49:53 |
Autor | hibari |
Mensagem de Log | formatted all files with 'astyle -A8 -HUpc -k3 -z2 -r ./*.cpp ./*.c ./*.h'.
|
/*!
* @file logger_impl.h
* @brief logger module implementation class.
*
* L7VSD: Linux Virtual Server for Layer7 Load Balancing
* Copyright (C) 2009 NTT COMWARE Corporation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
**********************************************************************/
#ifndef LOGGER_IMPL_H
#define LOGGER_IMPL_H
#include <sstream>
#include <map>
#include <log4cxx/logger.h>
#include <log4cxx/level.h>
#include <log4cxx/net/syslogappender.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/rollingfileappender.h>
#include <log4cxx/patternlayout.h>
#include <boost/format.hpp>
#include <boost/tr1/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include "logger_enum.h"
#include "logger_rotation_enum.h"
#include "appender_property.h"
#include "atomic.h"
#include "wrlock.h"
#if !defined(LOGGER_PROCESS_VSD) && !defined(LOGGER_PROCESS_ADM)
#define LOGGER_PROCESS_VSD
#endif
#if defined(LOGGER_PROCESS_VSD)
#define LOGGER_PROCESS_ID "VSD"
#elif defined(LOGGER_PROCESS_ADM)
#define LOGGER_PROCESS_ID "ADM"
#endif
#define LOGGER_PROCESS_PROTOCOL_MODULE_ID "PRM"
#define LOGGER_PROCESS_SCHEDULE_MODULE_ID "SCM"
#define LOGGER_NULL "/dev/null"
#define LOGGER_LEVEL_NUM (6)
namespace log4cxx
{
typedef helpers::ObjectPtrT<RollingFileAppender> RollingFileAppenderPtr;
}
namespace l7vs
{
//! @class LoggerImpl
//! @brief Logger implement class.
//! @brief this class manage logger setting and logging by log4cxx.
class LoggerImpl
{
protected:
//! typedef category <-> level map
typedef std::map< LOG_CATEGORY_TAG, LOG_LEVEL_TAG>
category_level_map_type;
//! typedef category <-> level map read only
typedef std::tr1::unordered_map< LOG_CATEGORY_TAG, LOG_LEVEL_TAG>
category_level_read_map_type;
//! typedef categoryname <-> CATEGORY_TAG map
typedef std::map< std::string, LOG_CATEGORY_TAG>
name_category_map_type;
//! typedef CATEGORY_TAG <-> categoryname map
typedef std::map< LOG_CATEGORY_TAG, std::string>
category_name_map_type;
public:
//! returns current instance.
static LoggerImpl &getInstance();
//! initialize function
virtual bool init();
//! Configuration function
virtual void loadConf();
/*!
* retrieve category's log level.
*
* @param category that want to know
* @return log level
*/
virtual inline LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat) {
return category_level_read_map[cat];
}
/*!
* retrieve all category's log level.
*
* @param[out] category level list
*/
virtual inline void getLogLevelAll(category_level_list_type &list) {
category_level_read_map.clear();
BOOST_FOREACH(category_level_map_type::value_type const & itr, category_level_map) {
category_level_read_map[itr.first] = itr.second;
list.push_back(std::make_pair(itr.first, itr.second));
}
}
/*!
* set category's log level.
*
* @param category to set log level
* @param level
* @retval true succeed
* @retval false failed
*/
virtual inline bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level) {
category_level_map_type::iterator lv_itr = category_level_map.find(cat);
lv_itr->second = level;
category_level_read_map.clear();
BOOST_FOREACH(category_level_map_type::value_type const & itr, category_level_map) {
category_level_read_map[itr.first] = itr.second;
}
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
try {
log4cxx::Logger::getLogger(categoryname_itr->second)->setLevel(log4cxx::Level::toLevel(levelTable[level]));
} catch (const std::exception &ex) {
return false;
}
return true;
}
/*!
* set all category's log level.
*
* @param category to set log level
* @param level
* @retval true succeed
* @retval false failed
*/
virtual inline bool setLogLevelAll(LOG_LEVEL_TAG level) {
category_level_read_map.clear();
BOOST_FOREACH(category_level_map_type::value_type & itr, category_level_map) {
itr.second = level;
category_level_read_map[itr.first] = itr.second;
category_name_map_type::iterator categoryname_itr = category_name_map.find(itr.first);
try {
log4cxx::Logger::getLogger(categoryname_itr->second)->setLevel(log4cxx::Level::toLevel(levelTable[level]));
} catch (const std::exception &ex) {
return false;
}
}
return true;
}
/*!
* output fatal log.
*
* @param category that logging matter occurred
* @param log message id
* @param log message
* @param current file
* @param current line
* @retrun void
*/
virtual inline void putLogFatal(LOG_CATEGORY_TAG cat,
const unsigned int message_id,
const std::string &message,
const char *file,
int line) {
std::stringstream buf;
switch (cat) {
case LOG_CAT_PROTOCOL:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_PROTOCOL_MODULE_ID
% LOG_LV_FATAL
% message_id
% message.c_str()
% hostname;
break;
case LOG_CAT_SCHEDULE:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_SCHEDULE_MODULE_ID
% LOG_LV_FATAL
% message_id
% message.c_str()
% hostname;
break;
default:
buf << boost::format("%s%d%02d%05d %s %s")
% LOGGER_PROCESS_ID
% LOG_LV_FATAL
% cat
% message_id
% message.c_str()
% hostname;
}
try {
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getFatal(),
buf.str(),
log4cxx::spi::LocationInfo(file, "", line));
// send_trap
if (logtrap_enabled.get() == 1) {
LOG_LEVEL_TAG tmp_level;
{
rd_scoped_lock lock(logtrap_level_mutex);
tmp_level = logtrap_level;
}
if ((tmp_level <= LOG_LV_FATAL) &&
snmp_send_trap_func &&
(LOG_CAT_L7VSD_SNMPAGENT != cat)) {
trapmessage trap_msg;
trap_msg.type = trapmessage::FATAL_LOG;
trap_msg.message = buf.str();
error_code err;
//send trap message
snmp_send_trap_func(trap_msg, err);
}
}
} catch (const std::exception &ex) {
std::ostringstream oss;
oss << "Logging Error (Fatal Log) : " << ex.what();
errorConf(3, oss.str(), __FILE__, __LINE__);
}
}
/*!
* output error log.
*
* @param category that logging matter occurred
* @param log message id
* @param log message
* @param current file
* @param current line
* @retrun void
*/
virtual inline void putLogError(LOG_CATEGORY_TAG cat,
const unsigned int message_id,
const std::string &message,
const char *file,
int line) {
std::stringstream buf;
switch (cat) {
case LOG_CAT_PROTOCOL:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_PROTOCOL_MODULE_ID
% LOG_LV_ERROR
% message_id
% message.c_str()
% hostname;
break;
case LOG_CAT_SCHEDULE:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_SCHEDULE_MODULE_ID
% LOG_LV_ERROR
% message_id
% message.c_str()
% hostname;
break;
default:
buf << boost::format("%s%d%02d%05d %s %s")
% LOGGER_PROCESS_ID
% LOG_LV_ERROR
% cat
% message_id
% message.c_str()
% hostname;
}
try {
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getError(),
buf.str(),
log4cxx::spi::LocationInfo(file, "", line));
// send_trap
if (logtrap_enabled.get() == 1) {
LOG_LEVEL_TAG tmp_level;
{
rd_scoped_lock lock(logtrap_level_mutex);
tmp_level = logtrap_level;
}
if ((tmp_level <= LOG_LV_ERROR) &&
snmp_send_trap_func &&
(LOG_CAT_L7VSD_SNMPAGENT != cat)) {
trapmessage trap_msg;
trap_msg.type = trapmessage::ERROR_LOG;
trap_msg.message = buf.str();
error_code err;
//send trap message
snmp_send_trap_func(trap_msg, err);
}
}
} catch (const std::exception &ex) {
std::ostringstream oss;
oss << "Logging Error (Error Log) : " << ex.what();
errorConf(4, oss.str(), __FILE__, __LINE__);
}
}
/*!
* output warn log.
*
* @param category that logging matter occurred
* @param log message id
* @param log message
* @param current file
* @param current line
* @retrun void
*/
virtual inline void putLogWarn(LOG_CATEGORY_TAG cat,
const unsigned int message_id,
const std::string &message,
const char *file,
int line) {
std::stringstream buf;
switch (cat) {
case LOG_CAT_PROTOCOL:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_PROTOCOL_MODULE_ID
% LOG_LV_WARN
% message_id
% message.c_str()
% hostname;
break;
case LOG_CAT_SCHEDULE:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_SCHEDULE_MODULE_ID
% LOG_LV_WARN
% message_id
% message.c_str()
% hostname;
break;
default:
buf << boost::format("%s%d%02d%05d %s %s")
% LOGGER_PROCESS_ID
% LOG_LV_WARN
% cat
% message_id
% message.c_str()
% hostname;
}
try {
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getWarn(),
buf.str(),
log4cxx::spi::LocationInfo(file, "", line));
// send_trap
if (logtrap_enabled.get() == 1) {
LOG_LEVEL_TAG tmp_level;
{
rd_scoped_lock lock(logtrap_level_mutex);
tmp_level = logtrap_level;
}
if ((tmp_level <= LOG_LV_WARN) &&
snmp_send_trap_func &&
(LOG_CAT_L7VSD_SNMPAGENT != cat)) {
trapmessage trap_msg;
trap_msg.type = trapmessage::WARN_LOG;
trap_msg.message = buf.str();
error_code err;
//send trap message
snmp_send_trap_func(trap_msg, err);
}
}
} catch (const std::exception &ex) {
std::ostringstream oss;
oss << "Logging Error (Warn Log) : " << ex.what();
errorConf(5, oss.str(), __FILE__, __LINE__);
}
}
/*!
* output info log.
*
* @param category that logging matter occurred
* @param log message id
* @param log message
* @param current file
* @param current line
* @retrun void
*/
virtual inline void putLogInfo(LOG_CATEGORY_TAG cat,
const unsigned int message_id,
const std::string &message,
const char *file,
int line) {
std::stringstream buf;
switch (cat) {
case LOG_CAT_PROTOCOL:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_PROTOCOL_MODULE_ID
% LOG_LV_INFO
% message_id
% message.c_str()
% hostname;
break;
case LOG_CAT_SCHEDULE:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_SCHEDULE_MODULE_ID
% LOG_LV_INFO
% message_id
% message.c_str()
% hostname;
break;
default:
buf << boost::format("%s%d%02d%05d %s %s")
% LOGGER_PROCESS_ID
% LOG_LV_INFO
% cat
% message_id
% message.c_str()
% hostname;
}
try {
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getInfo(),
buf.str(),
log4cxx::spi::LocationInfo(file, "", line));
// send_trap
if (logtrap_enabled.get() == 1) {
LOG_LEVEL_TAG tmp_level;
{
rd_scoped_lock lock(logtrap_level_mutex);
tmp_level = logtrap_level;
}
if ((tmp_level <= LOG_LV_INFO) &&
snmp_send_trap_func &&
(LOG_CAT_L7VSD_SNMPAGENT != cat)) {
trapmessage trap_msg;
trap_msg.type = trapmessage::INFO_LOG;
trap_msg.message = buf.str();
error_code err;
//send trap message
snmp_send_trap_func(trap_msg, err);
}
}
} catch (const std::exception &ex) {
std::ostringstream oss;
oss << "Logging Error (Info Log) : " << ex.what();
errorConf(6, oss.str(), __FILE__, __LINE__);
}
}
/*!
* output debug log.
*
* @param category that logging matter occurred
* @param log message id
* @param log message
* @param current file
* @param current line
* @retrun void
*/
virtual inline void putLogDebug(LOG_CATEGORY_TAG cat,
const unsigned int message_id,
const std::string &message,
const char *file,
int line) {
std::stringstream buf;
std::string logger_process_id = LOGGER_PROCESS_ID;
switch (cat) {
case LOG_CAT_PROTOCOL:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_PROTOCOL_MODULE_ID
% LOG_LV_DEBUG
% message_id
% message.c_str()
% hostname;
break;
case LOG_CAT_SCHEDULE:
buf << boost::format("%s%d%07d %s %s")
% LOGGER_PROCESS_SCHEDULE_MODULE_ID
% LOG_LV_DEBUG
% message_id
% message.c_str()
% hostname;
break;
default:
buf << boost::format("%s%d%02d%05d %s %s")
% LOGGER_PROCESS_ID
% LOG_LV_DEBUG
% cat
% message_id
% message.c_str()
% hostname;
}
try {
category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getDebug(),
buf.str(), log4cxx::spi::LocationInfo(file, "", line));
// send_trap
if (logtrap_enabled.get() == 1) {
LOG_LEVEL_TAG tmp_level;
{
rd_scoped_lock lock(logtrap_level_mutex);
tmp_level = logtrap_level;
}
if ((tmp_level <= LOG_LV_DEBUG) &&
snmp_send_trap_func &&
(LOG_CAT_L7VSD_SNMPAGENT != cat)) {
trapmessage trap_msg;
trap_msg.type = trapmessage::DEBUG_LOG;
trap_msg.message = buf.str();
error_code err;
//send trap message
snmp_send_trap_func(trap_msg, err);
}
}
} catch (const std::exception &ex) {
std::ostringstream oss;
oss << "Logging Error (Debug Log) : " << ex.what();
errorConf(7, oss.str(), __FILE__, __LINE__);
}
}
/*!
* set snmp sendtrap function
*
* @param snmp send trap function object
* @retrun void
*/
void set_snmp_send_trap_func(const snmp_send_trap_func_type func) {
snmp_send_trap_func = func;
}
/*!
* set log trap enable
* @retrun void
*/
void logtrap_enable() {
logtrap_enabled = true;
}
/*!
* set log trap disable
* @retrun void
*/
void logtrap_disable() {
logtrap_enabled = false;
}
/*!
* set log trap level
* @param log trap level
* @retrun void
*/
void set_logtrap_level(LOG_LEVEL_TAG in_logtrap_level) {
rw_scoped_lock lock(logtrap_level_mutex);
logtrap_level = in_logtrap_level;
}
protected:
//! default constructor initialize member variables.
LoggerImpl();
//! copy constructor disable
LoggerImpl(const LoggerImpl &);
//! operator= disable
LoggerImpl &operator=(const LoggerImpl &);
//! LOG_LEVEL_TAG to log4cxx::LevelPtr translator
virtual inline const log4cxx::LevelPtr toLevel(LOG_LEVEL_TAG level) {
return log4cxx::Level::toLevel(levelTable[level]);
}
//! if error occurred, switch appenders to syslogappender and fileappender(/dev/console)
virtual void errorConf(unsigned int messageId,
const std::string &errorMessage,
const char *file,
int line);
virtual void logic_error(const unsigned int, const std::string &, const char *, const unsigned int);
/*
//! log4cxx::LevelPtr to LOG_LEVEL_TAG translator
virtual inline LOG_LEVEL_TAG toLevelTag(const log4cxx::LevelPtr level){
int levelInt = level->toInt();
switch (levelInt) {
case log4cxx::Level::DEBUG_INT:
return LOG_LV_DEBUG;
case log4cxx::Level::INFO_INT:
return LOG_LV_INFO;
case log4cxx::Level::WARN_INT:
return LOG_LV_WARN;
case log4cxx::Level::ERROR_INT:
return LOG_LV_ERROR;
case log4cxx::Level::FATAL_INT:
return LOG_LV_FATAL;
default:
return LOG_LV_DEBUG;
}
}
*/
//! destructor.
virtual ~LoggerImpl() {}
//! initialized flag
bool initialized;
//! hostname
std::string hostname;
//log4cxx::Level* levelTable[LOGGER_LEVEL_NUM];
int levelTable[LOGGER_LEVEL_NUM];
//! category - loglevel hash map
category_level_map_type category_level_map;
category_level_read_map_type category_level_read_map;
//! category string -> logcategory hash map
name_category_map_type name_category_map;
//! log_category -> category string hash map
category_name_map_type category_name_map;
appender_property normal_log_property;
appender_property access_log_property;
//! snmp trap function
snmp_send_trap_func_type snmp_send_trap_func;
//! snmp log trap enable flag
atomic<unsigned int> logtrap_enabled;
//! snmp log trap level
LOG_LEVEL_TAG logtrap_level;
//! snmp log trap level mutex
wr_mutex logtrap_level_mutex;
};
} //namespace l7vs
#endif //__LOGGER_IMPL_H__