00001
00002
00003 #ifndef __ARC_LOGGER__
00004 #define __ARC_LOGGER__
00005
00006 #include <string>
00007 #include <list>
00008 #include <map>
00009 #include <iostream>
00010 #include <fstream>
00011
00012 #include <arc/Thread.h>
00013 #include <arc/IString.h>
00014
00015 namespace Arc {
00016
00018
00031 enum LogLevel {
00032 DEBUG = 1,
00033 VERBOSE = 2,
00034 INFO = 4,
00035 WARNING = 8,
00036 ERROR = 16,
00037 FATAL = 32
00038 };
00039
00041
00049 enum LogFormat {
00050 LongFormat,
00051 ShortFormat,
00052 DebugFormat,
00053 EmptyFormat
00054 };
00055
00056 struct LoggerFormat {
00057 LoggerFormat(LogFormat format)
00058 : format(format) {};
00059 LogFormat format;
00060 };
00061
00062 std::ostream& operator<<(std::ostream& os, const LoggerFormat& format);
00063
00065
00068 std::ostream& operator<<(std::ostream& os, LogLevel level);
00070 LogLevel string_to_level(const std::string& str);
00072
00086 bool istring_to_level(const std::string& llStr, LogLevel& ll);
00088 bool string_to_level(const std::string& str, LogLevel& ll);
00090 std::string level_to_string(const LogLevel& level);
00092 LogLevel old_level_to_level(unsigned int old_level);
00093
00094
00095
00097
00101 class LogMessage {
00102 public:
00103
00105
00113 LogMessage(LogLevel level,
00114 const IString& message);
00115
00117
00125 LogMessage(LogLevel level,
00126 const IString& message,
00127 const std::string& identifier);
00128
00130
00133 LogLevel getLevel() const;
00134
00135 protected:
00136
00138
00142 void setIdentifier(std::string identifier);
00143
00144 private:
00145
00147
00152 static std::string getDefaultIdentifier();
00153
00155
00159 void setDomain(std::string domain);
00160
00162 std::string time;
00163
00165 LogLevel level;
00166
00168 std::string domain;
00169
00171 std::string identifier;
00172
00174 IString message;
00175
00177
00180 friend std::ostream& operator<<(std::ostream& os,
00181 const LogMessage& message);
00182
00184
00187 friend class Logger;
00188
00189 };
00190
00191
00192
00194
00198 class LogDestination {
00199 public:
00200
00202 virtual void log(const LogMessage& message) = 0;
00203
00204 virtual ~LogDestination() {}
00205
00206 void setFormat(const LogFormat& newformat);
00207
00208 protected:
00209
00211
00213 LogDestination();
00214
00216
00218 LogDestination(const std::string& locale);
00219
00220 private:
00221
00223
00226 LogDestination(const LogDestination& unique);
00227
00229
00232 void operator=(const LogDestination& unique);
00233
00234 protected:
00235
00236 std::string locale;
00237 LogFormat format;
00238 };
00239
00240
00241
00243
00251 class LogStream
00252 : public LogDestination {
00253 public:
00254
00256
00261 LogStream(std::ostream& destination);
00262
00264
00267 LogStream(std::ostream& destination, const std::string& locale);
00268
00270
00275 virtual void log(const LogMessage& message);
00276
00277 private:
00278
00280
00283 LogStream(const LogStream& unique);
00284
00286
00289 void operator=(const LogStream& unique);
00290
00292
00295 std::ostream& destination;
00296
00298
00303 Glib::Mutex mutex;
00304
00305 };
00306
00308
00318 class LogFile
00319 : public LogDestination {
00320 public:
00321
00323
00329 LogFile(const std::string& path);
00330
00332
00336 LogFile(const std::string& path, const std::string& locale);
00337
00339
00344 void setMaxSize(int newsize);
00345
00347
00353 void setBackups(int newbackup);
00354
00355
00356
00358
00362 void setReopen(bool newreopen);
00363
00365 operator bool(void);
00366
00368 bool operator!(void);
00369
00371
00377 virtual void log(const LogMessage& message);
00378 private:
00379 LogFile(void);
00380 LogFile(const LogFile& unique);
00381 void operator=(const LogFile& unique);
00382 void backup(void);
00383 std::string path;
00384 std::ofstream destination;
00385 int maxsize;
00386 int backups;
00387 bool reopen;
00388 Glib::Mutex mutex;
00389 };
00390
00391 class LoggerContextRef;
00392
00394 class LoggerContext {
00395 friend class Logger;
00396 friend class LoggerContextRef;
00397 private:
00399 int usage_count;
00400
00402 Glib::Mutex mutex;
00403
00405 std::list<LogDestination*> destinations;
00406
00408 LogLevel threshold;
00409
00410 LoggerContext(LogLevel thr):usage_count(0),threshold(thr) { };
00411
00412 LoggerContext(const LoggerContext& ctx):
00413 usage_count(0),destinations(ctx.destinations),threshold(ctx.threshold) { };
00414
00415 ~LoggerContext(void);
00416
00417 void Acquire(void);
00418
00419 void Release(void);
00420 };
00421
00422
00424
00440 class Logger {
00441 public:
00442
00444
00447
00448 static Logger& getRootLogger();
00449
00451
00456 Logger(Logger& parent,
00457 const std::string& subdomain);
00458
00460
00465 Logger(Logger& parent,
00466 const std::string& subdomain,
00467 LogLevel threshold);
00468
00470
00472 ~Logger();
00473
00475
00482 void addDestination(LogDestination& destination);
00483
00485
00487 void addDestinations(const std::list<LogDestination*>& destinations);
00488
00490
00494 const std::list<LogDestination*>& getDestinations(void) const;
00495
00497 void removeDestinations(void);
00498
00500 void deleteDestinations(void);
00501
00503
00508 void setThreshold(LogLevel threshold);
00509
00511
00518 static void setThresholdForDomain(LogLevel threshold,
00519 const std::list<std::string>& subdomains);
00520
00522
00529 static void setThresholdForDomain(LogLevel threshold,
00530 const std::string& domain);
00531
00533
00536 LogLevel getThreshold() const;
00537
00539
00548 void setThreadContext(void);
00549
00551
00554 void msg(LogMessage message);
00555
00557
00563 void msg(LogLevel level, const std::string& str) {
00564 msg(LogMessage(level, IString(str)));
00565 }
00566
00567 template<class T0>
00568 void msg(LogLevel level, const std::string& str,
00569 const T0& t0) {
00570 msg(LogMessage(level, IString(str, t0)));
00571 }
00572
00573 template<class T0, class T1>
00574 void msg(LogLevel level, const std::string& str,
00575 const T0& t0, const T1& t1) {
00576 msg(LogMessage(level, IString(str, t0, t1)));
00577 }
00578
00579 template<class T0, class T1, class T2>
00580 void msg(LogLevel level, const std::string& str,
00581 const T0& t0, const T1& t1, const T2& t2) {
00582 msg(LogMessage(level, IString(str, t0, t1, t2)));
00583 }
00584
00585 template<class T0, class T1, class T2, class T3>
00586 void msg(LogLevel level, const std::string& str,
00587 const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
00588 msg(LogMessage(level, IString(str, t0, t1, t2, t3)));
00589 }
00590
00591 template<class T0, class T1, class T2, class T3, class T4>
00592 void msg(LogLevel level, const std::string& str,
00593 const T0& t0, const T1& t1, const T2& t2, const T3& t3,
00594 const T4& t4) {
00595 msg(LogMessage(level, IString(str, t0, t1, t2, t3, t4)));
00596 }
00597
00598 template<class T0, class T1, class T2, class T3, class T4,
00599 class T5>
00600 void msg(LogLevel level, const std::string& str,
00601 const T0& t0, const T1& t1, const T2& t2, const T3& t3,
00602 const T4& t4, const T5& t5) {
00603 msg(LogMessage(level, IString(str, t0, t1, t2, t3, t4, t5)));
00604 }
00605
00606 template<class T0, class T1, class T2, class T3, class T4,
00607 class T5, class T6>
00608 void msg(LogLevel level, const std::string& str,
00609 const T0& t0, const T1& t1, const T2& t2, const T3& t3,
00610 const T4& t4, const T5& t5, const T6& t6) {
00611 msg(LogMessage(level, IString(str, t0, t1, t2, t3, t4, t5, t6)));
00612 }
00613
00614 template<class T0, class T1, class T2, class T3, class T4,
00615 class T5, class T6, class T7>
00616 void msg(LogLevel level, const std::string& str,
00617 const T0& t0, const T1& t1, const T2& t2, const T3& t3,
00618 const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
00619 msg(LogMessage(level, IString(str, t0, t1, t2, t3, t4, t5, t6, t7)));
00620 }
00621
00622 private:
00623
00625
00630 Logger();
00631
00633
00636 Logger(const Logger& unique);
00637
00639
00642 void operator=(const Logger& unique);
00643
00645
00649 std::string getDomain();
00650
00652
00658 void log(const LogMessage& message);
00659
00661 Logger *parent;
00662
00664 std::string domain;
00665
00667 std::string context_id;
00668
00669 LoggerContext context;
00670
00671 LoggerContext& getContext(void);
00672
00673 Glib::Mutex mutex;
00674
00675 #define rootLoggerMagic (0xF6569201)
00676 static Logger *rootLogger;
00677 static std::map<std::string,LogLevel>* defaultThresholds;
00678 static unsigned int rootLoggerMark;
00679 };
00680
00681 }
00682
00683 #define rootLogger getRootLogger()
00684
00685 #define LOG(LGR, THR, FSTR, ...) { if ((LGR).getThreshold() >= (THR)(LGR).msg((THR), (FSTR), ...); }
00686
00687 #endif // __ARC_LOGGER__