< prev index next >

src/share/vm/logging/logConfiguration.cpp

Print this page
rev 11857 : [mq]: 8157948


  90   }
  91 }
  92 
  93 void LogConfiguration::initialize(jlong vm_start_time) {
  94   LogFileOutput::set_file_name_parameters(vm_start_time);
  95   LogDecorations::initialize(vm_start_time);
  96   assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
  97   _outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtLogging);
  98   _outputs[0] = LogOutput::Stdout;
  99   _outputs[1] = LogOutput::Stderr;
 100   _n_outputs = 2;
 101 }
 102 
 103 void LogConfiguration::finalize() {
 104   for (size_t i = 2; i < _n_outputs; i++) {
 105     delete _outputs[i];
 106   }
 107   FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
 108 }
 109 
 110 size_t LogConfiguration::find_output(const char* name) {
 111   for (size_t i = 0; i < _n_outputs; i++) {
 112     if (strcmp(_outputs[i]->name(), name) == 0) {
 113       return i;
 114     }
 115   }
 116   return SIZE_MAX;
 117 }
 118 
 119 LogOutput* LogConfiguration::new_output(char* name, const char* options, outputStream* errstream) {
 120   const char* type;
 121   char* equals_pos = strchr(name, '=');
 122   if (equals_pos == NULL) {
 123     type = "file";
 124   } else {
 125     *equals_pos = '\0';
 126     type = name;
 127     name = equals_pos + 1;





 128   }

 129 
 130   // Check if name is quoted, and if so, strip the quotes
 131   char* quote = strchr(name, '"');
 132   if (quote != NULL) {
 133     char* end_quote = strchr(name + 1, '"');
 134     if (end_quote == NULL) {
 135       errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
 136       return NULL;
 137     } else if (quote != name || end_quote[1] != '\0') {

 138       errstream->print_cr("Output name can not be partially quoted."
 139                           " Either surround the whole name with quotation marks,"
 140                           " or do not use quotation marks at all.");
 141       return NULL;
 142     }

 143     name++;
 144     *end_quote = '\0';











 145   }



 146 



 147   LogOutput* output;
 148   if (strcmp(type, "file") == 0) {
 149     output = new LogFileOutput(name);
 150   } else {
 151     errstream->print_cr("Unsupported log output type.");
 152     return NULL;
 153   }
 154 
 155   bool success = output->initialize(options, errstream);
 156   if (!success) {
 157     errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options);
 158     delete output;
 159     return NULL;
 160   }
 161   return output;
 162 }
 163 
 164 size_t LogConfiguration::add_output(LogOutput* output) {
 165   size_t idx = _n_outputs++;
 166   _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
 167   _outputs[idx] = output;
 168   return idx;
 169 }
 170 
 171 void LogConfiguration::delete_output(size_t idx) {


 347                                            const char* what,
 348                                            const char* decoratorstr,
 349                                            const char* output_options,
 350                                            outputStream* errstream) {
 351   if (outputstr == NULL || strlen(outputstr) == 0) {
 352     outputstr = "stdout";
 353   }
 354 
 355   LogTagLevelExpression expr;
 356   if (!expr.parse(what, errstream)) {
 357     return false;
 358   }
 359 
 360   LogDecorators decorators;
 361   if (!decorators.parse(decoratorstr, errstream)) {
 362     return false;
 363   }
 364 
 365   ConfigurationLock cl;
 366   size_t idx;
 367   if (outputstr[0] == '#') {
 368     int ret = sscanf(outputstr+1, SIZE_FORMAT, &idx);
 369     if (ret != 1 || idx >= _n_outputs) {
 370       errstream->print_cr("Invalid output index '%s'", outputstr);
 371       return false;
 372     }
 373   } else {
 374     idx = find_output(outputstr);
 375     if (idx == SIZE_MAX) {
 376       char* tmp = os::strdup_check_oom(outputstr, mtLogging);
 377       LogOutput* output = new_output(tmp, output_options, errstream);
 378       os::free(tmp);
 379       if (output == NULL) {
 380         return false;
 381       }






 382       idx = add_output(output);

 383     } else if (output_options != NULL && strlen(output_options) > 0) {
 384       errstream->print_cr("Output options for existing outputs are ignored.");





 385     }
 386   }
 387   configure_output(idx, expr, decorators);
 388   notify_update_listeners();
 389   return true;
 390 }
 391 
 392 void LogConfiguration::describe_available(outputStream* out){
 393   out->print("Available log levels:");
 394   for (size_t i = 0; i < LogLevel::Count; i++) {
 395     out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(i)));
 396   }
 397   out->cr();
 398 
 399   out->print("Available log decorators:");
 400   for (size_t i = 0; i < LogDecorators::Count; i++) {
 401     LogDecorators::Decorator d = static_cast<LogDecorators::Decorator>(i);
 402     out->print("%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
 403   }
 404   out->cr();




  90   }
  91 }
  92 
  93 void LogConfiguration::initialize(jlong vm_start_time) {
  94   LogFileOutput::set_file_name_parameters(vm_start_time);
  95   LogDecorations::initialize(vm_start_time);
  96   assert(_outputs == NULL, "Should not initialize _outputs before this function, initialize called twice?");
  97   _outputs = NEW_C_HEAP_ARRAY(LogOutput*, 2, mtLogging);
  98   _outputs[0] = LogOutput::Stdout;
  99   _outputs[1] = LogOutput::Stderr;
 100   _n_outputs = 2;
 101 }
 102 
 103 void LogConfiguration::finalize() {
 104   for (size_t i = 2; i < _n_outputs; i++) {
 105     delete _outputs[i];
 106   }
 107   FREE_C_HEAP_ARRAY(LogOutput*, _outputs);
 108 }
 109 
 110 // Normalizes the given LogOutput name to type=name form.
 111 static bool normalize_output_name(const char* full_name, char* buffer, size_t len, outputStream* errstream) {
 112   const char* start_quote = strchr(full_name, '"');
 113   const char* equals = strchr(full_name, '=');
 114   const bool quoted = start_quote != NULL;
 115   const bool is_stdout_or_stderr = (strcmp(full_name, "stdout") == 0 || strcmp(full_name, "stderr") == 0);
 116 
 117   // ignore equals sign within quotes
 118   if (quoted && equals > start_quote) {
 119     equals = NULL;
 120   }
 121 
 122   const char* prefix = "";
 123   size_t prefix_len = 0;
 124   const char* name = full_name;
 125   if (equals != NULL) {
 126     // split on equals sign
 127     name = equals + 1;
 128     prefix = full_name;
 129     prefix_len = equals - full_name + 1;
 130   } else if (!is_stdout_or_stderr) {
 131     prefix = "file=";
 132     prefix_len = strlen(prefix);
 133   }
 134   size_t name_len = strlen(name);
 135 
 136   if (quoted) {
 137     const char* end_quote = strchr(start_quote + 1, '"');


 138     if (end_quote == NULL) {
 139       errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
 140       return false;
 141     }
 142     if (start_quote != name || end_quote[1] != '\0') {
 143       errstream->print_cr("Output name can not be partially quoted."
 144                           " Either surround the whole name with quotation marks,"
 145                           " or do not use quotation marks at all.");
 146       return false;
 147     }
 148     // strip start and end quote
 149     name++;
 150     name_len -= 2;
 151   }
 152 
 153   int ret = jio_snprintf(buffer, len, "%.*s%.*s", prefix_len, prefix, name_len, name);
 154   assert(ret > 0, "buffer issue");
 155   return true;
 156 }
 157 
 158 size_t LogConfiguration::find_output(const char* name) {
 159   for (size_t i = 0; i < _n_outputs; i++) {
 160     if (strcmp(_outputs[i]->name(), name) == 0) {
 161       return i;
 162     }
 163   }
 164   return SIZE_MAX;
 165 }
 166 
 167 LogOutput* LogConfiguration::new_output(const char* name,
 168                                         const char* options,
 169                                         outputStream* errstream) {
 170   LogOutput* output;
 171   if (strncmp(name, "file=", strlen("file=")) == 0) {
 172     output = new LogFileOutput(name);
 173   } else {
 174     errstream->print_cr("Unsupported log output type: %s", name);
 175     return NULL;
 176   }
 177 
 178   bool success = output->initialize(options, errstream);
 179   if (!success) {
 180     errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options);
 181     delete output;
 182     return NULL;
 183   }
 184   return output;
 185 }
 186 
 187 size_t LogConfiguration::add_output(LogOutput* output) {
 188   size_t idx = _n_outputs++;
 189   _outputs = REALLOC_C_HEAP_ARRAY(LogOutput*, _outputs, _n_outputs, mtLogging);
 190   _outputs[idx] = output;
 191   return idx;
 192 }
 193 
 194 void LogConfiguration::delete_output(size_t idx) {


 370                                            const char* what,
 371                                            const char* decoratorstr,
 372                                            const char* output_options,
 373                                            outputStream* errstream) {
 374   if (outputstr == NULL || strlen(outputstr) == 0) {
 375     outputstr = "stdout";
 376   }
 377 
 378   LogTagLevelExpression expr;
 379   if (!expr.parse(what, errstream)) {
 380     return false;
 381   }
 382 
 383   LogDecorators decorators;
 384   if (!decorators.parse(decoratorstr, errstream)) {
 385     return false;
 386   }
 387 
 388   ConfigurationLock cl;
 389   size_t idx;
 390   if (outputstr[0] == '#') { // Output specified using index
 391     int ret = sscanf(outputstr + 1, SIZE_FORMAT, &idx);
 392     if (ret != 1 || idx >= _n_outputs) {
 393       errstream->print_cr("Invalid output index '%s'", outputstr);
 394       return false;
 395     }
 396   } else { // Output specified using name
 397     // Normalize the name, stripping quotes and ensures it includes type prefix
 398     size_t len = strlen(outputstr) + strlen("file=") + 1;
 399     char* normalized = NEW_C_HEAP_ARRAY(char, len, mtLogging);
 400     if (!normalize_output_name(outputstr, normalized, len, errstream)) {


 401       return false;
 402     }
 403 
 404     idx = find_output(normalized);
 405     if (idx == SIZE_MAX) {
 406       // Attempt to create and add the output
 407       LogOutput* output = new_output(normalized, output_options, errstream);
 408       if (output != NULL) {
 409         idx = add_output(output);
 410       }
 411     } else if (output_options != NULL && strlen(output_options) > 0) {
 412       errstream->print_cr("Output options for existing outputs are ignored.");
 413     }
 414 
 415     FREE_C_HEAP_ARRAY(char, normalized);
 416     if (idx == SIZE_MAX) {
 417       return false;
 418     }
 419   }
 420   configure_output(idx, expr, decorators);
 421   notify_update_listeners();
 422   return true;
 423 }
 424 
 425 void LogConfiguration::describe_available(outputStream* out){
 426   out->print("Available log levels:");
 427   for (size_t i = 0; i < LogLevel::Count; i++) {
 428     out->print("%s %s", (i == 0 ? "" : ","), LogLevel::name(static_cast<LogLevelType>(i)));
 429   }
 430   out->cr();
 431 
 432   out->print("Available log decorators:");
 433   for (size_t i = 0; i < LogDecorators::Count; i++) {
 434     LogDecorators::Decorator d = static_cast<LogDecorators::Decorator>(i);
 435     out->print("%s %s (%s)", (i == 0 ? "" : ","), LogDecorators::name(d), LogDecorators::abbreviation(d));
 436   }
 437   out->cr();


< prev index next >