8327410: Add hostname option for UL file names
Reviewed-by: jsjolen, dholmes
This commit is contained in:
parent
21867c929a
commit
f3db2796b8
@ -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:");
|
||||||
|
@ -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;
|
||||||
|
@ -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];
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user