首页 分类 关于我
ruby
Nginx 配置示例 工程师的产品观 理理File/Dir/Pathname(一) TracePoint介绍 ruby中的return 如何动态改变某个class的祖先链 ObjectSpace介绍 Rails日志实现探索(3) Rails日志实现探索(2) Rails日志实现探索(1) Rails中的request rescue exception in ruby 设计模式之观察者模式 require 的故事 ruby中的编码 研究ruby的一些小技巧 Rails中间件 ruby对象的序列化 ActiveSupport宝藏之MessageVerifier 如何写rakefile Ruby on Rails 环境及准备 基于Rack的项目初始化
git
如何移除某次提交之前的版本历史 Git 不常用的好用的命令 Git高级技巧之忽略文件
database
Mysql数据库编码 从mongodb向mysql迁移数据
工具
搭建ipsec服务
linux
Linux 常用查看命令

Rails日志实现探索(1)

概述

我一直很好奇在Rails中,日志是如何记录一个Rails App运行的信息的。我查看了一下Rails的中间件,发现了Rails::Rack::Logger

# rake middleware
...
use Rack::MethodOverride
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
...

查看Rails::Rack::Logger中实现记录日志的主要代码,发现了两个奇怪的类:ActiveSupport::Notifications和ActiveSupport::LogSubscriber

def call_app(request, env)
  # ...
  instrumenter = ActiveSupport::Notifications.instrumenter
  instrumenter.start 'request.action_dispatch', request: request
  logger.info { started_request_message(request) }
  resp = @app.call(env)
  resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
  resp
rescue Exception
  finish(request)
  raise
ensure
  ActiveSupport::LogSubscriber.flush_all!
end

日志功能实现

Rails中对日志的处理采用的是“消息-订阅”机制,各部分组件和功能如下:

  • 消息发送:ActiveSupport::Notifications
    • instrument: 通知subscribers
  • 消息订阅:ActiveSupport::LogSubscriber

© 2018 www.xinshengyin.com All rights reserved.

版权所有