3 * @brief logger module implementation class.
5 * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6 * Copyright (C) 2009 NTT COMWARE Corporation.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 **********************************************************************/
30 #include <log4cxx/logger.h>
31 #include <log4cxx/level.h>
32 #include <log4cxx/net/syslogappender.h>
33 #include <log4cxx/fileappender.h>
34 #include <log4cxx/rollingfileappender.h>
35 #include <log4cxx/patternlayout.h>
36 #include <boost/format.hpp>
37 #include <boost/tr1/unordered_map.hpp>
38 #include <boost/foreach.hpp>
39 #include <boost/thread.hpp>
40 #include "logger_enum.h"
41 #include "logger_rotation_enum.h"
42 #include "appender_property.h"
46 #if !defined(LOGGER_PROCESS_VSD) && !defined(LOGGER_PROCESS_ADM) && !defined(LOGGER_PROCESS_SNM)
47 #define LOGGER_PROCESS_VSD
50 #if defined(LOGGER_PROCESS_VSD)
51 #define LOGGER_PROCESS_ID "VSD"
52 #elif defined(LOGGER_PROCESS_ADM)
53 #define LOGGER_PROCESS_ID "ADM"
55 #define LOGGER_PROCESS_ID "SNM"
58 #define LOGGER_PROCESS_PROTOCOL_MODULE_ID "PRM"
60 #define LOGGER_PROCESS_SCHEDULE_MODULE_ID "SCM"
62 #define LOGGER_NULL "/dev/null"
64 #define LOGGER_LEVEL_NUM (6)
68 typedef helpers::ObjectPtrT<RollingFileAppender> RollingFileAppenderPtr;
75 //! @brief Logger implement class.
76 //! @brief this class manage logger setting and logging by log4cxx.
80 //! typedef category <-> level map
81 typedef std::map< LOG_CATEGORY_TAG, LOG_LEVEL_TAG>
82 category_level_map_type;
83 //! typedef category <-> level map read only
84 typedef std::tr1::unordered_map< LOG_CATEGORY_TAG, LOG_LEVEL_TAG>
85 category_level_read_map_type;
86 //! typedef categoryname <-> CATEGORY_TAG map
87 typedef std::map< std::string, LOG_CATEGORY_TAG>
88 name_category_map_type;
89 //! typedef CATEGORY_TAG <-> categoryname map
90 typedef std::map< LOG_CATEGORY_TAG, std::string>
91 category_name_map_type;
93 //! returns current instance.
94 static LoggerImpl &getInstance();
96 //! initialze function
99 //! Configuration function
100 virtual void loadConf();
103 * retrieve category's log level.
105 * @param category that want to know
108 virtual inline LOG_LEVEL_TAG getLogLevel(LOG_CATEGORY_TAG cat) {
109 return category_level_read_map[cat];
113 * retrieve all category's log level.
115 * @param[out] category level list
117 virtual inline void getLogLevelAll(category_level_list_type &list) {
118 category_level_read_map.clear();
119 BOOST_FOREACH(category_level_map_type::value_type const & itr, category_level_map) {
120 category_level_read_map[itr.first] = itr.second;
121 list.push_back(std::make_pair(itr.first, itr.second));
126 * set category's log level.
128 * @param category to set log level
130 * @retval true succeed
131 * @retval false failed
133 virtual inline bool setLogLevel(LOG_CATEGORY_TAG cat, LOG_LEVEL_TAG level) {
134 category_level_map_type::iterator lv_itr = category_level_map.find(cat);
135 lv_itr->second = level;
137 category_level_read_map.clear();
138 BOOST_FOREACH(category_level_map_type::value_type const & itr, category_level_map) {
139 category_level_read_map[itr.first] = itr.second;
142 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
145 log4cxx::Logger::getLogger(categoryname_itr->second)->setLevel(log4cxx::Level::toLevel(levelTable[level]));
146 } catch (const std::exception &ex) {
153 * set all category's log level.
155 * @param category to set log level
157 * @retval true succeed
158 * @retval false failed
160 virtual inline bool setLogLevelAll(LOG_LEVEL_TAG level) {
161 category_level_read_map.clear();
162 BOOST_FOREACH(category_level_map_type::value_type & itr, category_level_map) {
164 category_level_read_map[itr.first] = itr.second;
166 category_name_map_type::iterator categoryname_itr = category_name_map.find(itr.first);
168 log4cxx::Logger::getLogger(categoryname_itr->second)->setLevel(log4cxx::Level::toLevel(levelTable[level]));
169 } catch (const std::exception &ex) {
179 * @param category that logging matter occured
180 * @param log message id
182 * @param current file
183 * @param current line
186 virtual inline void putLogFatal(LOG_CATEGORY_TAG cat,
187 const unsigned int message_id,
188 const std::string &message,
191 std::stringstream buf;
195 case LOG_CAT_PROTOCOL:
197 buf << boost::format("%s%d%07d %s %s")
198 % LOGGER_PROCESS_PROTOCOL_MODULE_ID
205 case LOG_CAT_SCHEDULE:
207 buf << boost::format("%s%d%07d %s %s")
208 % LOGGER_PROCESS_SCHEDULE_MODULE_ID
217 buf << boost::format("%s%d%02d%05d %s %s")
228 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
229 log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getFatal(),
231 log4cxx::spi::LocationInfo(file, "", line));
233 if (logtrap_enabled.get() == 1) {
234 LOG_LEVEL_TAG tmp_level;
236 rd_scoped_lock lock(logtrap_level_mutex);
237 tmp_level = logtrap_level;
239 if ( (tmp_level >= LOG_LV_FATAL) &&
240 snmp_send_trap_func &&
241 (LOG_CAT_L7VSD_SNMPAGENT != cat)) {
242 trapmessage trap_msg;
243 trap_msg.type = trapmessage::FATAL_LOG;
244 trap_msg.message = buf.str();
247 snmp_send_trap_func(trap_msg, err);
250 } catch (const std::exception &ex) {
251 std::ostringstream oss;
252 oss << "Logging Error (Fatal Log) : " << ex.what();
253 errorConf(3, oss.str(), __FILE__, __LINE__);
259 * @param category that logging matter occured
260 * @param log message id
262 * @param current file
263 * @param current line
266 virtual inline void putLogError(LOG_CATEGORY_TAG cat,
267 const unsigned int message_id,
268 const std::string &message,
271 std::stringstream buf;
274 case LOG_CAT_PROTOCOL:
276 buf << boost::format("%s%d%07d %s %s")
277 % LOGGER_PROCESS_PROTOCOL_MODULE_ID
284 case LOG_CAT_SCHEDULE:
286 buf << boost::format("%s%d%07d %s %s")
287 % LOGGER_PROCESS_SCHEDULE_MODULE_ID
296 buf << boost::format("%s%d%02d%05d %s %s")
307 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
308 log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getError(),
310 log4cxx::spi::LocationInfo(file, "", line));
312 if (logtrap_enabled.get() == 1) {
313 LOG_LEVEL_TAG tmp_level;
315 rd_scoped_lock lock(logtrap_level_mutex);
316 tmp_level = logtrap_level;
318 if ( (tmp_level >= LOG_LV_ERROR) &&
319 snmp_send_trap_func &&
320 (LOG_CAT_L7VSD_SNMPAGENT != cat)) {
321 trapmessage trap_msg;
322 trap_msg.type = trapmessage::ERROR_LOG;
323 trap_msg.message = buf.str();
326 snmp_send_trap_func(trap_msg, err);
329 } catch (const std::exception &ex) {
330 std::ostringstream oss;
331 oss << "Logging Error (Error Log) : " << ex.what();
332 errorConf(4, oss.str(), __FILE__, __LINE__);
338 * @param category that logging matter occured
339 * @param log message id
341 * @param current file
342 * @param current line
345 virtual inline void putLogWarn(LOG_CATEGORY_TAG cat,
346 const unsigned int message_id,
347 const std::string &message,
350 std::stringstream buf;
353 case LOG_CAT_PROTOCOL:
355 buf << boost::format("%s%d%07d %s %s")
356 % LOGGER_PROCESS_PROTOCOL_MODULE_ID
363 case LOG_CAT_SCHEDULE:
365 buf << boost::format("%s%d%07d %s %s")
366 % LOGGER_PROCESS_SCHEDULE_MODULE_ID
375 buf << boost::format("%s%d%02d%05d %s %s")
386 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
387 log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getWarn(),
389 log4cxx::spi::LocationInfo(file, "", line));
391 if (logtrap_enabled.get() == 1) {
392 LOG_LEVEL_TAG tmp_level;
394 rd_scoped_lock lock(logtrap_level_mutex);
395 tmp_level = logtrap_level;
397 if ( (tmp_level >= LOG_LV_WARN) &&
398 snmp_send_trap_func &&
399 (LOG_CAT_L7VSD_SNMPAGENT != cat)) {
400 trapmessage trap_msg;
401 trap_msg.type = trapmessage::WARN_LOG;
402 trap_msg.message = buf.str();
405 snmp_send_trap_func(trap_msg, err);
408 } catch (const std::exception &ex) {
409 std::ostringstream oss;
410 oss << "Logging Error (Warn Log) : " << ex.what();
411 errorConf(5, oss.str(), __FILE__, __LINE__);
417 * @param category that logging matter occured
418 * @param log message id
420 * @param current file
421 * @param current line
424 virtual inline void putLogInfo(LOG_CATEGORY_TAG cat,
425 const unsigned int message_id,
426 const std::string &message,
429 std::stringstream buf;
432 case LOG_CAT_PROTOCOL:
434 buf << boost::format("%s%d%07d %s %s")
435 % LOGGER_PROCESS_PROTOCOL_MODULE_ID
442 case LOG_CAT_SCHEDULE:
444 buf << boost::format("%s%d%07d %s %s")
445 % LOGGER_PROCESS_SCHEDULE_MODULE_ID
454 buf << boost::format("%s%d%02d%05d %s %s")
465 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
466 log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getInfo(),
468 log4cxx::spi::LocationInfo(file, "", line));
471 if (logtrap_enabled.get() == 1) {
472 LOG_LEVEL_TAG tmp_level;
474 rd_scoped_lock lock(logtrap_level_mutex);
475 tmp_level = logtrap_level;
477 if ( (tmp_level >= LOG_LV_INFO) &&
478 snmp_send_trap_func &&
479 (LOG_CAT_L7VSD_SNMPAGENT != cat)) {
480 trapmessage trap_msg;
481 trap_msg.type = trapmessage::INFO_LOG;
482 trap_msg.message = buf.str();
485 snmp_send_trap_func(trap_msg, err);
488 } catch (const std::exception &ex) {
489 std::ostringstream oss;
490 oss << "Logging Error (Info Log) : " << ex.what();
491 errorConf(6, oss.str(), __FILE__, __LINE__);
497 * @param category that logging matter occured
498 * @param log message id
500 * @param current file
501 * @param current line
504 virtual inline void putLogDebug(LOG_CATEGORY_TAG cat,
505 const unsigned int message_id,
506 const std::string &message,
509 std::stringstream buf;
510 std::string logger_process_id = LOGGER_PROCESS_ID;
513 case LOG_CAT_PROTOCOL:
515 buf << boost::format("%s%d%07d %s %s")
516 % LOGGER_PROCESS_PROTOCOL_MODULE_ID
523 case LOG_CAT_SCHEDULE:
525 buf << boost::format("%s%d%07d %s %s")
526 % LOGGER_PROCESS_SCHEDULE_MODULE_ID
535 buf << boost::format("%s%d%02d%05d %s %s")
547 category_name_map_type::iterator categoryname_itr = category_name_map.find(cat);
548 log4cxx::Logger::getLogger(categoryname_itr->second)->forcedLog(log4cxx::Level::getDebug(),
549 buf.str(), log4cxx::spi::LocationInfo(file, "", line));
551 if (logtrap_enabled.get() == 1) {
552 LOG_LEVEL_TAG tmp_level;
554 rd_scoped_lock lock(logtrap_level_mutex);
555 tmp_level = logtrap_level;
557 if ( (tmp_level >= LOG_LV_DEBUG) &&
558 snmp_send_trap_func &&
559 (LOG_CAT_L7VSD_SNMPAGENT != cat)) {
560 trapmessage trap_msg;
561 trap_msg.type = trapmessage::DEBUG_LOG;
562 trap_msg.message = buf.str();
566 snmp_send_trap_func(trap_msg, err);
569 } catch (const std::exception &ex) {
570 std::ostringstream oss;
571 oss << "Logging Error (Debug Log) : " << ex.what();
572 errorConf(7, oss.str(), __FILE__, __LINE__);
577 * set snmp sendtrap function
579 * @param snmp send trap function object
582 void set_snmp_send_trap_func(const snmp_send_trap_func_type func) {
583 snmp_send_trap_func = func;
587 * set log trap enable
590 void logtrap_enable() {
591 logtrap_enabled = true;
595 * set log trap disable
598 void logtrap_disable() {
599 logtrap_enabled = false;
604 * @param log trap level
607 void set_logtrap_level(LOG_LEVEL_TAG in_logtrap_level) {
608 rw_scoped_lock lock(logtrap_level_mutex);
609 logtrap_level = in_logtrap_level;
614 //! default constructor initialize member variables.
617 //! cpoy constructor disable
618 LoggerImpl(const LoggerImpl &);
620 //! operator= disable
621 LoggerImpl &operator=(const LoggerImpl &);
623 //! LOG_LEVEL_TAG to log4cxx::LevelPtr transrator
624 virtual inline const log4cxx::LevelPtr toLevel(LOG_LEVEL_TAG level) {
625 return log4cxx::Level::toLevel(levelTable[level]);
628 //! if error occured, switch appenders to syslogappender and fileappender(/dev/console)
629 virtual void errorConf(unsigned int messageId,
630 const std::string &errorMessage,
634 virtual void logic_error(const unsigned int, const std::string &, const char *, const unsigned int);
637 //! log4cxx::LevelPtr to LOG_LEVEL_TAG transrator
638 virtual inline LOG_LEVEL_TAG toLevelTag(const log4cxx::LevelPtr level){
639 int levelInt = level->toInt();
641 case log4cxx::Level::DEBUG_INT:
643 case log4cxx::Level::INFO_INT:
645 case log4cxx::Level::WARN_INT:
647 case log4cxx::Level::ERROR_INT:
649 case log4cxx::Level::FATAL_INT:
658 virtual ~LoggerImpl() {}
662 std::string hostname;
664 //log4cxx::Level* levelTable[LOGGER_LEVEL_NUM];
665 int levelTable[LOGGER_LEVEL_NUM];
667 //! category - loglevel hash map
668 category_level_map_type category_level_map;
669 category_level_read_map_type category_level_read_map;
670 //! category string -> logcateogry hash map
671 name_category_map_type name_category_map;
672 //! log_category -> category string hash map
673 category_name_map_type category_name_map;
675 appender_property normal_log_property;
676 appender_property access_log_property;
678 //! snmp trap function
679 snmp_send_trap_func_type snmp_send_trap_func;
681 //! snmp log trap enable flag
682 atomic<unsigned int> logtrap_enabled;
684 //! snmp log trap level
685 LOG_LEVEL_TAG logtrap_level;
687 //! snmp log trap level mutex
688 wr_mutex logtrap_level_mutex;
693 #endif //__LOGGER_IMPL_H__