From f3db2796b875ee9177b111a0f3da3b9566d750d6 Mon Sep 17 00:00:00 2001 From: Fredrik Bredberg Date: Thu, 4 Apr 2024 15:28:46 +0000 Subject: [PATCH] 8327410: Add hostname option for UL file names Reviewed-by: jsjolen, dholmes --- .../share/logging/logConfiguration.cpp | 4 +- src/hotspot/share/logging/logFileOutput.cpp | 105 +++++++++--------- src/hotspot/share/logging/logFileOutput.hpp | 4 +- src/java.base/share/man/java.1 | 6 +- 4 files changed, 61 insertions(+), 58 deletions(-) diff --git a/src/hotspot/share/logging/logConfiguration.cpp b/src/hotspot/share/logging/logConfiguration.cpp index 18f225f7dd4..3a54d1f4e63 100644 --- a/src/hotspot/share/logging/logConfiguration.cpp +++ b/src/hotspot/share/logging/logConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -614,7 +614,7 @@ void LogConfiguration::print_command_line_help(outputStream* out) { out->print_cr("Available log outputs:"); out->print_cr(" stdout/stderr"); out->print_cr(" file="); - out->print_cr(" If the filename contains %%p and/or %%t, they will expand to the JVM's PID and startup timestamp, respectively."); + out->print_cr(" If the filename contains %%p, %%t and/or %%hn, they will expand to the JVM's PID, startup timestamp and host name, respectively."); out->cr(); out->print_cr("Available log output options:"); diff --git a/src/hotspot/share/logging/logFileOutput.cpp b/src/hotspot/share/logging/logFileOutput.cpp index 2350b37e726..783be865861 100644 --- a/src/hotspot/share/logging/logFileOutput.cpp +++ b/src/hotspot/share/logging/logFileOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ const char* const LogFileOutput::FileOpenMode = "a"; const char* const LogFileOutput::PidFilenamePlaceholder = "%p"; const char* const LogFileOutput::TimestampFilenamePlaceholder = "%t"; const char* const LogFileOutput::TimestampFormat = "%Y-%m-%d_%H-%M-%S"; +const char* const LogFileOutput::HostnameFilenamePlaceholder = "%hn"; const char* const LogFileOutput::FileSizeOptionKey = "filesize"; const char* const LogFileOutput::FileCountOptionKey = "filecount"; char LogFileOutput::_pid_str[PidBufferSize]; @@ -378,81 +379,81 @@ void LogFileOutput::rotate() { char* LogFileOutput::make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string) { + char hostname_string[HostnameBufferSize]; char* result = nullptr; - // Lets start finding out if we have any %d and/or %t in the name. + // Lets start finding out if we have any %p, %t and/or %hn in the name. // We will only replace the first occurrence of any placeholder const char* pid = strstr(file_name, PidFilenamePlaceholder); const char* timestamp = strstr(file_name, TimestampFilenamePlaceholder); + const char* hostname = strstr(file_name, HostnameFilenamePlaceholder); - if (pid == nullptr && timestamp == nullptr) { + if (pid == nullptr && timestamp == nullptr && hostname == nullptr) { // We found no place-holders, return the simple filename return os::strdup_check_oom(file_name, mtLogging); } // At least one of the place-holders were found in the file_name - const char* first = ""; - size_t first_pos = SIZE_MAX; - size_t first_replace_len = 0; - - const char* second = ""; - size_t second_pos = SIZE_MAX; - size_t second_replace_len = 0; - - // If we found a %p, then setup our variables accordingly + size_t result_len = strlen(file_name); if (pid != nullptr) { - if (timestamp == nullptr || pid < timestamp) { - first = pid_string; - first_pos = pid - file_name; - first_replace_len = strlen(PidFilenamePlaceholder); - } else { - second = pid_string; - second_pos = pid - file_name; - second_replace_len = strlen(PidFilenamePlaceholder); - } + result_len -= strlen(PidFilenamePlaceholder); + result_len += strlen(pid_string); } - if (timestamp != nullptr) { - if (pid == nullptr || timestamp < pid) { - first = timestamp_string; - first_pos = timestamp - file_name; - first_replace_len = strlen(TimestampFilenamePlaceholder); - } else { - second = timestamp_string; - second_pos = timestamp - file_name; - second_replace_len = strlen(TimestampFilenamePlaceholder); - } + result_len -= strlen(TimestampFilenamePlaceholder); + result_len += strlen(timestamp_string); + } + if (hostname != nullptr) { + if (!os::get_host_name(hostname_string, sizeof(hostname_string))) { + int res = jio_snprintf(hostname_string, sizeof(hostname_string), "unknown-host"); + assert(res > 0, "Hostname buffer too small"); + } + result_len -= strlen(HostnameFilenamePlaceholder); + result_len += strlen(hostname_string); } - - size_t first_len = strlen(first); - size_t second_len = strlen(second); - // Allocate the new buffer, size it to hold all we want to put in there +1. - size_t result_len = strlen(file_name) + first_len - first_replace_len + second_len - second_replace_len; result = NEW_C_HEAP_ARRAY(char, result_len + 1, mtLogging); // Assemble the strings size_t file_name_pos = 0; size_t i = 0; while (i < result_len) { - if (file_name_pos == first_pos) { - // We are in the range of the first placeholder - strcpy(result + i, first); - // Bump output buffer position with length of replacing string - i += first_len; - // Bump source buffer position to skip placeholder - file_name_pos += first_replace_len; - } else if (file_name_pos == second_pos) { - // We are in the range of the second placeholder - strcpy(result + i, second); - i += second_len; - file_name_pos += second_replace_len; - } else { - // Else, copy char by char of the original file - result[i] = file_name[file_name_pos++]; - i++; + if (file_name[file_name_pos] == '%') { + // Replace the first occurrence of any placeholder + if (pid != nullptr && strncmp(&file_name[file_name_pos], + PidFilenamePlaceholder, + strlen(PidFilenamePlaceholder)) == 0) { + strcpy(result + i, pid_string); + i += strlen(pid_string); + file_name_pos += strlen(PidFilenamePlaceholder); + pid = nullptr; + continue; + } + if (timestamp != nullptr && strncmp(&file_name[file_name_pos], + TimestampFilenamePlaceholder, + strlen(TimestampFilenamePlaceholder)) == 0) { + strcpy(result + i, timestamp_string); + i += strlen(timestamp_string); + file_name_pos += strlen(TimestampFilenamePlaceholder); + timestamp = nullptr; + continue; + } + if (hostname != nullptr && strncmp(&file_name[file_name_pos], + HostnameFilenamePlaceholder, + strlen(HostnameFilenamePlaceholder)) == 0) { + strcpy(result + i, hostname_string); + i += strlen(hostname_string); + file_name_pos += strlen(HostnameFilenamePlaceholder); + hostname = nullptr; + continue; + } } + // Else, copy char by char of the original file + result[i++] = file_name[file_name_pos++]; } + assert(i == result_len, "should be"); + assert(file_name[file_name_pos] == '\0', "should be"); + // Add terminating char result[result_len] = '\0'; return result; diff --git a/src/hotspot/share/logging/logFileOutput.hpp b/src/hotspot/share/logging/logFileOutput.hpp index aeac7f98f2d..6189cd08682 100644 --- a/src/hotspot/share/logging/logFileOutput.hpp +++ b/src/hotspot/share/logging/logFileOutput.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,10 +39,12 @@ class LogFileOutput : public LogFileStreamOutput { static const char* const PidFilenamePlaceholder; static const char* const TimestampFilenamePlaceholder; static const char* const TimestampFormat; + static const char* const HostnameFilenamePlaceholder; static const size_t DefaultFileCount = 5; static const size_t DefaultFileSize = 20 * M; static const size_t StartTimeBufferSize = 20; static const size_t PidBufferSize = 21; + static const size_t HostnameBufferSize = 512; static const uint MaxRotationFileCount = 1000; static char _pid_str[PidBufferSize]; static char _vm_start_time_str[StartTimeBufferSize]; diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 9d5bd5fba98..3754408fbde 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -4308,9 +4308,9 @@ The \f[V]-Xlog\f[R] option supports the following types of outputs: .IP \[bu] 2 \f[V]file=\f[R]\f[I]filename\f[R] --- Sends output to text file(s). .PP -When using \f[V]file=\f[R]\f[I]filename\f[R], specifying \f[V]%p\f[R] -and/or \f[V]%t\f[R] in the file name expands to the JVM\[aq]s PID and -startup timestamp, respectively. +When using \f[V]file=\f[R]\f[I]filename\f[R], specifying \f[V]%p\f[R], +\f[V]%t\f[R] and/or \f[V]%hn\f[R] in the file name expands to the +JVM\[aq]s PID, startup timestamp and host name, respectively. You can also configure text files to handle file rotation based on file size and a number of files to rotate. For example, to rotate the log file every 10 MB and keep 5 files in