From 8a9b21e2c99b72a614ca6d00c155f3c0957b0ae0 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Wed, 12 Nov 2025 11:01:22 +0100 Subject: [PATCH 1/3] Use casecmp? --- lib/proxy/log.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/proxy/log.rb b/lib/proxy/log.rb index 0b413fb6c..92c0b4025 100644 --- a/lib/proxy/log.rb +++ b/lib/proxy/log.rb @@ -25,16 +25,16 @@ def self.logger layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.file_logging_pattern + "\n") notime_layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.system_logging_pattern + "\n") logger = Logging.logger.root - if log_file.casecmp('STDOUT').zero? + if log_file.casecmp?('STDOUT') logger.add_appenders(Logging.appenders.stdout(logger_name, layout: layout)) - elsif log_file.casecmp('SYSLOG').zero? + elsif log_file.casecmp?('SYSLOG') unless syslog_available? puts "Syslog is not supported on this platform, use STDOUT or a file" exit(1) end logger.add_appenders(Logging.appenders.syslog( logger_name, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5)) - elsif log_file.casecmp('JOURNAL').zero? || log_file.casecmp('JOURNALD').zero? + elsif log_file.casecmp?('JOURNAL') || log_file.casecmp?('JOURNALD') begin logger.add_appenders(Logging.appenders.journald( logger_name, logger_name: :proxy_logger, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5)) From 017b3e44c9419662b013b21c6bf7e83074a72f86 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Wed, 12 Nov 2025 11:09:39 +0100 Subject: [PATCH 2/3] Factor out appender creation --- lib/proxy/log.rb | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/lib/proxy/log.rb b/lib/proxy/log.rb index 92c0b4025..3076cc652 100644 --- a/lib/proxy/log.rb +++ b/lib/proxy/log.rb @@ -21,39 +21,31 @@ class LoggerFactory end def self.logger - logger_name = 'foreman-proxy' - layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.file_logging_pattern + "\n") - notime_layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.system_logging_pattern + "\n") logger = Logging.logger.root if log_file.casecmp?('STDOUT') - logger.add_appenders(Logging.appenders.stdout(logger_name, layout: layout)) + logger.add_appenders(appender(:stdout)) elsif log_file.casecmp?('SYSLOG') unless syslog_available? puts "Syslog is not supported on this platform, use STDOUT or a file" exit(1) end - logger.add_appenders(Logging.appenders.syslog( - logger_name, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5)) + logger.add_appenders(appender(:syslog)) elsif log_file.casecmp?('JOURNAL') || log_file.casecmp?('JOURNALD') begin - logger.add_appenders(Logging.appenders.journald( - logger_name, logger_name: :proxy_logger, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5)) + logger.add_appenders(appender(:journald)) rescue NoMethodError - logger.add_appenders(Logging.appenders.stdout(logger_name, layout: layout)) + logger.add_appenders(appender(:stdout)) logger.warn "Journald is not available on this platform. Falling back to STDOUT." end else begin - keep = ::Proxy::SETTINGS.file_rolling_keep - size = BASE_LOG_SIZE * ::Proxy::SETTINGS.file_rolling_size - age = ::Proxy::SETTINGS.file_rolling_age - if size > 0 - logger.add_appenders(Logging.appenders.rolling_file(logger_name, layout: layout, filename: log_file, keep: keep, size: size, age: age, roll_by: 'date')) + if ::Proxy::SETTINGS.file_rolling_size.to_i > 0 + logger.add_appenders(appender(:rolling_file)) else - logger.add_appenders(Logging.appenders.file(logger_name, layout: layout, filename: log_file)) + logger.add_appenders(appender(:file)) end rescue ArgumentError => ae - logger.add_appenders(Logging.appenders.stdout(logger_name, layout: layout)) + logger.add_appenders(appender(:stdout)) logger.warn "Log file #{log_file} cannot be opened. Falling back to STDOUT: #{ae}" end end @@ -68,6 +60,28 @@ def self.syslog_available? def self.log_file @log_file ||= ::Proxy::SETTINGS.log_file end + + def self.appender(variant) + logger_name = 'foreman-proxy' + layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.file_logging_pattern + "\n") + notime_layout = Logging::Layouts.pattern(pattern: ::Proxy::SETTINGS.system_logging_pattern + "\n") + + case variant + when :stdout + Logging.appenders.stdout(logger_name, layout: layout) + when :syslog + Logging.appenders.syslog(logger_name, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5) + when :journald + Logging.appenders.journald(logger_name, logger_name: :proxy_logger, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5) + when :rolling_file + keep = ::Proxy::SETTINGS.file_rolling_keep + size = BASE_LOG_SIZE * ::Proxy::SETTINGS.file_rolling_size + age = ::Proxy::SETTINGS.file_rolling_age + Logging.appenders.rolling_file(logger_name, layout: layout, filename: log_file, keep: keep, size: size, age: age, roll_by: 'date') + when :file + Logging.appenders.file(logger_name, layout: layout, filename: log_file) + end + end end class LoggerMiddleware From 48fdd4fd5569d02d7a0751130dc1d6eab5f18d6d Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Wed, 12 Nov 2025 11:15:12 +0100 Subject: [PATCH 3/3] Implement AUTO logging output --- lib/proxy/log.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/proxy/log.rb b/lib/proxy/log.rb index 3076cc652..dd24d9c3b 100644 --- a/lib/proxy/log.rb +++ b/lib/proxy/log.rb @@ -22,7 +22,22 @@ class LoggerFactory def self.logger logger = Logging.logger.root - if log_file.casecmp?('STDOUT') + if log_file.casecmp?('AUTO') + if ENV.key?('JOURNAL_STREAM') + # https://systemd.io/JOURNAL_NATIVE_PROTOCOL/#automatic-protocol-upgrading + # TODO: catch if unavailable + logger.add_appenders(appender(:journald)) + elsif ENV.key?('LOGS_DIRECTORY') + # If LogsDirectory in systemd unit is provided + # TODO: does log_file respect LOGS_DIRECTORY? + # TODO: rolling file or expect logrotate? + logger.add_appenders(appender(:file)) + elsif syslog_available? + logger.add_appenders(appender(:syslog)) + else + logger.add_appenders(appender(:stdout)) + end + elsif log_file.casecmp?('STDOUT') logger.add_appenders(appender(:stdout)) elsif log_file.casecmp?('SYSLOG') unless syslog_available?