ActiveSupport::Notificationsは、レールベースの通知システムです。 Railsで特定の通知をサブスクライブし、送信時にコードを呼び出すことができます。 これは
ActiveSupport::Callbacks多少似ていますが、プロジェクト全体で機能し、イベントを事前に通知する必要はありません。
たとえば、通知
'render'サブスクライブでき
'render' 。
ActiveSupport::Notifications.subscribe("render") do |*args|
正規表現を通知の名前として使用し、その表現に一致するすべての通知をサブスクライブできます。 すべての通知をサブスクライブする場合は、
subscribeメソッドに何も渡さないでください。
subscribeメソッドは、サブスクライバーへのリンクを返します;通知のサブスクリプションを解除する必要がある場合があります。
ActiveSupport::Notifications.publishメソッドを使用して通知を送信できます。
ActiveSupport::Notifications.publish('render', 'arg1', 'arg2')
subscribeブロックでは、
'render' 、
'arg1' 、および
'arg2'が渡されます。
これらの機能を直接使用するRailsのコードは見つかりませんでした。おそらく、この機能はフレームワークのユーザーがアプリケーションタスクに使用するはずです。 しかし、
ActiveSupport::Notificationsには非常に便利な
instrumentメソッドがあります。 ブロックを受信すると、ブロック実行の開始と終了のタイムスタンプと、追加データを含むハッシュを含む通知を送信します。 Railsはこのメカニズムを使用し、間接的に、
subscribeおよび
publishメソッドを使用して開発環境で詳細なログを作成します(本番環境では同じ「メーター」が使用されますが、すべてがログに書き込まれるわけではありません)
同じ目的で、これらの「メーター」をアプリケーションで使用できます。 このメソッドでチェックインするコードをラップし、実行結果をログに書き込むことができます。 たとえば、追跡したい実行速度のメソッドがあります。
def do_something
ActiveSupport::Notifications.instrumentブロックでラップするだけです
def do_something ActiveSupport::Notifications.instrument('benchmark.do_something', desc: 'Some description') do
config/initializers/benchmarking.rbなどの場所では、
'benchmark.'という行ですべての通知
config/initializers/benchmarking.rbサブスクライブし
'benchmark.' 。
logger = Logger.new(File.join(Rails.root, 'log', "benchmarks.log")) ActiveSupport::Notifications.subscribe(%r/benchmark\.*/) do |name, start, ending, transaction_id, payload| method = name.split(?.).last duration = (1000.0 * (ending - start)) message = if payload[:exception].present? payload[:exception].join(' ') else payload[:desc].to_s end logger.info("Benchmark:%s: %.0fms - %s" % method, duration, message) end
次の変数がブロックに転送されます:
name, start, ending, transaction_id, payload 。
- name-キャッチされた通知の名前
startブロックのstart時間ending -ブロック実行終了時間transaction_id一意のID、通常は同じスレッド内で一意payload -「メーター」に送信される追加データ
次に、実行時間をログに書き込みます。 例外が発生した場合、
payload[:exception]は、例外の名前とエラーメッセージを含む配列を記録します。 これも考慮に入れる必要があります。
ActiveSupport::Notifications Railsロギングの
ActiveSupport::Notifications役割の詳細については、
ActiveSupport::LogSubscriber 、
ActiveRecord::LogSubscriber 、
ActionController::LogSubscriberおよび
ActionMailer::LogSubscriber 。
一時的に通知をサブスクライブする別のメソッドがありますが、それに渡されたブロックが実行されている間のみです。
callback = lambda do|*args|
イベントのサブスクリプ
unsubscribeするには、
unsubscribeメソッドを呼び出して、サブスクライバーリンクを渡します。
ActiveSupport::Notifications.unsubscribe(subscriber)
通知配信メカニズム自体は、
ActiveSupport::Notifications::Fanoutに隠されています
ActiveSupport::Notifications::Instrumenterクラスを見ると興味深いでしょう。このクラスは、
instrumentメソッドでブロックの実行時間を測定する役割を果たします。
例として、
ActiveSupport::Notificationsを使用してメソッドの実行時間をリアルタイムで計算するための
ActiveSupport::Notifications :
class Module def benchmark_it *names options, names = benchmark_options_and_names(*names) names.each do |name| target, punctuation = name.to_s.sub(/([?!=])$/, ''), $1 define_method "
このように使用します:
class MyClass def my_method
これは何のためですか? 同じRailsの例を使用すると、コードが異なる疎結合コンポーネントで構成されている場合、そのような通知を使用してそれらとの対話を確立できることがわかります。 したがって、ORMまたは他のライブラリ(
MyORMなど)を
MyORMして、
MyORM::LogSubscriberから継承した
MyORM::LogSubscriberクラスにロギングタスクを
ActiveSupport::LogSubscriberます。 ログの表示を担当するメッセージコードはアプリケーションによって塗りつぶされませんが、1か所にあります。 もちろん、ライブラリ全体にセンサーを配置する必要があります。 ちなみに、これらの同じセンサーは、ロギング以外のあらゆるものに使用できます。
一方で、私のコードはRailsに結び付けられておらず、一方で、Railsはライブラリについても何も知りませんが、それにもかかわらず、私のgemは共通のロギングシステムに接続されています。
当然、ロギングは通知のアプリケーションの唯一の領域ではありませんが、この例では通知が必要な理由を簡単に示すことができます。