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 这个又是谁呢?
答案揭晓
其实这个员工他也不干活,他将工作外包出去了!!!