如何禁用Rails/Unicorn默认输出的请求访问日志
问题场景
- 运行环境:Rails v5.2.6 应用,部署在Unicorn应用服务器上
- 故障现象:日志被大量固定格式的请求日志刷屏,严重干扰正常问题排查,示例日志如下:
24.33.33.243, 12.0.52.41 - - [26/Jun/2022:13:43:39 +0000] "GET /our_path HTTP/1.1" 200 - 0.0078
- 现有措施:已自定义
Rails.logger通过正则规则过滤部分冗余日志,但这类请求日志走独立输出链路,未被现有规则拦截。
日志来源定位
这类日志是Rack层默认的Rack::CommonLogger中间件输出的标准访问日志,不经过Rails.logger链路,所以Rails侧配置的日志过滤规则对它无效。
Unicorn启动Rails应用时会默认注入该中间件,按Apache通用日志格式打印每一条请求记录;日志开头出现两个IP,是因为前端反向代理(Nginx、负载均衡等)通过X-Forwarded-For头传递了客户端真实IP,和示例日志格式完全匹配。
可落地方案
根据实际需求二选一即可:
方案1:直接关闭Unicorn层访问日志(推荐)
绝大多数架构下前端反向代理已经会记录全量访问日志,Unicorn层重复打印属于纯冗余输出,直接关闭即可:
- 编辑Rails应用配置
config/application.rb,删除默认的CommonLogger中间件:
config.middleware.delete ::Rack::CommonLogger
- 编辑Unicorn配置文件(通常路径为
config/unicorn.rb),禁止Unicorn自动注入日志中间件:
preload_app true # 配置Unicorn自身日志输出到标准输出,不绑定访问日志逻辑 logger Logger.new($stdout)
- 重启Unicorn服务生效。
如果重启后仍有同类日志输出,在项目根目录执行bundle exec rake middleware RAILS_ENV=你的运行环境,打印全量加载的中间件列表,搜索Rack::CommonLogger定位注入来源,删除对应注入配置即可。
方案2:保留访问日志,仅过滤指定路径的冗余记录
如果需要保留其他路径的Unicorn层访问日志,可以自定义带过滤规则的日志中间件替换默认实现:
- 新建中间件文件
app/middleware/filtered_access_logger.rb:
class FilteredAccessLogger # 填入需要过滤的请求路径 FILTER_PATHS = %w[/our_path /ping /health_check].freeze def initialize(app, log_target = nil) @app = app @logger = log_target || Logger.new(STDOUT) end def call(env) start_time = Time.now status, headers, response = @app.call(env) headers = Rack::Utils::HeaderHash.new(headers) # 命中过滤规则则跳过日志打印 unless FILTER_PATHS.include?(env['PATH_INFO']) @logger.info(format_log(env, status, start_time)) end [status, headers, response] end private def format_log(env, status, start_time) client_ip = env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR'] log_time = Time.now.strftime('%d/%b/%Y:%H:%M:%S %z') request_line = "#{env['REQUEST_METHOD']} #{env['PATH_INFO']} #{env['HTTP_VERSION']}" cost_seconds = (Time.now - start_time).round(4) "#{client_ip} - - [#{log_time}] \"#{request_line}\" #{status} - #{cost_seconds}" end end
- 修改
config/application.rb,替换默认访问日志中间件:
# 删除原有默认访问日志中间件 config.middleware.delete ::Rack::CommonLogger # 加载自定义过滤版日志中间件 config.middleware.use FilteredAccessLogger, Rails.logger
- 重启Unicorn服务生效,指定路径的请求日志将不再输出,其余路径日志保持原有格式不变。
内容的提问来源于stack exchange,提问作者nadavgam
相关产品推荐
相关产品推荐

