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.
*
* 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=<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->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.
*
* 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;

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.
*
* 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];

View File

@ -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