00001 #ifndef Logger_HH
00002 #define Logger_HH
00003
00004 #include <syslog.h>
00005 #include <pthread.h>
00006
00007 #include <sstream>
00008 #include <string>
00009
00010 #include <map>
00011 #include <vector>
00012
00013
00014
00015
00016 #ifdef _GNU_SOURCE
00017 #define dpm_strerror_r(errnum, buf, buflen) \
00018 if (buflen > 0) { \
00019 int old_errno = errno, cur_errno = errnum; \
00020 char buffer[128], *msg = NULL; \
00021 errno = 0; \
00022 buf[0] = '\0'; \
00023 msg = strerror_r(cur_errno, buffer, sizeof(buffer)); \
00024 if (msg) \
00025 strncpy(buf, msg, buflen); \
00026 else \
00027 snprintf(buf, buflen, "Unknown error %d", errnum); \
00028 buf[buflen-1] = '\0'; \
00029 errno = old_errno; \
00030 }
00031 #else
00032 #define dpm_strerror_r(errnum, buf, buflen) \
00033 if (buflen > 0) { \
00034 int old_errno = errno, cur_errno = errnum, rc; \
00035 errno = 0; \
00036 rc = strerror_r(cur_errno, buf, buflen); \
00037 switch (rc) { \
00038 case 0: \
00039 case ERANGE: \
00040 break; \
00041 case EINVAL: \
00042 snprintf(buf, buflen, "Unknown error %d", errnum); \
00043 buf[buflen-1] = '\0'; \
00044 break; \
00045 } \
00046 errno = old_errno; \
00047 }
00048 #endif
00049
00050
00051 #define SSTR(message) static_cast<std::ostringstream&>(std::ostringstream().flush() << message).str()
00052
00053 #define Log(lvl, mymask, where, what) \
00054 do{ \
00055 if (Logger::get()->getLevel() >= lvl && Logger::get()->isLogged(mymask)) \
00056 { \
00057 std::ostringstream outs; \
00058 outs << "{" << pthread_self() << "}" << "[" << lvl << "] dmlite " << where << " " << __func__ << " : " << what; \
00059 Logger::get()->log((Logger::Level)lvl, outs.str()); \
00060 } \
00061 }while(0) \
00062
00063
00064 #define Err(where, what) \
00065 do{ \
00066 std::ostringstream outs; \
00067 outs << "{" << pthread_self() << "}" << "!!! dmlite " << where << " " << __func__ << " : " << what; \
00068 Logger::get()->log((Logger::Level)0, outs.str()); \
00069 }while(0)
00070
00071
00072
00073
00074 class Logger
00075 {
00076
00077 public:
00078
00079 typedef unsigned long long bitmask;
00080
00081 typedef std::string component;
00082
00083 static bitmask unregistered;
00084 static char *unregisteredname;
00085
00086
00087
00088 enum Level
00089 {
00090 Lvl0,
00091 Lvl1,
00092 Lvl2,
00093 Lvl3,
00094 Lvl4,
00095 Lvl5
00096 };
00097
00098
00099 ~Logger();
00100
00101 static Logger *instance;
00102
00103
00104 static Logger *get()
00105 {
00106 if (instance == 0)
00107 instance = new Logger();
00108 return instance;
00109 }
00110
00111 static void set(Logger *inst) {
00112 Logger *old = instance;
00113 instance = inst;
00114 if (old) delete old;
00115 }
00116
00117 short getLevel() const
00118 {
00119 return level;
00120 }
00121
00122
00123 void setLevel(Level lvl)
00124 {
00125 level = lvl;
00126 }
00127
00128
00129 bool isLogged(bitmask m) const
00130 {
00131 if (mask == 0) return mask & unregistered;
00132 return mask & m;
00133 }
00134
00135
00136 void registerComponent(component const & comp);
00137
00138
00139 void registerComponents(std::vector<component> const & components);
00140
00141
00142
00143
00144 void setLogged(component const &comp, bool tobelogged);
00145
00146
00147
00148
00149
00150
00151
00152
00153 void log(Level lvl, std::string const & msg) const;
00154
00155
00156
00157
00158
00159 void logAll()
00160 {
00161 mask = ~0;
00162 }
00163
00164
00165
00166
00167
00168
00169 bitmask getMask(component const & comp);
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 static int getStackTrace(std::string &s);
00180
00181 private:
00182
00183
00184 Logger();
00185
00186 Logger(Logger const &);
00187
00188 Logger & operator=(Logger const &);
00189
00190
00191 short level;
00192
00193 int size;
00194
00195 bitmask mask;
00196
00197 std::map<component, bitmask> mapping;
00198
00199
00200
00201 };
00202
00203
00204
00205 void LogCfgParm(int lvl, Logger::bitmask mymask, std::string where, std::string key, std::string value);
00206
00207
00208
00209
00210 #endif