New logger configuration (#3813)

This commit is contained in:
Marc
2025-12-20 19:00:34 +01:00
committed by GitHub
parent 5cbf1e0785
commit cf6761156c
6 changed files with 186 additions and 56 deletions

View File

@@ -77,15 +77,68 @@ The openj9 image tags include specific variables to simplify configuration:
- `-e TUNE_NURSERY_SIZES=TRUE` : configures nursery sizes where the initial size is 50%
of the `MAX_MEMORY` and the max size is 80%.
## Enabling rolling logs
## Customizing log4j2 configuration
By default the vanilla log file will grow without limit. The logger can be reconfigured to use a rolling log files strategy by using:
The image now uses a templated log4j2 configuration based on PaperMC's logging setup, which is automatically applied for versions that don't require Log4j security patches. This configuration provides rolling logs and advanced logging features by default.
### Customization via environment variables
You can customize various aspects of the logging behavior using environment variables:
- `LOG_LEVEL` : Root logger level (default: `info`)
```
-e ENABLE_ROLLING_LOGS=true
-e LOG_LEVEL=debug
```
> **NOTE** this will interfere with interactive/color consoles [as described in the section above](#interactive-and-color-console)
- `ROLLING_LOG_FILE_PATTERN` : Pattern for rolled log file names (default: `logs/%d{yyyy-MM-dd}-%i.log.gz`)
```
-e ROLLING_LOG_FILE_PATTERN="logs/archive/%d{yyyy-MM-dd}-%i.log.gz"
```
- `ROLLING_LOG_MAX_FILES` : Maximum number of archived log files to keep (default: `1000`)
```
-e ROLLING_LOG_MAX_FILES=30
```
### Customizing log message formats
For full control over how log messages are formatted, you can customize the Log4j2 pattern layouts using these variables. These use [Log4j2 Pattern Layout syntax](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout):
- `LOG_CONSOLE_FORMAT` : Format for console output (what you see in `docker logs`)
Default: `[%d{HH:mm:ss}] [%t/%level]: %msg%n`
- `LOG_FILE_FORMAT` : Format for file logs (written to `logs/latest.log`)
Default: `[%d{HH:mm:ss}] [%t/%level]: %msg%n`
- `LOG_TERMINAL_FORMAT` : Format for interactive terminal console (used with `docker attach`)
Default: `[%d{HH:mm:ss} %level]: %msg%n`
### Example configurations
Simple timestamp customization (most common use case):
```yaml
environment:
# What you see in docker logs
LOG_CONSOLE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t/%level]: %msg%n"
# What gets written to logs/latest.log
LOG_FILE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%t/%level]: %msg%n"
```
Advanced customization:
```yaml
environment:
LOG_LEVEL: debug
# Custom ISO8601 format with logger names
LOG_CONSOLE_FORMAT: "%d{ISO8601} %-5level [%t] %logger{36} - %msg%n"
LOG_FILE_FORMAT: "%d{ISO8601} %-5level [%t] %logger{36} - %msg%n"
ROLLING_LOG_MAX_FILES: 50
```
### Legacy ENABLE_ROLLING_LOGS option
The `ENABLE_ROLLING_LOGS` environment variable is no longer needed for most use cases, as rolling logs are now enabled by default through the templated configuration. This option is maintained for backward compatibility but is only checked for error reporting when rolling logs cannot be used due to Log4j security patches.
> **NOTE** The templated log4j2 configuration may interfere with interactive/color consoles [as described in the section above](#interactive-and-color-console)
## Timezone Configuration

View File

@@ -57,9 +57,45 @@ alternatively, you can mount: <code>/etc/localtime:/etc/localtime:ro
<td><code>UTC</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>LOG_LEVEL</code></td>
<td>Root logger level (trace, debug, info, warn, error)</td>
<td><code>info</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>LOG_CONSOLE_FORMAT</code></td>
<td>Log4j2 pattern for console output (what you see in <code>docker logs</code>)</td>
<td><code>[%d{HH:mm:ss}] [%t/%level]: %msg%n</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>LOG_FILE_FORMAT</code></td>
<td>Log4j2 pattern for file logs (written to <code>logs/latest.log</code>)</td>
<td><code>[%d{HH:mm:ss}] [%t/%level]: %msg%n</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>LOG_TERMINAL_FORMAT</code></td>
<td>Log4j2 pattern for interactive terminal console (used with <code>docker attach</code>)</td>
<td><code>[%d{HH:mm:ss} %level]: %msg%n</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>ROLLING_LOG_FILE_PATTERN</code></td>
<td>Pattern for rolled/archived log file names</td>
<td><code>logs/%d{yyyy-MM-dd}-%i.log.gz</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>ROLLING_LOG_MAX_FILES</code></td>
<td>Maximum number of archived log files to keep</td>
<td><code>1000</code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>ENABLE_ROLLING_LOGS</code></td>
<td>By default the vanilla log file will grow without limit. The logger can be reconfigured to use a rolling log files strategy by setting this to <code>true</code></td>
<td><strong>Legacy option.</strong> Rolling logs are now enabled by default via templated log4j2 configuration. This option is maintained for backward compatibility but only used for error reporting</td>
<td><code>false</code></td>
<td>⬜️</td>
</tr>

View File

@@ -110,9 +110,20 @@ services:
####################################################################
# Logging Options #
# #
# Set to "true" to delete old logs #
# Rolling logs are now enabled by default with templated #
# log4j2 configuration. You can customize: #
# #
# LOG_LEVEL: Log level (default: info) #
# LOG_CONSOLE_FORMAT: Console output format (docker logs) #
# LOG_FILE_FORMAT: File log format (logs/latest.log) #
# ROLLING_LOG_MAX_FILES: Max archived files (default: 1000) #
# #
# Example: Add full timestamp to logs #
# LOG_CONSOLE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n"
# LOG_FILE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n"
# #
# ENABLE_ROLLING_LOGS is now legacy and no longer needed. #
####################################################################
ENABLE_ROLLING_LOGS: "true"
####################################################################
# Server Timezone #

View File

@@ -120,9 +120,20 @@ services:
####################################################################
# Logging Options #
# #
# Set to "true" to delete old logs #
# Rolling logs are now enabled by default with templated #
# log4j2 configuration. You can customize: #
# #
# LOG_LEVEL: Log level (default: info) #
# LOG_CONSOLE_FORMAT: Console output format (docker logs) #
# LOG_FILE_FORMAT: File log format (logs/latest.log) #
# ROLLING_LOG_MAX_FILES: Max archived files (default: 1000) #
# #
# Example: Add full timestamp to logs #
# LOG_CONSOLE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n"
# LOG_FILE_FORMAT: "[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n"
# #
# ENABLE_ROLLING_LOGS is now legacy and no longer needed. #
####################################################################
ENABLE_ROLLING_LOGS: "true"
####################################################################
# Server Timezone #

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n" />
</Console>
<Queue name="TerminalConsole">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss} %level]: %msg%n" />
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%t/%level]: %msg%n" />
<Policies>
<!-- Based on filePattern resolution, so daily -->
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="100 MB" />
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="logs">
<IfFileName glob="*.log.gz" />
<IfLastModified age="7d" />
<IfAccumulatedFileCount exceeds="20"/>
</Delete>
</DefaultRolloverStrategy>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="info">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole"/>
</Root>
</Loggers>
</Configuration>

