util/Log4cplus.cpp

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002 Name:      Log4cplus.cpp
00003 Project:   xmlBlaster.org
00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
00005 Comment:   Embed logging library log4cpp http://log4cplus.sourceforge.net/
00006 ----------------------------------------------------------------------------*/
00007 
00008 #if XMLBLASTER_COMPILE_LOG4CPLUS_PLUGIN==1
00009 
00010 #include <util/Log4cplus.h>
00011 #include <log4cplus/logger.h>
00012 #include <log4cplus/configurator.h>
00013 #include <log4cplus/helpers/property.h>
00014 #include <log4cplus/helpers/loglog.h>
00015 #include <fstream>
00016 #include <util/PropertyDef.h>
00017 #include <util/lexical_cast.h>
00018 
00019 using namespace std;
00020 using namespace log4cplus;
00021 
00022 namespace org { namespace xmlBlaster {
00023 namespace util {
00024 
00025    Log4cplusFactory::Log4cplusFactory()
00026    {  
00027    }
00028 
00034    void Log4cplusFactory::initialize(const PropMap& propMap)
00035    {
00036       {
00037          PropMap::const_iterator pos = propMap.find("xmlBlaster/logging/debug");
00038          if (pos != propMap.end()) {
00039             log4cplus::helpers::LogLog::getLogLog()->setInternalDebugging(lexical_cast<bool>(pos->second));
00040          }
00041       }
00042 
00043       bool initialize = true;
00044       PropMap::const_iterator pos = propMap.find("xmlBlaster/logging/initialize");
00045       if (pos != propMap.end())
00046          if ("false" == pos->second)
00047             initialize = false;
00048 
00049 
00050       if (initialize) {
00051          // Find the configuration file name
00052          const char *envName = "xmlBlaster/logging/configFileName";
00053          string configFileName = "log4cplus.properties"; // local directory
00054          pos = propMap.find(envName);
00055          if (pos != propMap.end()) {
00056             configFileName = (*pos).second;
00057          }
00058          else {
00059             const char* envValue = getenv(envName);
00060             if (envValue != 0) {
00061                configFileName = envValue;
00062             }
00063             else {
00064                std::ifstream file;
00065                file.open(configFileName.c_str());  // local directory?
00066                if(!file) {
00067                   pos = propMap.find("user.home");
00068                   if (pos != propMap.end()) {
00069                      string tmp = (*pos).second + FILE_SEP + configFileName;
00070                      std::ifstream file2;
00071                      file2.open(tmp.c_str());
00072                      if(!file2) {
00073                      }
00074                      else {
00075                         configFileName = tmp;
00076                      }
00077                   }
00078                }
00079             }
00080          }
00081 
00082          bool inheritEnvironment = true;
00083 
00084          std::ifstream file;
00085          file.open(configFileName.c_str());
00086          if(!file) {
00087             // No configuration file
00088             if (inheritEnvironment) {
00089                // We pass all xmlBlaster.properties + command line settings to log4cplus
00090                log4cplus::helpers::Properties props;
00091                PropMap::const_iterator iter = propMap.begin();
00092                while (iter != propMap.end()) {
00093                     props.setProperty((*iter).first, (*iter).second);
00094                   iter++;
00095                }
00096                PropertyConfigurator tmp(props, Logger::getDefaultHierarchy());
00097                tmp.configure();
00098             }
00099             else {
00100                BasicConfigurator config;
00101                config.configure();
00102             }
00103             Logger logger = Logger::getInstance("org.xmlBlaster");
00104             LOG4CPLUS_WARN(logger, "Couldn't find file logging configuration file \"-xmlBlaster/logging/configFileName " + configFileName + "\", you can use the example in xmlBlaster" +
00105                                     FILE_SEP + "config" + FILE_SEP + configFileName);
00106             LOG4CPLUS_INFO(logger, "We continue with default logging configuration.");
00107          }
00108          else {
00109             // Scan configuration file
00110             if (inheritEnvironment) {
00111                // Log4Cplus can replace env variables in its config file
00112                // there for we pass all settings from xmlBlaster.properties to log4cplus
00113                log4cplus::helpers::Properties props(configFileName);
00114                PropMap::const_iterator iter = propMap.begin();
00115                while (iter != propMap.end()) {
00116                     props.setProperty((*iter).first, (*iter).second);
00117                   iter++;
00118                }
00119                PropertyConfigurator tmp(props, Logger::getDefaultHierarchy());
00120                tmp.configure();
00121             }
00122             else {
00123                PropertyConfigurator::doConfigure(configFileName);
00124             }
00125 
00126             Logger logger = Logger::getInstance("org.xmlBlaster");
00127             LOG4CPLUS_INFO(logger, "Configured log4cplus with configuration file xmlBlaster/logging/configFileName=" + configFileName);
00128          }
00129       }
00130       else {
00131          Logger logger = Logger::getInstance("org.xmlBlaster");
00132          LOG4CPLUS_INFO(logger, "Log4cplus is configured already (xmlBlaster/logging/initialize=false), no reconfiguration done.");
00133       }
00134 
00135       //Logger logger = Logger::getInstance("org.xmlBlaster");
00136       //LOG4CPLUS_WARN(logger, "LOG4CPLUS: Hello, World!");
00137    }
00138 
00142    Log4cplusFactory::~Log4cplusFactory()
00143    {
00144       LogMap::reverse_iterator i;
00145       for(i = logMap_.rbegin(); i != logMap_.rend(); ++i) {
00146          I_Log* log = (*i).second;
00147          delete log;
00148       }
00149       logMap_.clear();
00150 
00151       //Logger::getDefaultHierarchy().shutdown();
00152       Logger::shutdown();
00153    }
00154 
00158    I_Log& Log4cplusFactory::getLog(const string& logName)
00159    {
00160       LogMap::iterator pos = logMap_.find(logName);
00161       if (pos != logMap_.end()) return *((*pos).second);
00162       
00163       Log4cplusLog *help = new Log4cplusLog(logName);
00164       logMap_.insert(LogMap::value_type(logName, help));
00165       pos = logMap_.find(logName);
00166       if (pos != logMap_.end()) {
00167          I_Log* log = (*pos).second;
00168          return *log;
00169       }
00170 
00171       std::cerr << "LogManager.cpp getLog(" << logName << ") is not implemented -> throwing exception" << std::endl;
00172       throw bad_exception();
00173    }
00174    
00178    void Log4cplusFactory::releaseLog(const string& name)
00179    {
00180       std::cerr << "Log4cplus.cpp releaseLog(" << name << ") is not implemented" << std::endl;
00181    }
00182 
00183 //================== Log4cplusLog implementation ======================
00184 
00185    Log4cplusLog::Log4cplusLog(std::string logName) : logName_(logName), logger_(Logger::getInstance(logName)) {
00186       //Should we set this if basic configured??:
00187       //logger.setLogLevel(INFO_LOG_LEVEL);
00188       call_ = dump_ = time_ = logger_.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL);
00189       trace_ = logger_.isEnabledFor(log4cplus::TRACE_LOG_LEVEL);
00190       info_ = logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL);
00191    }
00192 
00193    void Log4cplusLog::info(const std::string &instance, const std::string &text){
00194       //std::cout << "[INFO]  " << instance << ": " << text << std::endl;
00195       if (logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL)) {
00196          log4cplus::tostringstream _log4cplus_buf;
00197          _log4cplus_buf << text;
00198          logger_.forcedLog(log4cplus::INFO_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00199       }
00200       //LOG4CPLUS_INFO(logger_, text);
00201    }
00202    
00203    void Log4cplusLog::warn(const std::string &instance, const std::string &text){
00204       if (logger_.isEnabledFor(log4cplus::WARN_LOG_LEVEL)) {
00205          log4cplus::tostringstream _log4cplus_buf;
00206          _log4cplus_buf << text;
00207          logger_.forcedLog(log4cplus::WARN_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00208       }
00209    }
00210    
00211    void Log4cplusLog::error(const std::string &instance, const std::string &text){
00212       if (logger_.isEnabledFor(log4cplus::ERROR_LOG_LEVEL)) {
00213          log4cplus::tostringstream _log4cplus_buf;
00214          _log4cplus_buf << text;
00215          logger_.forcedLog(log4cplus::ERROR_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00216       }
00217    }
00218 
00219    void Log4cplusLog::panic(const std::string &instance, const std::string &text){
00220       if (logger_.isEnabledFor(log4cplus::FATAL_LOG_LEVEL)) {
00221          log4cplus::tostringstream _log4cplus_buf;
00222          _log4cplus_buf << text;
00223          logger_.forcedLog(log4cplus::FATAL_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00224       }
00225       ::exit(1);
00226    }
00227    
00228    void Log4cplusLog::trace(const std::string &instance, const std::string &text){
00229       if (logger_.isEnabledFor(log4cplus::TRACE_LOG_LEVEL)) {
00230          log4cplus::tostringstream _log4cplus_buf;
00231          _log4cplus_buf << text;
00232          logger_.forcedLog(log4cplus::TRACE_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00233       }
00234    }
00235    
00236    void Log4cplusLog::call(const std::string &instance, const std::string &text){
00237       if (logger_.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) {
00238          log4cplus::tostringstream _log4cplus_buf;
00239          _log4cplus_buf << text;
00240          logger_.forcedLog(log4cplus::DEBUG_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
00241       }
00242    }
00243 
00244    std::string Log4cplusLog::usage() const {
00245       std::string str;
00246       str += "\nLOG4CPLUS logging configuration, see http://log4cplus.sourceforge.net";
00247       str += "\n   -xmlBlaster/logging/configFileName [log4cplus.properties]";
00248       str += "\n                       Path to the log4cplus configuration file, for";
00249       str += "\n                       configuration see http://logging.apache.org/log4j/docs/manual.html";
00250       str += string("\n                       We provide an example file in xmlBlaster")+FILE_SEP+"config"+FILE_SEP+"log4cplus.properties";
00251       return str;
00252    }
00253 }}} // end of namespace
00254 
00255 #endif // XMLBLASTER_COMPILE_LOG4CPLUS_PLUGIN
00256 
00257