1 /*----------------------------------------------------------------------------
  2 Name:      Log4cplus.cpp
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Embed logging library log4cpp http://log4cplus.sourceforge.net/
  6 ----------------------------------------------------------------------------*/
  7 
  8 #if XMLBLASTER_COMPILE_LOG4CPLUS_PLUGIN==1
  9 
 10 #include <util/Log4cplus.h>
 11 #include <log4cplus/logger.h>
 12 #include <log4cplus/configurator.h>
 13 #include <log4cplus/helpers/property.h>
 14 #include <log4cplus/helpers/loglog.h>
 15 #include <fstream>
 16 #include <util/PropertyDef.h>
 17 #include <util/lexical_cast.h>
 18 
 19 using namespace std;
 20 using namespace log4cplus;
 21 
 22 namespace org { namespace xmlBlaster {
 23 namespace util {
 24 
 25    Log4cplusFactory::Log4cplusFactory()
 26    {  
 27    }
 28 
 29    /**
 30     * Enforced by I_LogFactory, initialize the logging environment
 31     * If your code does logging initialization already you can switch this initialization off
 32     * by adding a property "xmlBlaster/logging/initialize=false" to propMap.
 33     */
 34    void Log4cplusFactory::initialize(const PropMap& propMap)
 35    {
 36       {
 37          PropMap::const_iterator pos = propMap.find("xmlBlaster/logging/debug");
 38          if (pos != propMap.end()) {
 39             log4cplus::helpers::LogLog::getLogLog()->setInternalDebugging(lexical_cast<bool>(pos->second));
 40          }
 41       }
 42 
 43       bool initialize = true;
 44       PropMap::const_iterator pos = propMap.find("xmlBlaster/logging/initialize");
 45       if (pos != propMap.end())
 46          if ("false" == pos->second)
 47             initialize = false;
 48 
 49 
 50       if (initialize) {
 51          // Find the configuration file name
 52          const char *envName = "xmlBlaster/logging/configFileName";
 53          string configFileName = "log4cplus.properties"; // local directory
 54          pos = propMap.find(envName);
 55          if (pos != propMap.end()) {
 56             configFileName = (*pos).second;
 57          }
 58          else {
 59             const char* envValue = getenv(envName);
 60             if (envValue != 0) {
 61                configFileName = envValue;
 62             }
 63             else {
 64                std::ifstream file;
 65                file.open(configFileName.c_str());  // local directory?
 66                if(!file) {
 67                   pos = propMap.find("user.home");
 68                   if (pos != propMap.end()) {
 69                      string tmp = (*pos).second + FILE_SEP + configFileName;
 70                      std::ifstream file2;
 71                      file2.open(tmp.c_str());
 72                      if(!file2) {
 73                      }
 74                      else {
 75                         configFileName = tmp;
 76                      }
 77                   }
 78                }
 79             }
 80          }
 81 
 82          bool inheritEnvironment = true;
 83 
 84          std::ifstream file;
 85          file.open(configFileName.c_str());
 86          if(!file) {
 87             // No configuration file
 88             if (inheritEnvironment) {
 89                // We pass all xmlBlaster.properties + command line settings to log4cplus
 90                log4cplus::helpers::Properties props;
 91                PropMap::const_iterator iter = propMap.begin();
 92                while (iter != propMap.end()) {
 93                     props.setProperty((*iter).first, (*iter).second);
 94                   iter++;
 95                }
 96                PropertyConfigurator tmp(props, Logger::getDefaultHierarchy());
 97                tmp.configure();
 98             }
 99             else {
100                BasicConfigurator config;
101                config.configure();
102             }
103             Logger logger = Logger::getInstance("org.xmlBlaster");
104             LOG4CPLUS_WARN(logger, "Couldn't find file logging configuration file \"-xmlBlaster/logging/configFileName " + configFileName + "\", you can use the example in xmlBlaster" +
105                                     FILE_SEP + "config" + FILE_SEP + configFileName);
106             LOG4CPLUS_INFO(logger, "We continue with default logging configuration.");
107          }
108          else {
109             // Scan configuration file
110             if (inheritEnvironment) {
111                // Log4Cplus can replace env variables in its config file
112                // there for we pass all settings from xmlBlaster.properties to log4cplus
113                log4cplus::helpers::Properties props(configFileName);
114                PropMap::const_iterator iter = propMap.begin();
115                while (iter != propMap.end()) {
116                     props.setProperty((*iter).first, (*iter).second);
117                   iter++;
118                }
119                PropertyConfigurator tmp(props, Logger::getDefaultHierarchy());
120                tmp.configure();
121             }
122             else {
123                PropertyConfigurator::doConfigure(configFileName);
124             }
125 
126             Logger logger = Logger::getInstance("org.xmlBlaster");
127             LOG4CPLUS_INFO(logger, "Configured log4cplus with configuration file xmlBlaster/logging/configFileName=" + configFileName);
128          }
129       }
130       else {
131          Logger logger = Logger::getInstance("org.xmlBlaster");
132          LOG4CPLUS_INFO(logger, "Log4cplus is configured already (xmlBlaster/logging/initialize=false), no reconfiguration done.");
133       }
134 
135       //Logger logger = Logger::getInstance("org.xmlBlaster");
136       //LOG4CPLUS_WARN(logger, "LOG4CPLUS: Hello, World!");
137    }
138 
139    /**
140     * Enforced by I_LogFactory
141     */
142    Log4cplusFactory::~Log4cplusFactory()
143    {
144       LogMap::reverse_iterator i;
145       for(i = logMap_.rbegin(); i != logMap_.rend(); ++i) {
146          I_Log* log = (*i).second;
147          delete log;
148       }
149       logMap_.clear();
150 
151       //Logger::getDefaultHierarchy().shutdown();
152       Logger::shutdown();
153    }
154 
155    /**
156     * Enforced by I_LogFactory
157     */
158    I_Log& Log4cplusFactory::getLog(const string& logName)
159    {
160       LogMap::iterator pos = logMap_.find(logName);
161       if (pos != logMap_.end()) return *((*pos).second);
162       
163       Log4cplusLog *help = new Log4cplusLog(logName);
164       logMap_.insert(LogMap::value_type(logName, help));
165       pos = logMap_.find(logName);
166       if (pos != logMap_.end()) {
167          I_Log* log = (*pos).second;
168          return *log;
169       }
170 
171       std::cerr << "LogManager.cpp getLog(" << logName << ") is not implemented -> throwing exception" << std::endl;
172       throw bad_exception();
173    }
174    
175    /**
176     * Enforced by I_LogFactory
177     */
178    void Log4cplusFactory::releaseLog(const string& name)
179    {
180       std::cerr << "Log4cplus.cpp releaseLog(" << name << ") is not implemented" << std::endl;
181    }
182 
183 //================== Log4cplusLog implementation ======================
184 
185    Log4cplusLog::Log4cplusLog(std::string logName) : logName_(logName), logger_(Logger::getInstance(logName)) {
186       //Should we set this if basic configured??:
187       //logger.setLogLevel(INFO_LOG_LEVEL);
188       call_ = dump_ = time_ = logger_.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL);
189       trace_ = logger_.isEnabledFor(log4cplus::TRACE_LOG_LEVEL);
190       info_ = logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL);
191    }
192 
193    void Log4cplusLog::info(const std::string &instance, const std::string &text){
194       //std::cout << "[INFO]  " << instance << ": " << text << std::endl;
195       if (logger_.isEnabledFor(log4cplus::INFO_LOG_LEVEL)) {
196          log4cplus::tostringstream _log4cplus_buf;
197          _log4cplus_buf << text;
198          logger_.forcedLog(log4cplus::INFO_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
199       }
200       //LOG4CPLUS_INFO(logger_, text);
201    }
202    
203    void Log4cplusLog::warn(const std::string &instance, const std::string &text){
204       if (logger_.isEnabledFor(log4cplus::WARN_LOG_LEVEL)) {
205          log4cplus::tostringstream _log4cplus_buf;
206          _log4cplus_buf << text;
207          logger_.forcedLog(log4cplus::WARN_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
208       }
209    }
210    
211    void Log4cplusLog::error(const std::string &instance, const std::string &text){
212       if (logger_.isEnabledFor(log4cplus::ERROR_LOG_LEVEL)) {
213          log4cplus::tostringstream _log4cplus_buf;
214          _log4cplus_buf << text;
215          logger_.forcedLog(log4cplus::ERROR_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
216       }
217    }
218 
219    void Log4cplusLog::panic(const std::string &instance, const std::string &text){
220       if (logger_.isEnabledFor(log4cplus::FATAL_LOG_LEVEL)) {
221          log4cplus::tostringstream _log4cplus_buf;
222          _log4cplus_buf << text;
223          logger_.forcedLog(log4cplus::FATAL_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
224       }
225       ::exit(1);
226    }
227    
228    void Log4cplusLog::trace(const std::string &instance, const std::string &text){
229       if (logger_.isEnabledFor(log4cplus::TRACE_LOG_LEVEL)) {
230          log4cplus::tostringstream _log4cplus_buf;
231          _log4cplus_buf << text;
232          logger_.forcedLog(log4cplus::TRACE_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
233       }
234    }
235    
236    void Log4cplusLog::call(const std::string &instance, const std::string &text){
237       if (logger_.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) {
238          log4cplus::tostringstream _log4cplus_buf;
239          _log4cplus_buf << text;
240          logger_.forcedLog(log4cplus::DEBUG_LOG_LEVEL, _log4cplus_buf.str(), instance.c_str(), -1);
241       }
242    }
243 
244    std::string Log4cplusLog::usage() const {
245       std::string str;
246       str += "\nLOG4CPLUS logging configuration, see http://log4cplus.sourceforge.net";
247       str += "\n   -xmlBlaster/logging/configFileName [log4cplus.properties]";
248       str += "\n                       Path to the log4cplus configuration file, for";
249       str += "\n                       configuration see http://logging.apache.org/log4j/docs/manual.html";
250       str += string("\n                       We provide an example file in xmlBlaster")+FILE_SEP+"config"+FILE_SEP+"log4cplus.properties";
251       return str;
252    }
253 }}} // end of namespace
254 
255 #endif // XMLBLASTER_COMPILE_LOG4CPLUS_PLUGIN


syntax highlighted by Code2HTML, v. 0.9.1