View File

@@ -103,21 +103,77 @@ elif versionLessThan 1.18.1; then
fi
fi
if isTrue "${ENABLE_ROLLING_LOGS:-false}"; then
if ! ${canUseRollingLogs}; then
# Set up log4j2 configuration with templating support
if ${canUseRollingLogs}; then
# Set up log configuration defaults
: "${LOG_LEVEL:=info}"
: "${ROLLING_LOG_MAX_FILES:=1000}"
# Note: Can't use ${VAR:=default} syntax for values containing } as it breaks parsing
if [ -z "${ROLLING_LOG_FILE_PATTERN}" ]; then
ROLLING_LOG_FILE_PATTERN='logs/%d{yyyy-MM-dd}-%i.log.gz'
fi
# Pattern format defaults (compatible with vanilla Minecraft)
# Note: Can't use ${VAR:=default} syntax because } in the value breaks parsing
if [ -z "${LOG_CONSOLE_FORMAT}" ]; then
LOG_CONSOLE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
if [ -z "${LOG_TERMINAL_FORMAT}" ]; then
LOG_TERMINAL_FORMAT='[%d{HH:mm:ss} %level]: %msg%n'
fi
if [ -z "${LOG_FILE_FORMAT}" ]; then
LOG_FILE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
export LOG_LEVEL ROLLING_LOG_FILE_PATTERN ROLLING_LOG_MAX_FILES
export LOG_CONSOLE_FORMAT LOG_TERMINAL_FORMAT LOG_FILE_FORMAT
LOGFILE="${SERVER_DIR}/log4j2.xml"
# Always regenerate if file doesn't exist or REGENERATE_LOG4J2 is set
if [ ! -e "$LOGFILE" ] || isTrue "${REGENERATE_LOG4J2:-false}"; then
log "Generating log4j2.xml from template in ${LOGFILE}"
# Generate log4j2.xml using heredoc for reliable variable substitution
cat > "$LOGFILE" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_CONSOLE_FORMAT}" />
</Console>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="${ROLLING_LOG_FILE_PATTERN}">
<PatternLayout pattern="${LOG_FILE_FORMAT}" />
<Policies>
<TimeBasedTriggeringPolicy />
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="${ROLLING_LOG_MAX_FILES}"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="${LOG_LEVEL}">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole"/>
</Root>
</Loggers>
</Configuration>
EOF
else
log "log4j2.xml already exists and is up to date, skipping generation"
fi
# Apply the log4j2 configuration
JVM_OPTS="-Dlog4j.configurationFile=log4j2.xml ${JVM_OPTS}"
elif isTrue "${ENABLE_ROLLING_LOGS:-false}"; then
# Legacy behavior: error if rolling logs explicitly requested but not possible
logError "Using rolling logs is currently not possible in the selected version due to CVE-2021-44228"
exit 1
fi
# Set up log configuration
LOGFILE="${SERVER_DIR}/log4j2.xml"
if [ ! -e "$LOGFILE" ]; then
log "Creating log4j2.xml in ${LOGFILE}"
cp /image/log4j2.xml "$LOGFILE"
else
log "log4j2.xml already created, skipping"
fi
JVM_OPTS="-Dlog4j.configurationFile=log4j2.xml ${JVM_OPTS}"
fi
# Optional disable console
if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then