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 }