00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "libts.h"
00025 #include "I_Layout.h"
00026 #include "DiagsConfig.h"
00027 #include "P_RecCore.h"
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 void
00042 DiagsConfig::reconfigure_diags()
00043 {
00044   int i, e;
00045   char *p, *dt, *at;
00046   DiagsConfigState c;
00047   bool found, all_found;
00048 
00049   static struct
00050   {
00051     const char *config_name;
00052     DiagsLevel level;
00053   } output_records[] = {
00054     {
00055     "proxy.config.diags.output.diag", DL_Diag}, {
00056     "proxy.config.diags.output.debug", DL_Debug}, {
00057     "proxy.config.diags.output.status", DL_Status}, {
00058     "proxy.config.diags.output.note", DL_Note}, {
00059     "proxy.config.diags.output.warning", DL_Warning}, {
00060     "proxy.config.diags.output.error", DL_Error}, {
00061     "proxy.config.diags.output.fatal", DL_Fatal}, {
00062     "proxy.config.diags.output.alert", DL_Alert}, {
00063     "proxy.config.diags.output.emergency", DL_Emergency}, {
00064     NULL, DL_Undefined}
00065   };
00066 
00067   if (!callbacks_established) {
00068     register_diags_callbacks();
00069   }
00070 
00071   
00072 
00073 
00074   all_found = true;
00075 
00076   
00077   c.enabled[DiagsTagType_Debug] = (diags->base_debug_tags != NULL);
00078   c.enabled[DiagsTagType_Action] = (diags->base_action_tags != NULL);
00079 
00080   
00081 
00082   e = (int) REC_readInteger("proxy.config.diags.debug.enabled", &found);
00083   if (e && found)
00084     c.enabled[DiagsTagType_Debug] = 1;  
00085   all_found = all_found && found;
00086 
00087   e = (int) REC_readInteger("proxy.config.diags.action.enabled", &found);
00088   if (e && found)
00089     c.enabled[DiagsTagType_Action] = 1; 
00090   all_found = all_found && found;
00091 
00092   e = (int) REC_readInteger("proxy.config.diags.show_location", &found);
00093   diags->show_location = ((e && found) ? 1 : 0);
00094   all_found = all_found && found;
00095 
00096   
00097   for (i = 0;; i++) {
00098     const char *record_name = output_records[i].config_name;
00099     DiagsLevel l = output_records[i].level;
00100 
00101     if (!record_name)
00102       break;
00103     p = REC_readString(record_name, &found);
00104     all_found = all_found && found;
00105     if (found) {
00106       parse_output_string(p, &(c.outputs[l]));
00107       ats_free(p);
00108     } else {
00109       diags->print(NULL, DTA(DL_Error), "can't find config variable '%s'\n", record_name);
00110     }
00111   }
00112 
00113   p = REC_readString("proxy.config.diags.debug.tags", &found);
00114   dt = (found ? p : NULL);      
00115   all_found = all_found && found;
00116 
00117   p = REC_readString("proxy.config.diags.action.tags", &found);
00118   at = (found ? p : NULL);      
00119   all_found = all_found && found;
00120 
00121 
00122   
00123   
00124 
00125 
00126   if (!all_found) {
00127     diags->print(NULL, DTA(DL_Error), "couldn't fetch all proxy.config.diags values");
00128   } else {
00129 
00130     
00131 
00132 
00133     diags->deactivate_all(DiagsTagType_Debug);
00134     diags->deactivate_all(DiagsTagType_Action);
00135 
00136 
00137     
00138 
00139 
00140     diags->activate_taglist((diags->base_debug_tags ? diags->base_debug_tags : dt), DiagsTagType_Debug);
00141     diags->activate_taglist((diags->base_action_tags ? diags->base_action_tags : at), DiagsTagType_Action);
00142 
00143 
00144     
00145 
00146 #if !defined(__GNUC__)
00147     diags->config = c;
00148 #else
00149     memcpy(((void *) &diags->config), ((void *) &c), sizeof(DiagsConfigState));
00150 #endif
00151     diags->print(NULL, DTA(DL_Note), "updated diags config");
00152   }
00153 
00154 
00155   
00156 
00157   ats_free(dt);
00158   ats_free(at);
00159 }
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 static int
00172 diags_config_callback(const char * , RecDataT ,
00173                       RecData , void *opaque_token)
00174 {
00175   DiagsConfig *diagsConfig;
00176 
00177   diagsConfig = (DiagsConfig *) opaque_token;
00178   ink_assert(diags->magic == DIAGS_MAGIC);
00179   diagsConfig->reconfigure_diags();
00180   return (0);
00181 }
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 void
00203 DiagsConfig::parse_output_string(char *s, DiagsModeOutput * o)
00204 {
00205   o->to_stdout = (s && strchr(s, 'O'));
00206   o->to_stderr = (s && strchr(s, 'E'));
00207   o->to_syslog = (s && strchr(s, 'S'));
00208   o->to_diagslog = (s && strchr(s, 'L'));
00209 }
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 void
00221 DiagsConfig::config_diags_norecords()
00222 {
00223   DiagsConfigState c;
00224 
00225 
00226   
00227 
00228   diags->deactivate_all(DiagsTagType_Debug);
00229   diags->deactivate_all(DiagsTagType_Action);
00230 
00231 
00232   
00233 
00234 
00235   if (diags->base_debug_tags) {
00236     diags->activate_taglist(diags->base_debug_tags, DiagsTagType_Debug);
00237     c.enabled[DiagsTagType_Debug] = 1;
00238   } else {
00239     c.enabled[DiagsTagType_Debug] = 0;
00240   }
00241 
00242   if (diags->base_action_tags) {
00243     diags->activate_taglist(diags->base_action_tags, DiagsTagType_Action);
00244     c.enabled[DiagsTagType_Action] = 1;
00245   } else {
00246     c.enabled[DiagsTagType_Action] = 0;
00247   }
00248 
00249 #if !defined(__GNUC__)
00250   diags->config = c;
00251 #else
00252   memcpy(((void *) &diags->config), ((void *) &c), sizeof(DiagsConfigState));
00253 #endif
00254 }
00255 
00256 void
00257 DiagsConfig::RegisterDiagConfig()
00258 {
00259   RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.debug.enabled", 0, RECU_NULL, RECC_NULL, NULL);
00260   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.debug.tags", "", RECU_NULL, RECC_NULL, NULL);
00261   RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.action.enabled", 0, RECU_NULL, RECC_NULL, NULL);
00262   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.action.tags", "", RECU_NULL, RECC_NULL, NULL);
00263   RecRegisterConfigInt(RECT_CONFIG, "proxy.config.diags.show_location", 0, RECU_NULL, RECC_NULL, NULL);
00264   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.diag", "L", RECU_NULL, RECC_NULL, NULL);
00265   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.debug", "L", RECU_NULL, RECC_NULL, NULL);
00266   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.status", "L", RECU_NULL, RECC_NULL, NULL);
00267   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.note", "L", RECU_NULL, RECC_NULL, NULL);
00268   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.warning", "L", RECU_NULL, RECC_NULL, NULL);
00269   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.error", "SL", RECU_NULL, RECC_NULL, NULL);
00270   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.fatal", "SL", RECU_NULL, RECC_NULL, NULL);
00271   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.alert", "L", RECU_NULL, RECC_NULL, NULL);
00272   RecRegisterConfigString(RECT_CONFIG, "proxy.config.diags.output.emergency", "SL", RECU_NULL, RECC_NULL, NULL);
00273 }
00274 
00275 
00276 DiagsConfig::DiagsConfig(const char * filename, const char * tags, const char * actions, bool use_records)
00277 {
00278   char diags_logpath[PATH_NAME_MAX + 1];
00279   ats_scoped_str logpath;
00280 
00281   callbacks_established = false;
00282   diags_log_fp = (FILE *) NULL;
00283   diags = NULL;
00284 
00285 
00286   
00287   
00288   
00289 
00290 
00291   if (!use_records) {
00292     diags = new Diags(tags, actions, NULL);
00293     config_diags_norecords();
00294     return;
00295   }
00296 
00297   
00298   
00299 
00300   logpath = RecConfigReadLogDir();
00301   if (access(logpath, W_OK | R_OK) == -1) {
00302     fprintf(stderr, "unable to access log directory '%s': %d, %s\n",
00303             (const char *)logpath, errno, strerror(errno));
00304     fprintf(stderr, "please set 'proxy.config.log.logfile_dir'\n");
00305     _exit(1);
00306   }
00307 
00308   ink_filepath_make(diags_logpath, sizeof(diags_logpath), logpath, filename);
00309 
00310   
00311   
00312   diags_log_fp = fopen(diags_logpath, "a+");
00313   if (diags_log_fp) {
00314     int status;
00315     status = setvbuf(diags_log_fp, NULL, _IOLBF, 512);
00316     if (status != 0) {
00317       fclose(diags_log_fp);
00318       diags_log_fp = NULL;
00319     }
00320   }
00321 
00322   diags = new Diags(tags, actions, diags_log_fp);
00323   if (diags_log_fp == NULL) {
00324 
00325     diags->print(NULL, DTA(DL_Warning),
00326                  "couldn't open diags log file '%s', " "will not log to this file", diags_logpath);
00327   }
00328   diags->print(NULL, DTA(DL_Status), "opened %s", diags_logpath);
00329 
00330   register_diags_callbacks();
00331 
00332   reconfigure_diags();
00333 
00334 }
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 void
00349 DiagsConfig::register_diags_callbacks()
00350 {
00351 
00352   static const char *config_record_names[] = {
00353     "proxy.config.diags.debug.enabled",
00354     "proxy.config.diags.debug.tags",
00355     "proxy.config.diags.action.enabled",
00356     "proxy.config.diags.action.tags",
00357     "proxy.config.diags.show_location",
00358     "proxy.config.diags.output.diag",
00359     "proxy.config.diags.output.debug",
00360     "proxy.config.diags.output.status",
00361     "proxy.config.diags.output.note",
00362     "proxy.config.diags.output.warning",
00363     "proxy.config.diags.output.error",
00364     "proxy.config.diags.output.fatal",
00365     "proxy.config.diags.output.alert",
00366     "proxy.config.diags.output.emergency",
00367     NULL
00368   };
00369 
00370   bool total_status = true;
00371   bool status;
00372   int i;
00373   void *o = (void *) this;
00374 
00375   
00376   for (i = 0; config_record_names[i] != NULL; i++) {
00377     status = (REC_RegisterConfigUpdateFunc(config_record_names[i], diags_config_callback, o) == REC_ERR_OKAY);
00378     if (!status) {
00379       diags->print(NULL, DTA(DL_Warning),
00380                    "couldn't register variable '%s', is records.config up to date?", config_record_names[i]);
00381     }
00382     total_status = total_status && status;
00383   }
00384 
00385   if (total_status == false) {
00386     diags->print(NULL, DTA(DL_Error), "couldn't setup all diags callbacks, diagnostics may misbehave");
00387     callbacks_established = false;
00388   } else {
00389     callbacks_established = true;
00390   }
00391 
00392 }
00393 
00394 DiagsConfig::~DiagsConfig()
00395 {
00396   if (diags_log_fp) {
00397     fclose(diags_log_fp);
00398     diags_log_fp = NULL;
00399   }
00400   delete diags;
00401 }