$search
00001 /* 00002 * Category.cpp 00003 * 00004 * Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved. 00005 * Copyright 2000, Bastiaan Bakker. All rights reserved. 00006 * 00007 * See the COPYING file for the terms of usage and distribution. 00008 */ 00009 00010 #include "PortabilityImpl.hh" 00011 00012 #ifdef LOG4CPP_HAVE_UNISTD_H 00013 # include <unistd.h> 00014 #endif 00015 00016 #include <log4cpp/Category.hh> 00017 #include <log4cpp/HierarchyMaintainer.hh> 00018 #include <log4cpp/NDC.hh> 00019 #include "StringUtil.hh" 00020 00021 namespace log4cpp { 00022 00023 Category& Category::getRoot() { 00024 return getInstance(""); 00025 } 00026 00027 void Category::setRootPriority(Priority::Value priority) { 00028 getRoot().setPriority(priority); 00029 } 00030 00031 Priority::Value Category::getRootPriority() throw() { 00032 return getRoot().getPriority(); 00033 } 00034 00035 Category& Category::getInstance(const std::string& name) { 00036 return HierarchyMaintainer::getDefaultMaintainer().getInstance(name); 00037 } 00038 00039 Category* Category::exists(const std::string& name) { 00040 return HierarchyMaintainer::getDefaultMaintainer().getExistingInstance(name); 00041 } 00042 00043 std::vector<Category*>* Category::getCurrentCategories() { 00044 return HierarchyMaintainer::getDefaultMaintainer(). 00045 getCurrentCategories(); 00046 } 00047 00048 void Category::shutdown() { 00049 HierarchyMaintainer::getDefaultMaintainer().shutdown(); 00050 } 00051 00052 Category::Category(const std::string& name, Category* parent, Priority::Value priority) : 00053 _name(name), 00054 _parent(parent), 00055 _priority(priority), 00056 _isAdditive(true) { 00057 } 00058 00059 Category::~Category() { 00060 removeAllAppenders(); 00061 } 00062 00063 const std::string& Category::getName() const throw() { 00064 return _name; 00065 } 00066 00067 Priority::Value Category::getPriority() const throw() { 00068 return _priority; 00069 } 00070 00071 void Category::setPriority(Priority::Value priority) 00072 throw(std::invalid_argument) { 00073 if ((priority < Priority::NOTSET) || (getParent() != NULL)) { 00074 _priority = priority; 00075 } else { 00076 /* caller tried to set NOTSET priority to root Category. 00077 Bad caller! 00078 */ 00079 throw std::invalid_argument("cannot set priority NOTSET on Root Category"); 00080 } 00081 } 00082 00083 Priority::Value Category::getChainedPriority() const throw() { 00084 // REQUIRE(rootCategory->getPriority() != Priority::NOTSET) 00085 00086 const Category* c = this; 00087 while(c->getPriority() >= Priority::NOTSET) { 00088 c = c->getParent(); 00089 } 00090 00091 return c->getPriority(); 00092 } 00093 00094 void Category::addAppender(Appender* appender) 00095 throw(std::invalid_argument) { 00096 if (appender) { 00097 threading::ScopedLock lock(_appenderSetMutex); 00098 { 00099 AppenderSet::iterator i = _appender.find(appender); 00100 if (_appender.end() == i) { 00101 // not found 00102 _appender.insert(appender); 00103 _ownsAppender[appender] = true; 00104 } 00105 } 00106 } else { 00107 throw std::invalid_argument("NULL appender"); 00108 } 00109 } 00110 00111 void Category::addAppender(Appender& appender) { 00112 threading::ScopedLock lock(_appenderSetMutex); 00113 { 00114 AppenderSet::iterator i = _appender.find(&appender); 00115 if (_appender.end() == i) { 00116 _appender.insert(&appender); 00117 _ownsAppender[&appender] = false; 00118 } 00119 } 00120 } 00121 00122 Appender* Category::getAppender() const { 00123 threading::ScopedLock lock(_appenderSetMutex); 00124 { 00125 AppenderSet::const_iterator i = _appender.begin(); 00126 return (_appender.end() == i) ? NULL : *i; 00127 } 00128 } 00129 00130 Appender* Category::getAppender(const std::string& name) const { 00131 threading::ScopedLock lock(_appenderSetMutex); 00132 { 00133 AppenderSet::const_iterator i = _appender.begin(); 00134 if (_appender.end() != i) { 00135 // found 00136 return((*i)->getAppender(name)); 00137 } 00138 else { 00139 return(NULL); 00140 } 00141 } 00142 } 00143 00144 AppenderSet Category::getAllAppenders() const { 00145 threading::ScopedLock lock(_appenderSetMutex); 00146 { 00147 return _appender; 00148 } 00149 } 00150 00151 void Category::removeAllAppenders() { 00152 threading::ScopedLock lock(_appenderSetMutex); 00153 { 00154 for (AppenderSet::iterator i = _appender.begin(); 00155 i != _appender.end(); i++) { 00156 // found 00157 OwnsAppenderMap::iterator i2; 00158 if (ownsAppender(*i, i2)) { 00159 delete (*i); 00160 } 00161 } 00162 00163 _ownsAppender.clear(); 00164 _appender.clear(); 00165 } 00166 } 00167 00168 void Category::removeAppender(Appender* appender) { 00169 threading::ScopedLock lock(_appenderSetMutex); 00170 { 00171 AppenderSet::iterator i = _appender.find(appender); 00172 if (_appender.end() != i) { 00173 OwnsAppenderMap::iterator i2; 00174 if (ownsAppender(*i, i2)) { 00175 _ownsAppender.erase(i2); 00176 delete (*i); 00177 } 00178 _appender.erase(i); 00179 } else { 00180 // appender not found 00181 } 00182 } 00183 } 00184 00185 bool Category::ownsAppender(Appender* appender) const throw() { 00186 bool owned = false; 00187 00188 threading::ScopedLock lock(_appenderSetMutex); 00189 { 00190 if (NULL != appender) { 00191 OwnsAppenderMap::const_iterator i = 00192 _ownsAppender.find(appender); 00193 if (_ownsAppender.end() != i) { 00194 owned = (*i).second; 00195 } 00196 } 00197 } 00198 00199 return owned; 00200 } 00201 00202 /* assume lock is held */ 00203 bool Category::ownsAppender(Appender* appender, 00204 Category::OwnsAppenderMap::iterator& i2) throw() { 00205 bool owned = false; 00206 00207 if (NULL != appender) { 00208 OwnsAppenderMap::iterator i = _ownsAppender.find(appender); 00209 if (_ownsAppender.end() != i) { 00210 owned = (*i).second; 00211 if (owned) { 00212 i2 = i; 00213 } 00214 } 00215 } 00216 00217 return owned; 00218 } 00219 00220 void Category::callAppenders(const LoggingEvent& event) throw() { 00221 threading::ScopedLock lock(_appenderSetMutex); 00222 { 00223 if (!_appender.empty()) { 00224 for(AppenderSet::const_iterator i = _appender.begin(); 00225 i != _appender.end(); i++) { 00226 (*i)->doAppend(event); 00227 } 00228 } 00229 } 00230 if (getAdditivity() && (getParent() != NULL)) { 00231 getParent()->callAppenders(event); 00232 } 00233 } 00234 00235 void Category::setAdditivity(bool additivity) { 00236 _isAdditive = additivity; 00237 } 00238 00239 bool Category::getAdditivity() const throw() { 00240 return _isAdditive; 00241 } 00242 00243 Category* Category::getParent() throw() { 00244 return _parent; 00245 } 00246 00247 const Category* Category::getParent() const throw() { 00248 return _parent; 00249 } 00250 00251 void Category::_logUnconditionally(Priority::Value priority, 00252 const char* format, 00253 va_list arguments) throw() { 00254 _logUnconditionally2(priority, StringUtil::vform(format, arguments)); 00255 } 00256 00257 void Category::_logUnconditionally2(Priority::Value priority, 00258 const std::string& message) throw() { 00259 LoggingEvent event(getName(), message, NDC::get(), priority); 00260 callAppenders(event); 00261 } 00262 00263 bool Category::isPriorityEnabled(Priority::Value priority) const throw() { 00264 return(getChainedPriority() >= priority); 00265 } 00266 00267 void Category::log(Priority::Value priority, 00268 const char* stringFormat, ...) throw() { 00269 if (isPriorityEnabled(priority)) { 00270 va_list va; 00271 va_start(va, stringFormat); 00272 _logUnconditionally(priority, stringFormat, va); 00273 va_end(va); 00274 } 00275 } 00276 00277 void Category::log(Priority::Value priority, 00278 const std::string& message) throw() { 00279 if (isPriorityEnabled(priority)) 00280 _logUnconditionally2(priority, message); 00281 } 00282 00283 void Category::logva(Priority::Value priority, 00284 const char* stringFormat, 00285 va_list va) throw() { 00286 if (isPriorityEnabled(priority)) { 00287 _logUnconditionally(priority, stringFormat, va); 00288 } 00289 } 00290 00291 void Category::debug(const char* stringFormat, ...) throw() { 00292 if (isPriorityEnabled(Priority::DEBUG)) { 00293 va_list va; 00294 va_start(va,stringFormat); 00295 _logUnconditionally(Priority::DEBUG, stringFormat, va); 00296 va_end(va); 00297 } 00298 } 00299 00300 void Category::debug(const std::string& message) throw() { 00301 if (isPriorityEnabled(Priority::DEBUG)) 00302 _logUnconditionally2(Priority::DEBUG, message); 00303 } 00304 00305 void Category::info(const char* stringFormat, ...) throw() { 00306 if (isPriorityEnabled(Priority::INFO)) { 00307 va_list va; 00308 va_start(va,stringFormat); 00309 _logUnconditionally(Priority::INFO, stringFormat, va); 00310 va_end(va); 00311 } 00312 } 00313 00314 void Category::info(const std::string& message) throw() { 00315 if (isPriorityEnabled(Priority::INFO)) 00316 _logUnconditionally2(Priority::INFO, message); 00317 } 00318 00319 void Category::notice(const char* stringFormat, ...) throw() { 00320 if (isPriorityEnabled(Priority::NOTICE)) { 00321 va_list va; 00322 va_start(va,stringFormat); 00323 _logUnconditionally(Priority::NOTICE, stringFormat, va); 00324 va_end(va); 00325 } 00326 } 00327 00328 void Category::notice(const std::string& message) throw() { 00329 if (isPriorityEnabled(Priority::NOTICE)) 00330 _logUnconditionally2(Priority::NOTICE, message); 00331 } 00332 00333 void Category::warn(const char* stringFormat, ...) throw() { 00334 if (isPriorityEnabled(Priority::WARN)) { 00335 va_list va; 00336 va_start(va,stringFormat); 00337 _logUnconditionally(Priority::WARN, stringFormat, va); 00338 va_end(va); 00339 } 00340 } 00341 00342 void Category::warn(const std::string& message) throw() { 00343 if (isPriorityEnabled(Priority::WARN)) 00344 _logUnconditionally2(Priority::WARN, message); 00345 } 00346 00347 void Category::error(const char* stringFormat, ...) throw() { 00348 if (isPriorityEnabled(Priority::ERROR)) { 00349 va_list va; 00350 va_start(va,stringFormat); 00351 _logUnconditionally(Priority::ERROR, stringFormat, va); 00352 va_end(va); 00353 } 00354 } 00355 00356 void Category::error(const std::string& message) throw() { 00357 if (isPriorityEnabled(Priority::ERROR)) 00358 _logUnconditionally2(Priority::ERROR, message); 00359 } 00360 00361 void Category::crit(const char* stringFormat, ...) throw() { 00362 if (isPriorityEnabled(Priority::CRIT)) { 00363 va_list va; 00364 va_start(va,stringFormat); 00365 _logUnconditionally(Priority::CRIT, stringFormat, va); 00366 va_end(va); 00367 } 00368 } 00369 00370 void Category::crit(const std::string& message) throw() { 00371 if (isPriorityEnabled(Priority::CRIT)) 00372 _logUnconditionally2(Priority::CRIT, message); 00373 } 00374 00375 void Category::alert(const char* stringFormat, ...) throw() { 00376 if (isPriorityEnabled(Priority::ALERT)) { 00377 va_list va; 00378 va_start(va,stringFormat); 00379 _logUnconditionally(Priority::ALERT, stringFormat, va); 00380 va_end(va); 00381 } 00382 } 00383 00384 void Category::alert(const std::string& message) throw() { 00385 if (isPriorityEnabled(Priority::ALERT)) 00386 _logUnconditionally2(Priority::ALERT, message); 00387 } 00388 00389 void Category::emerg(const char* stringFormat, ...) throw() { 00390 if (isPriorityEnabled(Priority::EMERG)) { 00391 va_list va; 00392 va_start(va,stringFormat); 00393 _logUnconditionally(Priority::EMERG, stringFormat, va); 00394 va_end(va); 00395 } 00396 } 00397 00398 void Category::emerg(const std::string& message) throw() { 00399 if (isPriorityEnabled(Priority::EMERG)) 00400 _logUnconditionally2(Priority::EMERG, message); 00401 } 00402 00403 void Category::fatal(const char* stringFormat, ...) throw() { 00404 if (isPriorityEnabled(Priority::FATAL)) { 00405 va_list va; 00406 va_start(va,stringFormat); 00407 _logUnconditionally(Priority::FATAL, stringFormat, va); 00408 va_end(va); 00409 } 00410 } 00411 00412 void Category::fatal(const std::string& message) throw() { 00413 if (isPriorityEnabled(Priority::FATAL)) 00414 _logUnconditionally2(Priority::FATAL, message); 00415 } 00416 00417 CategoryStream Category::getStream(Priority::Value priority) { 00418 return CategoryStream(*this, isPriorityEnabled(priority) ? 00419 priority : Priority::NOTSET); 00420 } 00421 00422 CategoryStream Category::operator<<(Priority::Value priority) { 00423 return getStream(priority); 00424 } 00425 } 00426