00001 // OSB library ************************************************ -*- C++ -*- 00009 /* 00010 AUTHOR(S): Stephan Broennimann (vb) 00011 00012 RCS information 00013 $Name: OSB_060808 $ 00014 $Revision: 1.20 $ 00015 00016 License 00017 OSB rating and billing library for communication networks 00018 Copyright (C) 2004, 2005, 2006 OSB systems 00019 00020 This file may be distributed and/or modify under the terms of the 00021 GNU General Public License (GPL) as published by the Free Software 00022 Foundation which is provided in the file LICENSE.GPL included in the 00023 packaging of this file. 00024 00025 The file is distributed in the hope that it will be useful, but WITHOUT 00026 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00027 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00028 for more details. 00029 00030 Holders of a OSB Commercial License may use this file under the terms 00031 and conditions of this commercial license. 00032 */ 00033 #ifndef _OSBLOG_H_ 00034 #define _OSBLOG_H_ 00035 00036 // ************************************************************************ 00037 // included header files 00038 // + standard includes 00039 #include <ostream> 00040 #include <memory> 00041 00042 // + libraries 00043 00044 // + local headers 00045 00046 // + class declarations 00047 00048 // ************************************************************************ 00049 // namespace extensions 00050 namespace OSB_LIB { 00051 00052 // ************************************************************************ 00053 // forward declarations 00054 00055 // ************************************************************************ 00056 // type definitions 00057 00058 // ************************************************************************ 00059 // class definitions 00099 class LogBase { 00100 public: 00102 struct HeadFiller { 00104 char filler_; 00105 }; 00106 public: 00108 explicit LogBase(int logLevel); 00110 virtual ~LogBase(); 00111 00112 public: 00118 00119 inline LogBase& fatal(); 00121 inline LogBase& error(); 00123 inline LogBase& warn(); 00125 inline LogBase& info(); 00126 00128 inline LogBase& raw(int level); 00129 00139 inline LogBase& debug(int level); 00141 00142 public: 00149 virtual void elog() = 0; 00150 00157 virtual void endlog() = 0; 00158 00166 virtual LogBase& nl() = 0; 00174 virtual LogBase& head(char filler) = 0; 00175 00176 public: 00178 00179 00180 inline void operator<<( 00181 void (*func)(LogBase&) 00182 ); 00184 inline LogBase& operator<<( 00185 LogBase& (*func)(LogBase&) 00186 ); 00188 inline LogBase& operator<<( 00189 const HeadFiller& filler 00190 ); 00192 00194 template<typename T> 00195 inline LogBase& operator<<(const T& t); 00196 00198 00199 inline LogBase& operator<<( 00200 std::ostream& (*func)(std::ostream&) 00201 ); 00202 inline LogBase& operator<<( 00203 std::ios& (*func)(std::ios&) 00204 ); 00205 inline LogBase& operator<<( 00206 std::ios_base& (*func)(std::ios_base&) 00207 ); 00209 00210 public: 00212 00213 00219 virtual int logLevel() const; 00226 virtual bool verbose() const; 00235 virtual void setLevel(int logLevel); 00242 virtual void setVerbose(bool on); 00244 00245 protected: 00260 virtual LogBase& start(int level, bool noHead = false) = 0; 00261 00263 virtual std::ostream& plog() = 0; 00265 virtual std::ostream* slog() = 0; 00266 00276 inline bool mustLog() const; 00277 00278 protected: 00285 int logLevel_; 00287 int curLevel_; 00289 bool verbose_; 00291 bool noHead_; 00293 bool useIndent_; 00295 std::string indent_; 00296 }; // class LogBase 00297 00304 class Log { 00305 public: 00307 00308 00309 inline static LogBase& fatal(); 00311 inline static LogBase& error(); 00313 inline static LogBase& warn(); 00315 inline static LogBase& info(); 00316 00327 inline static LogBase& raw(int level = 4); 00328 00349 inline static LogBase& cont(); 00355 inline static void endlog(); 00357 inline static void empty(int level, int lines = 1); 00363 inline static LogBase& debug(int level = 1); 00364 00366 inline static LogBase& nl(LogBase& log); 00368 inline static void elog(LogBase& log); 00370 inline static void endlog(LogBase& log); 00381 inline static const LogBase::HeadFiller head(char filler = ' '); 00383 00384 public: 00386 00387 00395 static LogBase* setInstance(LogBase* instance); 00404 static LogBase* setInstance( 00405 std::auto_ptr<LogBase> instance 00406 ); 00408 inline static int logLevel(); 00410 inline static bool verbose(); 00416 inline static void setLevel(int logLevel); 00418 inline static void setVerbose(bool on); 00420 private: 00422 Log(); 00423 private: 00429 static LogBase& instance(); 00430 private: 00432 static LogBase* instance_; 00434 static bool ownsInstance_; 00435 }; // class Log 00436 00440 class ConsoleLog : public LogBase { 00441 public: 00443 explicit ConsoleLog(int logLevel); 00444 00445 public: 00451 LogBase& nl(); 00457 virtual void elog(); 00463 virtual void endlog(); 00465 LogBase& head(char); 00466 00467 protected: 00477 virtual LogBase& start(int level, bool noHead); 00478 00479 private: 00485 LogBase& init(const char* what); 00486 00493 std::ostream& plog(); 00495 std::ostream* slog(); 00496 00497 private: 00499 bool useCerr_; 00500 }; // class ConsoleLog 00501 } // namespace OSB_LIB 00502 00503 // ************************************************************************ 00504 // inline definitions 00505 namespace OSB_LIB { 00506 // ******************************************************************** 00507 // class Log 00508 LogBase& Log::fatal() 00509 { 00510 return instance().fatal(); 00511 } 00512 00513 LogBase& Log::error() 00514 { 00515 return instance().error(); 00516 } 00517 00518 LogBase& Log::warn() 00519 { 00520 return instance().warn(); 00521 } 00522 00523 LogBase& Log::info() 00524 { 00525 return instance().info(); 00526 } 00527 00528 LogBase& Log::raw(int level) 00529 { 00530 return instance().raw(level); 00531 } 00532 00533 LogBase& Log::debug(int level) 00534 { 00535 return instance().debug(level); 00536 } 00537 00538 LogBase& Log::cont() 00539 { 00540 return instance(); 00541 } 00542 00543 void Log::endlog() 00544 { 00545 instance().endlog(); 00546 } 00547 00548 void Log::empty(int level, int lines) 00549 { 00550 if (1 > lines) return; 00551 00552 raw(level); 00553 for (int i = 0; i < lines; ++i) cont() << "\n"; 00554 endlog(); 00555 } 00556 00557 LogBase& Log::nl(LogBase& log) 00558 { 00559 return log.nl(); 00560 } 00561 00562 void Log::elog(LogBase& log) 00563 { 00564 log.elog(); 00565 } 00566 00567 void Log::endlog(LogBase& log) 00568 { 00569 log.endlog(); 00570 } 00571 00572 const LogBase::HeadFiller Log::head(char filler) 00573 { 00574 LogBase::HeadFiller rc; 00575 rc.filler_ = filler; 00576 return rc; 00577 } 00578 00579 int Log::logLevel() 00580 { 00581 return instance().logLevel(); 00582 } 00583 00584 void Log::setLevel(int logLevel) 00585 { 00586 return instance().setLevel(logLevel); 00587 } 00588 00589 bool Log::verbose() 00590 { 00591 return instance().verbose(); 00592 } 00593 00594 void Log::setVerbose(bool on) 00595 { 00596 return instance().setVerbose(on); 00597 } 00598 00599 // ******************************************************************** 00600 // class LogBase 00601 LogBase& LogBase::fatal() 00602 { 00603 return start(1); 00604 } 00605 00606 LogBase& LogBase::error() 00607 { 00608 return start(2); 00609 } 00610 00611 LogBase& LogBase::warn() 00612 { 00613 return start(3); 00614 } 00615 00616 LogBase& LogBase::info() 00617 { 00618 return start(4); 00619 } 00620 00621 LogBase& LogBase::raw(int level) 00622 { 00623 return start(level, true); 00624 } 00625 00626 LogBase& LogBase::debug(int level) 00627 { 00628 return start(level+4); 00629 } 00630 00631 bool LogBase::mustLog() const 00632 { 00633 if (-1 == logLevel_) return true; 00634 if (curLevel_ > logLevel_) return false; 00635 return true; 00636 } 00637 00638 void LogBase::operator<<( 00639 void (*func)(LogBase&) 00640 ) 00641 { 00642 func(*this); 00643 } 00644 00645 LogBase& LogBase::operator<<( 00646 LogBase& (*func)(LogBase&) 00647 ) 00648 { 00649 return func(*this); 00650 } 00651 00652 LogBase& LogBase::operator<<( 00653 const HeadFiller& filler 00654 ) 00655 { 00656 return this->head(filler.filler_); 00657 } 00658 00659 template<typename T> 00660 LogBase& LogBase::operator<<(const T& t) 00661 { 00662 if (useIndent_) { 00663 useIndent_ = false; 00664 *this << indent_; 00665 } 00666 00667 if (!mustLog()) return *this; 00668 00669 plog() << t; 00670 if (verbose_) { 00671 std::ostream* s = slog(); 00672 if (s) *s << t; 00673 } 00674 return *this; 00675 } 00676 00677 LogBase& LogBase::operator<<( 00678 std::ostream& (*func)(std::ostream&) 00679 ) 00680 { 00681 if (!mustLog()) return *this; 00682 00683 plog() << func; 00684 if (verbose_) { 00685 std::ostream* s = slog(); 00686 if (s) *s << func; 00687 } 00688 return *this; 00689 } 00690 00691 LogBase& LogBase::operator<<( 00692 std::ios& (*func)(std::ios&) 00693 ) 00694 { 00695 if (!mustLog()) return *this; 00696 00697 plog() << func; 00698 if (verbose_) { 00699 std::ostream* s = slog(); 00700 if (s) *s << func; 00701 } 00702 return *this; 00703 } 00704 00705 LogBase& LogBase::operator<<( 00706 std::ios_base& (*func)(std::ios_base&) 00707 ) 00708 { 00709 if (!mustLog()) return *this; 00710 00711 plog() << func; 00712 if (verbose_) { 00713 std::ostream* s = slog(); 00714 if (s) *s << func; 00715 } 00716 return *this; 00717 } 00718 } // namespace OSB_LIB 00719 #endif // #ifndef _OSBLOG_H_