diff --git a/docs/configuration/misc-options.md b/docs/configuration/misc-options.md index d562f97d..717e8ca1 100644 --- a/docs/configuration/misc-options.md +++ b/docs/configuration/misc-options.md @@ -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. -``` - -e ENABLE_ROLLING_LOGS=true +### Customization via environment variables + +You can customize various aspects of the logging behavior using environment variables: + +- `LOG_LEVEL` : Root logger level (default: `info`) + ``` + -e LOG_LEVEL=debug + ``` + +- `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" ``` -> **NOTE** this will interfere with interactive/color consoles [as described in the section above](#interactive-and-color-console) +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 diff --git a/docs/variables.md b/docs/variables.md index 53889a84..275da66d 100644 --- a/docs/variables.md +++ b/docs/variables.md @@ -57,9 +57,45 @@ alternatively, you can mount: /etc/localtime:/etc/localtime:ro UTC ⬜️ + + LOG_LEVEL + Root logger level (trace, debug, info, warn, error) + info + ⬜️ + + + LOG_CONSOLE_FORMAT + Log4j2 pattern for console output (what you see in docker logs) + [%d{HH:mm:ss}] [%t/%level]: %msg%n + ⬜️ + + + LOG_FILE_FORMAT + Log4j2 pattern for file logs (written to logs/latest.log) + [%d{HH:mm:ss}] [%t/%level]: %msg%n + ⬜️ + + + LOG_TERMINAL_FORMAT + Log4j2 pattern for interactive terminal console (used with docker attach) + [%d{HH:mm:ss} %level]: %msg%n + ⬜️ + + + ROLLING_LOG_FILE_PATTERN + Pattern for rolled/archived log file names + logs/%d{yyyy-MM-dd}-%i.log.gz + ⬜️ + + + ROLLING_LOG_MAX_FILES + Maximum number of archived log files to keep + 1000 + ⬜️ + ENABLE_ROLLING_LOGS - 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 true + Legacy option. Rolling logs are now enabled by default via templated log4j2 configuration. This option is maintained for backward compatibility but only used for error reporting false ⬜️ diff --git a/examples/docker-compose-curseforge-atm7.yaml b/examples/docker-compose-curseforge-atm7.yaml index 7553e95f..1067782f 100644 --- a/examples/docker-compose-curseforge-atm7.yaml +++ b/examples/docker-compose-curseforge-atm7.yaml @@ -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 # diff --git a/examples/docker-compose-forge-bettermcplus b/examples/docker-compose-forge-bettermcplus index 4e86d537..1f6d075e 100644 --- a/examples/docker-compose-forge-bettermcplus +++ b/examples/docker-compose-forge-bettermcplus @@ -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 # diff --git a/files/log4j2.xml b/files/log4j2.xml deleted file mode 100644 index aca0e399..00000000 --- a/files/log4j2.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 5ec470d2..6c89690b 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -103,20 +103,76 @@ elif versionLessThan 1.18.1; then fi fi -if isTrue "${ENABLE_ROLLING_LOGS:-false}"; then - if ! ${canUseRollingLogs}; then - logError "Using rolling logs is currently not possible in the selected version due to CVE-2021-44228" - exit 1 +# 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 - # Set up log configuration + + # 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" - if [ ! -e "$LOGFILE" ]; then - log "Creating log4j2.xml in ${LOGFILE}" - cp /image/log4j2.xml "$LOGFILE" + + # 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 else - log "log4j2.xml already created, skipping" + 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 # Optional disable console