00001
00002
00003
00004
00005
00006
00007
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
00077
00078
00079 throw std::invalid_argument("cannot set priority NOTSET on Root Category");
00080 }
00081 }
00082
00083 Priority::Value Category::getChainedPriority() const throw() {
00084
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
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
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
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
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
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