8327410: Add hostname option for UL file names

Reviewed-by: jsjolen, dholmes
This commit is contained in:
Fredrik Bredberg 2024-04-04 15:28:46 +00:00 committed by Jesper Wilhelmsson
parent 21867c929a
commit f3db2796b8
4 changed files with 61 additions and 58 deletions

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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("Available log outputs:");
out->print_cr(" stdout/stderr"); out->print_cr(" stdout/stderr");
out->print_cr(" file=<filename>"); out->print_cr(" file=<filename>");
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->cr();
out->print_cr("Available log output options:"); out->print_cr("Available log output options:");

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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::PidFilenamePlaceholder = "%p";
const char* const LogFileOutput::TimestampFilenamePlaceholder = "%t"; const char* const LogFileOutput::TimestampFilenamePlaceholder = "%t";
const char* const LogFileOutput::TimestampFormat = "%Y-%m-%d_%H-%M-%S"; 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::FileSizeOptionKey = "filesize";
const char* const LogFileOutput::FileCountOptionKey = "filecount"; const char* const LogFileOutput::FileCountOptionKey = "filecount";
char LogFileOutput::_pid_str[PidBufferSize]; char LogFileOutput::_pid_str[PidBufferSize];
@ -378,81 +379,81 @@ void LogFileOutput::rotate() {
char* LogFileOutput::make_file_name(const char* file_name, char* LogFileOutput::make_file_name(const char* file_name,
const char* pid_string, const char* pid_string,
const char* timestamp_string) { const char* timestamp_string) {
char hostname_string[HostnameBufferSize];
char* result = nullptr; 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 // We will only replace the first occurrence of any placeholder
const char* pid = strstr(file_name, PidFilenamePlaceholder); const char* pid = strstr(file_name, PidFilenamePlaceholder);
const char* timestamp = strstr(file_name, TimestampFilenamePlaceholder); 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 // We found no place-holders, return the simple filename
return os::strdup_check_oom(file_name, mtLogging); return os::strdup_check_oom(file_name, mtLogging);
} }
// At least one of the place-holders were found in the file_name // At least one of the place-holders were found in the file_name
const char* first = ""; size_t result_len = strlen(file_name);
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
if (pid != nullptr) { if (pid != nullptr) {
if (timestamp == nullptr || pid < timestamp) { result_len -= strlen(PidFilenamePlaceholder);
first = pid_string; result_len += strlen(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);
}
} }
if (timestamp != nullptr) { if (timestamp != nullptr) {
if (pid == nullptr || timestamp < pid) { result_len -= strlen(TimestampFilenamePlaceholder);
first = timestamp_string; result_len += strlen(timestamp_string);
first_pos = timestamp - file_name; }
first_replace_len = strlen(TimestampFilenamePlaceholder); if (hostname != nullptr) {
} else { if (!os::get_host_name(hostname_string, sizeof(hostname_string))) {
second = timestamp_string; int res = jio_snprintf(hostname_string, sizeof(hostname_string), "unknown-host");
second_pos = timestamp - file_name; assert(res > 0, "Hostname buffer too small");
second_replace_len = strlen(TimestampFilenamePlaceholder); }
} 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. // 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); result = NEW_C_HEAP_ARRAY(char, result_len + 1, mtLogging);
// Assemble the strings // Assemble the strings
size_t file_name_pos = 0; size_t file_name_pos = 0;
size_t i = 0; size_t i = 0;
while (i < result_len) { while (i < result_len) {
if (file_name_pos == first_pos) { if (file_name[file_name_pos] == '%') {
// We are in the range of the first placeholder // Replace the first occurrence of any placeholder
strcpy(result + i, first); if (pid != nullptr && strncmp(&file_name[file_name_pos],
// Bump output buffer position with length of replacing string PidFilenamePlaceholder,
i += first_len; strlen(PidFilenamePlaceholder)) == 0) {
// Bump source buffer position to skip placeholder strcpy(result + i, pid_string);
file_name_pos += first_replace_len; i += strlen(pid_string);
} else if (file_name_pos == second_pos) { file_name_pos += strlen(PidFilenamePlaceholder);
// We are in the range of the second placeholder pid = nullptr;
strcpy(result + i, second); continue;
i += second_len; }
file_name_pos += second_replace_len; if (timestamp != nullptr && strncmp(&file_name[file_name_pos],
} else { TimestampFilenamePlaceholder,
// Else, copy char by char of the original file strlen(TimestampFilenamePlaceholder)) == 0) {
result[i] = file_name[file_name_pos++]; strcpy(result + i, timestamp_string);
i++; 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 // Add terminating char
result[result_len] = '\0'; result[result_len] = '\0';
return result; return result;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 PidFilenamePlaceholder;
static const char* const TimestampFilenamePlaceholder; static const char* const TimestampFilenamePlaceholder;
static const char* const TimestampFormat; static const char* const TimestampFormat;
static const char* const HostnameFilenamePlaceholder;
static const size_t DefaultFileCount = 5; static const size_t DefaultFileCount = 5;
static const size_t DefaultFileSize = 20 * M; static const size_t DefaultFileSize = 20 * M;
static const size_t StartTimeBufferSize = 20; static const size_t StartTimeBufferSize = 20;
static const size_t PidBufferSize = 21; static const size_t PidBufferSize = 21;
static const size_t HostnameBufferSize = 512;
static const uint MaxRotationFileCount = 1000; static const uint MaxRotationFileCount = 1000;
static char _pid_str[PidBufferSize]; static char _pid_str[PidBufferSize];
static char _vm_start_time_str[StartTimeBufferSize]; static char _vm_start_time_str[StartTimeBufferSize];

View File

@ -4308,9 +4308,9 @@ The \f[V]-Xlog\f[R] option supports the following types of outputs:
.IP \[bu] 2 .IP \[bu] 2
\f[V]file=\f[R]\f[I]filename\f[R] --- Sends output to text file(s). \f[V]file=\f[R]\f[I]filename\f[R] --- Sends output to text file(s).
.PP .PP
When using \f[V]file=\f[R]\f[I]filename\f[R], specifying \f[V]%p\f[R] 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 \f[V]%t\f[R] and/or \f[V]%hn\f[R] in the file name expands to the
startup timestamp, respectively. JVM\[aq]s PID, startup timestamp and host name, respectively.
You can also configure text files to handle file rotation based on file You can also configure text files to handle file rotation based on file
size and a number of files to rotate. size and a number of files to rotate.
For example, to rotate the log file every 10 MB and keep 5 files in For example, to rotate the log file every 10 MB and keep 5 files in