首页 分类 关于我
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日志实现探索(2)

日志功能实现

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

日志消息的发送:ActiveSupport::Notifications

  • instrument: 通知所有的 subscribers

扩展:可在通知前先执行一个代码块;

ActiveSupport::Notifications.instrument('render', extra: :information) do
  render text: 'Foo'
end
  • ActiveSupport::Notifications::Instrumenter: 下发通知的组织

  • ActiveSupport::Notifications::Fanout: 下发通知的执行人

工作流程

安排下发通知的人

# 1、每个事件分配一个执行人员(员工)
ActiveSupport::Notifications.notifier = ActiveSupport::Notifications::Fanout.new

# 2、不能瞎指派员工,指派的员工须得有这个能力
if notifier.listening?(name)
  instrumenter.instrument(name, payload) { yield payload if block_given? }
end

# 3、通过员工的上级领导(cto)分配工作
def instrumenter
  InstrumentationRegistry.instance.instrumenter_for(notifier)
end

具体工作

1、Instrumenter安排工作

# Send a start notification with +name+ and +payload+.
def start(name, payload)
  @notifier.start name, @id, payload
end

# Send a finish notification with +name+ and +payload+.
def finish(name, payload)
  @notifier.finish name, @id, payload
end

2、Fanout 接受任务开始干活

def start(name, id, payload)
  listeners_for(name).each { |s| s.start(name, id, payload) }
end

def finish(name, id, payload)
  listeners_for(name).each { |s| s.finish(name, id, payload) }
end

def publish(name, *args)
  listeners_for(name).each { |s| s.publish(name, *args) }

  # s 为`ActiveSupport::Notifications::Fanout::Subscribers::Evented`实例
end

干活的人多了个publish方法,反馈任务(员工需要汇报工作)

3、ActiveSupport::Notifications::Fanout::Subscribers::Evented 具体的任务

def publish(name, *args)
  if @can_publish
    @delegate.publish name, *args
  end
end

def start(name, id, payload)
  @delegate.start name, id, payload
end

def finish(name, id, payload)
  @delegate.finish name, id, payload
end

delegate 这个又是谁呢?

答案揭晓

其实这个员工他也不干活,他将工作外包出去了!!!

© 2018 www.xinshengyin.com All rights reserved.

版权所有