hotspot/src/share/vm/logging/logConfiguration.cpp
changeset 35229 b8d78ee728b2
parent 35228 e7bbfb90fd31
child 35230 a528ea8203ec
equal deleted inserted replaced
35228:e7bbfb90fd31 35229:b8d78ee728b2
   108     }
   108     }
   109   }
   109   }
   110   return SIZE_MAX;
   110   return SIZE_MAX;
   111 }
   111 }
   112 
   112 
   113 LogOutput* LogConfiguration::new_output(char* name, const char* options) {
   113 LogOutput* LogConfiguration::new_output(char* name, const char* options, outputStream* errstream) {
   114   const char* type;
   114   const char* type;
   115   char* equals_pos = strchr(name, '=');
   115   char* equals_pos = strchr(name, '=');
   116   if (equals_pos == NULL) {
   116   if (equals_pos == NULL) {
   117     type = "file";
   117     type = "file";
   118   } else {
   118   } else {
   119     *equals_pos = '\0';
   119     *equals_pos = '\0';
   120     type = name;
   120     type = name;
   121     name = equals_pos + 1;
   121     name = equals_pos + 1;
   122   }
   122   }
   123 
   123 
       
   124   // Check if name is quoted, and if so, strip the quotes
       
   125   char* quote = strchr(name, '"');
       
   126   if (quote != NULL) {
       
   127     char* end_quote = strchr(name + 1, '"');
       
   128     if (end_quote == NULL) {
       
   129       errstream->print_cr("Output name has opening quote but is missing a terminating quote.");
       
   130       return NULL;
       
   131     } else if (quote != name || end_quote[1] != '\0') {
       
   132       errstream->print_cr("Output name can not be partially quoted."
       
   133                           " Either surround the whole name with quotation marks,"
       
   134                           " or do not use quotation marks at all.");
       
   135       return NULL;
       
   136     }
       
   137     name++;
       
   138     *end_quote = '\0';
       
   139   }
       
   140 
   124   LogOutput* output;
   141   LogOutput* output;
   125   if (strcmp(type, "file") == 0) {
   142   if (strcmp(type, "file") == 0) {
   126     output = new LogFileOutput(name);
   143     output = new LogFileOutput(name);
   127   } else {
   144   } else {
   128     // unsupported log output type
   145     errstream->print_cr("Unsupported log output type.");
   129     return NULL;
   146     return NULL;
   130   }
   147   }
   131 
   148 
   132   bool success = output->initialize(options);
   149   bool success = output->initialize(options);
   133   if (!success) {
   150   if (!success) {
       
   151     errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options);
   134     delete output;
   152     delete output;
   135     return NULL;
   153     return NULL;
   136   }
   154   }
   137   return output;
   155   return output;
   138 }
   156 }
   272 
   290 
   273 bool LogConfiguration::parse_command_line_arguments(const char* opts) {
   291 bool LogConfiguration::parse_command_line_arguments(const char* opts) {
   274   char* copy = os::strdup_check_oom(opts, mtLogging);
   292   char* copy = os::strdup_check_oom(opts, mtLogging);
   275 
   293 
   276   // Split the option string to its colon separated components.
   294   // Split the option string to its colon separated components.
   277   char* what = NULL;
   295   char* str = copy;
   278   char* output_str = NULL;
   296   char* substrings[4] = {0};
   279   char* decorators_str = NULL;
   297   for (int i = 0 ; i < 4; i++) {
   280   char* output_options = NULL;
   298     substrings[i] = str;
   281 
   299 
   282   what = copy;
   300     // Find the next colon or quote
   283   char* colon = strchr(what, ':');
   301     char* next = strpbrk(str, ":\"");
   284   if (colon != NULL) {
   302     while (next != NULL && *next == '"') {
   285     *colon = '\0';
   303       char* end_quote = strchr(next + 1, '"');
   286     output_str = colon + 1;
   304       if (end_quote == NULL) {
   287     colon = strchr(output_str, ':');
   305         log_error(logging)("Missing terminating quote in -Xlog option '%s'", str);
   288     if (colon != NULL) {
   306         os::free(copy);
   289       *colon = '\0';
   307         return false;
   290       decorators_str = colon + 1;
       
   291       colon = strchr(decorators_str, ':');
       
   292       if (colon != NULL) {
       
   293         *colon = '\0';
       
   294         output_options = colon + 1;
       
   295       }
   308       }
   296     }
   309       // Keep searching after the quoted substring
   297   }
   310       next = strpbrk(end_quote + 1, ":\"");
   298 
   311     }
   299   // Parse each argument
   312 
       
   313     if (next != NULL) {
       
   314       *next = '\0';
       
   315       str = next + 1;
       
   316     } else {
       
   317       break;
       
   318     }
       
   319   }
       
   320 
       
   321   // Parse and apply the separated configuration options
       
   322   char* what = substrings[0];
       
   323   char* output = substrings[1];
       
   324   char* decorators = substrings[2];
       
   325   char* output_options = substrings[3];
   300   char errbuf[512];
   326   char errbuf[512];
   301   stringStream ss(errbuf, sizeof(errbuf));
   327   stringStream ss(errbuf, sizeof(errbuf));
   302   bool success = parse_log_arguments(output_str, what, decorators_str, output_options, &ss);
   328   bool success = parse_log_arguments(output, what, decorators, output_options, &ss);
   303   if (!success) {
   329   if (!success) {
   304     errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline.
   330     errbuf[strlen(errbuf) - 1] = '\0'; // Strip trailing newline.
   305     log_error(logging)("%s", errbuf);
   331     log_error(logging)("%s", errbuf);
   306   }
   332   }
   307 
   333 
   338     }
   364     }
   339   } else {
   365   } else {
   340     idx = find_output(outputstr);
   366     idx = find_output(outputstr);
   341     if (idx == SIZE_MAX) {
   367     if (idx == SIZE_MAX) {
   342       char* tmp = os::strdup_check_oom(outputstr, mtLogging);
   368       char* tmp = os::strdup_check_oom(outputstr, mtLogging);
   343       LogOutput* output = new_output(tmp, output_options);
   369       LogOutput* output = new_output(tmp, output_options, errstream);
   344       os::free(tmp);
   370       os::free(tmp);
   345       if (output == NULL) {
   371       if (output == NULL) {
   346         errstream->print("Unable to add output '%s'", outputstr);
       
   347         if (output_options != NULL && strlen(output_options) > 0) {
       
   348           errstream->print(" with options '%s'", output_options);
       
   349         }
       
   350         errstream->cr();
       
   351         return false;
   372         return false;
   352       }
   373       }
   353       idx = add_output(output);
   374       idx = add_output(output);
   354     } else if (output_options != NULL && strlen(output_options) > 0) {
   375     } else if (output_options != NULL && strlen(output_options) > 0) {
   355       errstream->print_cr("Output options for existing outputs are ignored.");
   376       errstream->print_cr("Output options for existing outputs are ignored.");