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