00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef __DIAGS_H___
00036 #define __DIAGS_H___
00037
00038 #include <stdarg.h>
00039 #include "ink_error.h"
00040 #include "ink_mutex.h"
00041 #include "Regex.h"
00042 #include "ink_apidefs.h"
00043
00044 #define DIAGS_MAGIC 0x12345678
00045
00046 class Diags;
00047
00048
00049 typedef enum
00050 {
00051 DiagsTagType_Debug = 0,
00052 DiagsTagType_Action = 1
00053 } DiagsTagType;
00054
00055 struct DiagsModeOutput
00056 {
00057 bool to_stdout;
00058 bool to_stderr;
00059 bool to_syslog;
00060 bool to_diagslog;
00061 };
00062
00063 typedef enum
00064 {
00065 DL_Diag = 0,
00066 DL_Debug,
00067 DL_Status,
00068 DL_Note,
00069 DL_Warning,
00070 DL_Error,
00071 DL_Fatal,
00072 DL_Alert,
00073 DL_Emergency,
00074 DL_Undefined
00075 } DiagsLevel;
00076
00077 #define DiagsLevel_Count DL_Undefined
00078
00079 #define DiagsLevel_IsTerminal(_l) (((_l) >= DL_Fatal) && ((_l) < DL_Undefined))
00080
00081
00082
00083 typedef void (*DiagsCleanupFunc) ();
00084
00085 struct DiagsConfigState
00086 {
00087
00088 static bool enabled[2];
00089 DiagsModeOutput outputs[DiagsLevel_Count];
00090 };
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #define DiagsMakeLocation() SrcLoc(__FILE__, __FUNCTION__, __LINE__)
00104
00105 class SrcLoc
00106 {
00107 public:
00108 const char *file;
00109 const char *func;
00110 const int line;
00111
00112 bool valid() const {
00113 return file && line;
00114 }
00115
00116 SrcLoc(const char *_file, const char *_func, int _line)
00117 : file(_file), func(_func), line(_line) {
00118 }
00119
00120 char * str(char *buf, int buflen) const;
00121 };
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 class Diags
00140 {
00141 public:
00142 Diags(const char *base_debug_tags, const char *base_action_tags, FILE * _diags_log_fp = NULL);
00143 ~Diags();
00144
00145 FILE *diags_log_fp;
00146 const unsigned int magic;
00147 volatile DiagsConfigState config;
00148 int show_location;
00149 DiagsCleanupFunc cleanup_func;
00150 const char *prefix_str;
00151
00152
00153
00154
00155
00156 bool on(DiagsTagType mode = DiagsTagType_Debug) const {
00157 return (config.enabled[mode]);
00158 }
00159
00160 bool on(const char *tag, DiagsTagType mode = DiagsTagType_Debug) const {
00161 return (config.enabled[mode] && tag_activated(tag, mode));
00162 }
00163
00164
00165
00166
00167
00168 inkcoreapi bool tag_activated(const char *tag, DiagsTagType mode = DiagsTagType_Debug) const;
00169
00170
00171
00172
00173
00174 const char *level_name(DiagsLevel dl) const;
00175
00176 inkcoreapi void print_va(const char *tag, DiagsLevel dl,
00177 const SrcLoc *loc, const char *format_string, va_list ap) const;
00178
00179
00180
00181
00182
00183
00184 void print(const char *tag, DiagsLevel dl, const char *file, const char *func,
00185 const int line, const char *format_string, ...) const TS_PRINTFLIKE(7, 8)
00186 {
00187 va_list ap;
00188 va_start(ap, format_string);
00189 if (show_location) {
00190 SrcLoc lp(file, func, line);
00191 print_va(tag, dl, &lp, format_string, ap);
00192 } else {
00193 print_va(tag, dl, NULL, format_string, ap);
00194 }
00195 va_end(ap);
00196 }
00197
00198
00199
00200
00201
00202
00203 void log_va(const char *tag, DiagsLevel dl, const SrcLoc * loc, const char *format_string, va_list ap)
00204 {
00205 if (!on(tag))
00206 return;
00207 print_va(tag, dl, loc, format_string, ap);
00208 }
00209
00210 void log(const char *tag, DiagsLevel dl,
00211 const char *file, const char *func, const int line,
00212 const char *format_string, ...) const TS_PRINTFLIKE(7, 8);
00213
00214 void error_va(DiagsLevel dl,
00215 const char *file, const char *func, const int line,
00216 const char *format_string, va_list ap) const;
00217
00218 void
00219 error(DiagsLevel level,
00220 const char *file, const char *func, const int line,
00221 const char *format_string, ...) const TS_PRINTFLIKE(6, 7)
00222 {
00223 va_list ap;
00224 va_start(ap, format_string);
00225 error_va(level, file, func, line, format_string, ap);
00226 va_end(ap);
00227 }
00228
00229 void dump(FILE * fp = stdout) const;
00230
00231 void activate_taglist(const char *taglist, DiagsTagType mode = DiagsTagType_Debug);
00232
00233 void deactivate_all(DiagsTagType mode = DiagsTagType_Debug);
00234
00235 const char *base_debug_tags;
00236 const char *base_action_tags;
00237
00238 private:
00239 mutable ink_mutex tag_table_lock;
00240 DFA *activated_tags[2];
00241
00242 void lock() const
00243 {
00244 ink_mutex_acquire(&tag_table_lock);
00245 }
00246 void unlock() const
00247 {
00248 ink_mutex_release(&tag_table_lock);
00249 }
00250 };
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 #if !defined (__GNUC__)
00266 #ifndef __FUNCTION__
00267 #define __FUNCTION__ NULL
00268 #endif
00269 #endif
00270
00271 extern inkcoreapi Diags *diags;
00272
00273 #define DTA(l) l,__FILE__,__FUNCTION__,__LINE__
00274 void dummy_debug(const char * tag, const char *fmt, ...) TS_PRINTFLIKE(2, 3);
00275 inline void
00276 dummy_debug(const char *tag, const char *fmt, ...)
00277 {
00278 (void)tag;
00279 (void)fmt;
00280 }
00281
00282 #define Status(...) diags->error(DTA(DL_Status), __VA_ARGS__)
00283 #define Note(...) diags->error(DTA(DL_Note), __VA_ARGS__)
00284 #define Warning(...) diags->error(DTA(DL_Warning), __VA_ARGS__)
00285 #define Error(...) diags->error(DTA(DL_Error), __VA_ARGS__)
00286 #define Fatal(...) diags->error(DTA(DL_Fatal), __VA_ARGS__)
00287 #define Alert(...) diags->error(DTA(DL_Alert), __VA_ARGS__)
00288 #define Emergency(...) diags->error(DTA(DL_Emergency), __VA_ARGS__)
00289
00290 #define StatusV(fmt, ap) diags->error_va(DTA(DL_Status), fmt, ap)
00291 #define NoteV(fmt, ap) diags->error_va(DTA(DL_Note), fmt, ap)
00292 #define WarningV(fmt, ap) diags->error_va(DTA(DL_Warning), fmt, ap)
00293 #define ErrorV(fmt, ap) diags->error_va(DTA(DL_Error), fmt, ap)
00294 #define FatalV(fmt, ap) diags->error_va(DTA(DL_Fatal), fmt, ap)
00295 #define AlertV(fmt, ap) diags->error_va(DTA(DL_Alert), fmt, ap)
00296 #define EmergencyV(fmt, ap) diags->error_va(DTA(DL_Emergency), fmt, ap)
00297
00298 #ifdef TS_USE_DIAGS
00299 #define Diag(tag, ...) if (unlikely(diags->on())) diags->log(tag, DTA(DL_Diag), __VA_ARGS__)
00300 #define Debug(tag, ...) if (unlikely(diags->on())) diags->log(tag, DTA(DL_Debug), __VA_ARGS__)
00301 #define DiagSpecific(flag, tag, ...) if (unlikely(diags->on())) flag ? diags->print(tag, DTA(DL_Diag), __VA_ARGS__) : \
00302 diags->log(tag, DTA(DL_Diag), __VA_ARGS__)
00303 #define DebugSpecific(flag, tag, ...) if (unlikely(diags->on())) flag ? diags->print(tag, DTA(DL_Debug), __VA_ARGS__) : \
00304 diags->log(tag, DTA(DL_Debug), __VA_ARGS__)
00305
00306 #define is_debug_tag_set(_t) unlikely(diags->on(_t,DiagsTagType_Debug))
00307 #define is_action_tag_set(_t) unlikely(diags->on(_t,DiagsTagType_Action))
00308 #define debug_tag_assert(_t,_a) (is_debug_tag_set(_t) ? (ink_release_assert(_a), 0) : 0)
00309 #define action_tag_assert(_t,_a) (is_action_tag_set(_t) ? (ink_release_assert(_a), 0) : 0)
00310 #define is_diags_on(_t) unlikely(diags->on(_t))
00311
00312 #else // TS_USE_DIAGS
00313
00314 #define Diag(tag, fmt, ...) if (0) dummy_debug(tag, __VA_ARGS__)
00315 #define Debug(tag, fmt, ...) if (0) dummy_debug(tag, __VA_ARGS__)
00316 #define DiagSpecific(flag, tag, ...) if (0 && tag) dummy_debug(tag, __VA_ARGS__);
00317 #define DebugSpecific(flag, tag, ...) if (0 && tag) dummy_debug(tag, __VA_ARGS__);
00318
00319
00320 #define is_debug_tag_set(_t) 0
00321 #define is_action_tag_set(_t) 0
00322 #define debug_tag_assert(_t,_a)
00323 #define action_tag_assert(_t,_a)
00324 #define is_diags_on(_t) 0
00325
00326 #endif // TS_USE_DIAGS
00327 #endif