Rails.event.notify(…) 도입 배경 및 기능
기존 문제점: ActiveSupport::Notifications와 파편화된 계측
Rails 애플리케이션에 관측 가능성을 추가하려 할 때 ActiveSupport::Notifications API를 사용하게 됩니다. 이 API는 유연하지만, 다음과 같은 문제점을 야기합니다:
-
상용구 코드: 이벤트 발행 및 처리에 필요한 반복적인 코드.
-
일관성 부족: 프로젝트마다 다른 방식으로 구현되어 일관된 계측이 어려움.
-
벤더 종속성: Datadog, AppSignal 등 서드파티 서비스는 자체 컨벤션과 래퍼를 사용하여 단편화된 API와 벤더 종속성을 초래.
Datadog 통합 예시 (기존 방식)
ruby
# config/initializers/datadog.rb
Datadog.configure do |c|
c.instrument :rails
end
ActiveSupport::Notifications.subscribe("checkout.completed") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
Datadog.statsd.increment(
"rails.checkout.completed",
tags: ["order_id:#{event.payload[:order_id]}", "env:#{Rails.env}"]
)
end
Rails 8.1에서는 Rails.event.notify("checkout.completed", order_id: order.id) 호출만으로 Datadog에서 메트릭으로 자동 캡처됩니다.
AppSignal 통합 예시 (기존 방식)
ruby
# config/initializers/appsignal.rb
ActiveSupport::Notifications.subscribe("user.login") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
Appsignal.increment_counter(
"rails.user.login",
1,
user_id: event.payload[:user_id]
)
end
Rails.event.notify("user.login", user_id: current_user.id) 호출 시 AppSignal 대시보드에 커스텀 카운터로 나타납니다.
새로운 API: Rails.event.notify(…)
Rails 8.1은 이벤트 발행을 위한 통합된 새 API를 제공합니다. 이는 Rails의 기본 로거가 인간이 읽기에는 좋지만 사후 처리에 적합하지 않다는 문제점을 해결합니다.
-
구조화된 이벤트 발행:
Rails.event.notify("checkout.completed", order_id: order.id, amount: order.total_cents) -
태그 지원:
Rails.event.tagged("graphql") { Rails.event.notify("user.signup", user_id: 123) } -
컨텍스트 지원:
Rails.event.set_context(request_id: "abc123", shop_id: 456) -
구독자(Subscriber) 모델:
emit메서드를 구현하는 구독자를 통해 이벤트가 직렬화되고 발행 방식을 제어합니다. (예:LogSubscriber)
ruby
class LogSubscriber
def emit(event)
payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
source_location = event[:source_location]
log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
Rails.logger.info(log)
end
end
새로운 API의 주요 특징
-
구조화된 이벤트: 네임스페이스(예:
checkout.completed)별로 정리. -
도구 독립적: Datadog, AppSignal 등 특정 도구에 맞춘 커스텀 코드 불필요.
-
경량성: Rails 내부 알림 시스템 기반으로 가볍게 동작.
-
표준화된 접근 방식: Rails 커뮤니티 전반에 걸쳐 일관된 계측 제공.
관측 가능성 및 AI/데이터 웨어하우스 연동
이 API는 일관된 이벤트 발행을 통해 APM 도구와의 원활한 통합을 제공하고, 애플리케이션 수준 이벤트와 하위 수준 메트릭 간의 상관관계를 분석하여 성능 통찰력을 향상시킵니다. 또한, 명확하고 체계적인 이벤트 발행은 AI 도구, 분석 시스템, 대규모 데이터 저장소에 유용한 데이터를 제공하여 자동화, 패턴 발견, 의사 결정 지원에 기여합니다.
이벤트 설계 모범 사례
-
명확한 네임스페이스:
resource.action형식(예:checkout.completed). -
최소한의 페이로드: ID, 금액, 상태 등 필수 정보만 포함하고 민감 정보는 제외.
-
고가치 이벤트 집중: 모든 이벤트 대신 중요한 이벤트에 집중.
-
헬퍼 메서드 활용: 일관된 코드베이스를 위해 알림을 헬퍼 메서드로 래핑.
ruby
module Instrumentation
def self.checkout_completed(order)
Rails.event.notify("checkout.completed", order_id: order.id, amount: order.total_cents)
end
end