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