hotspot/src/share/vm/logging/log.cpp
changeset 37465 1d5551f466ee
parent 37463 a4581cbe32cd
child 38263 a7488329ad27
equal deleted inserted replaced
37464:5373bbadb433 37465:1d5551f466ee
    29 #ifndef PRODUCT
    29 #ifndef PRODUCT
    30 
    30 
    31 #include "gc/shared/gcTraceTime.inline.hpp"
    31 #include "gc/shared/gcTraceTime.inline.hpp"
    32 #include "logging/log.hpp"
    32 #include "logging/log.hpp"
    33 #include "logging/logConfiguration.hpp"
    33 #include "logging/logConfiguration.hpp"
       
    34 #include "logging/logFileOutput.hpp"
    34 #include "logging/logOutput.hpp"
    35 #include "logging/logOutput.hpp"
    35 #include "logging/logTagLevelExpression.hpp"
    36 #include "logging/logTagLevelExpression.hpp"
    36 #include "logging/logTagSet.hpp"
    37 #include "logging/logTagSet.hpp"
    37 #include "logging/logStream.inline.hpp"
    38 #include "logging/logStream.inline.hpp"
    38 #include "memory/resourceArea.hpp"
    39 #include "memory/resourceArea.hpp"
   134 
   135 
   135   // Disable 'gc*' and 'logging', verifying all logging is properly disabled
   136   // Disable 'gc*' and 'logging', verifying all logging is properly disabled
   136   LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc));
   137   LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc));
   137   LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging));
   138   LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging));
   138   assert_str_eq("all=off", stdoutput->config_string());
   139   assert_str_eq("all=off", stdoutput->config_string());
       
   140 }
       
   141 
       
   142 static size_t number_of_lines_with_substring_in_file(const char* filename,
       
   143                                                      const char* substr) {
       
   144   ResourceMark rm;
       
   145   size_t ret = 0;
       
   146   FILE* fp = fopen(filename, "r");
       
   147   assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno));
       
   148 
       
   149   int buflen = 512;
       
   150   char* buf = NEW_RESOURCE_ARRAY(char, buflen);
       
   151   long pos = 0;
       
   152 
       
   153   while (fgets(buf, buflen, fp) != NULL) {
       
   154     if (buf[strlen(buf) - 1] != '\n' && !feof(fp)) {
       
   155       // retry with a larger buffer
       
   156       buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2);
       
   157       buflen *= 2;
       
   158       // rewind to beginning of line
       
   159       fseek(fp, pos, SEEK_SET);
       
   160       continue;
       
   161     }
       
   162     pos = ftell(fp);
       
   163     if (strstr(buf, substr) != NULL) {
       
   164       ret++;
       
   165     }
       
   166   }
       
   167 
       
   168   fclose(fp);
       
   169   return ret;
       
   170 }
       
   171 
       
   172 static bool file_exists(const char* filename) {
       
   173   struct stat st;
       
   174   return os::stat(filename, &st) == 0;
       
   175 }
       
   176 
       
   177 static void delete_file(const char* filename) {
       
   178   if (!file_exists(filename)) {
       
   179     return;
       
   180   }
       
   181   int ret = remove(filename);
       
   182   assert(ret == 0, "failed to remove file '%s': %s", filename, strerror(errno));
       
   183 }
       
   184 
       
   185 static void create_directory(const char* name) {
       
   186   assert(!file_exists(name), "can't create directory: %s already exists", name);
       
   187   bool failed;
       
   188 #ifdef _WINDOWS
       
   189   failed = !CreateDirectory(name, NULL);
       
   190 #else
       
   191   failed = mkdir(name, 0777);
       
   192 #endif
       
   193   assert(!failed, "failed to create directory %s", name);
       
   194 }
       
   195 
       
   196 static const char* ExpectedLine = "a (hopefully) unique log line for testing";
       
   197 
       
   198 static void init_file(const char* filename, const char* options = "") {
       
   199   LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options,
       
   200                                         Log(logging)::error_stream());
       
   201   log_debug(logging)("%s", ExpectedLine);
       
   202   LogConfiguration::parse_log_arguments(filename, "all=off", "", "",
       
   203                                         Log(logging)::error_stream());
       
   204 }
       
   205 
       
   206 void Test_log_file_startup_rotation() {
       
   207   ResourceMark rm;
       
   208   const size_t rotations = 5;
       
   209   const char* filename = "start-rotate-test";
       
   210   char* rotated_file[rotations];
       
   211   for (size_t i = 0; i < rotations; i++) {
       
   212     size_t len = strlen(filename) + 3;
       
   213     rotated_file[i] = NEW_RESOURCE_ARRAY(char, len);
       
   214     jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT, filename, i);
       
   215     delete_file(rotated_file[i]);
       
   216   };
       
   217 
       
   218   delete_file(filename);
       
   219   init_file(filename);
       
   220   assert(file_exists(filename),
       
   221          "configured logging to file '%s' but file was not found", filename);
       
   222 
       
   223   // Initialize the same file a bunch more times to trigger rotations
       
   224   for (size_t i = 0; i < rotations; i++) {
       
   225     init_file(filename);
       
   226     assert(file_exists(rotated_file[i]), "existing file was not rotated");
       
   227   }
       
   228 
       
   229   // Remove a file and expect its slot to be re-used
       
   230   delete_file(rotated_file[1]);
       
   231   init_file(filename);
       
   232   assert(file_exists(rotated_file[1]), "log file not properly rotated");
       
   233 
       
   234   // Clean up after test
       
   235   delete_file(filename);
       
   236   for (size_t i = 0; i < rotations; i++) {
       
   237     delete_file(rotated_file[i]);
       
   238   }
       
   239 }
       
   240 
       
   241 void Test_log_file_startup_truncation() {
       
   242   ResourceMark rm;
       
   243   const char* filename = "start-truncate-test";
       
   244   const char* archived_filename = "start-truncate-test.0";
       
   245 
       
   246   delete_file(filename);
       
   247   delete_file(archived_filename);
       
   248 
       
   249   // Use the same log file twice and expect it to be overwritten/truncated
       
   250   init_file(filename, "filecount=0");
       
   251   assert(file_exists(filename), "couldn't find log file: %s", filename);
       
   252 
       
   253   init_file(filename, "filecount=0");
       
   254   assert(file_exists(filename), "couldn't find log file: %s", filename);
       
   255   assert(!file_exists(archived_filename),
       
   256          "existing log file %s was not properly truncated when filecount was 0",
       
   257          filename);
       
   258 
       
   259   // Verify that the file was really truncated and not just appended
       
   260   assert(number_of_lines_with_substring_in_file(filename, ExpectedLine) == 1,
       
   261          "log file %s appended rather than truncated", filename);
       
   262 
       
   263   delete_file(filename);
       
   264   delete_file(archived_filename);
   139 }
   265 }
   140 
   266 
   141 static int Test_logconfiguration_subscribe_triggered = 0;
   267 static int Test_logconfiguration_subscribe_triggered = 0;
   142 
   268 
   143 static void Test_logconfiguration_subscribe_helper() {
   269 static void Test_logconfiguration_subscribe_helper() {
   739   Test_log_gctracetime_no_heap();
   865   Test_log_gctracetime_no_heap();
   740   Test_log_gctracetime_no_cause();
   866   Test_log_gctracetime_no_cause();
   741   Test_log_gctracetime_no_heap_no_cause();
   867   Test_log_gctracetime_no_heap_no_cause();
   742 }
   868 }
   743 
   869 
       
   870 void Test_invalid_log_file() {
       
   871   ResourceMark rm;
       
   872   stringStream ss;
       
   873   const char* target_name = "tmplogdir";
       
   874 
       
   875   // Attempt to log to a directory (existing log not a regular file)
       
   876   create_directory(target_name);
       
   877   LogFileOutput bad_file("tmplogdir");
       
   878   assert(bad_file.initialize("", &ss) == false, "file was initialized "
       
   879          "when there was an existing directory with the same name");
       
   880   assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL,
       
   881          "missing expected error message, received msg: %s", ss.as_string());
       
   882   ss.reset();
       
   883   remove(target_name);
       
   884 }
       
   885 
   744 #endif // PRODUCT
   886 #endif // PRODUCT