1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails×Datadog】auditsとDatadogを掛け合わせることで調査が楽になった話

Last updated at Posted at 2025-01-15

はじめに

プロダクトの規模が大きくなってモデルのデータが変更される入口が増えてくると、

  • 何の操作によってデータが変更されたのか?
  • 何のController、Actionで変更がされたのか
  • 変更された入口はどこなのか?

というのを特定し辛くなり、不具合やお問い合わせの調査に苦戦します。この記事ではauditsとDatadogを用いて上記問題が特定できるようになり調査が楽になりました。

※audits、Datadogの導入手順については省略します。

auditsとは

RailsのGemで、モデルの変更を監視してくれるライブラリです。
auditsテーブルには誰がその変更を行ったかを記録することができます。
使い方、導入
https://github.com/collectiveidea/audited

※コールバックが発生しない変更やactiverecord-importのようなbulk_insertではauditsにデータは残りませんので注意

auditsテーブルの内容(一部抜粋)

カラム名 説明
id システム内ID
auditable_id 監視先のテーブルのID
auditable_type 監視先のモデル名
user_id 変更を行ったUserのID
action 変更時のアクション名(update、create、destroyなど)
audited_changes 変更内容
request_uuid リクエストのUUID(Datadogでどういう操作で変更されたのかを特定するのに使用)
created_at 変更日時

Datadogについて

Datadogとはインフラ、アプリケーション、及びログを一元的に監視・分析するためのツールです。
https://docs.datadoghq.com/ja/containers/

この記事では主にDatadogのLogsにRailsアプリケーションのログを送信して調査することを前提にします。

RailsのログをDatadogに送信する

DatadogにRailsのログを送信する設定を行います。ドキュメント通りlogrageを使います。
https://docs.datadoghq.com/ja/logs/log_collection/ruby/?tab=lograge

1. Gemをインストールする

gem 'lograge'

2. Docker環境なのでビルドする

docker-compose build
docker-compose up -d

3. logrageの設定をする

app/controllers/application_controller.rb

# frozen_string_literal: true

class ApplicationController < ActionController::Base

  private

  def append_info_to_payload(payload)
    super

    payload[:login_user] = current_user&.id
    payload[:ua] = request.user_agent
    payload[:referer] = request.referer
    payload[:remote_ip] = request.remote_ip
    payload[:request_id] = request.uuid
  end
end

config/initializers/lograge.rbを作成。下記内容を記述します。

Rails.application.configure do
  if Rails.env.production? || Rails.env.staging?
    config.lograge.enabled = true
    config.lograge.formatter = Lograge::Formatters::Json.new

    config.lograge.custom_options = lambda do |event|
      {
        ddtrace: 'rails',
        env: Rails.env,
        ddsource: ['app_name'],
        login_user: event.payload[:login_user], # ユーザーIDが必要であれば
        remote_ip: event.payload[:remote_ip],
        ua: event.payload[:ua],
        referer: event.payload[:referer],
        controller: event.payload[:controller],
        action: event.payload[:action],
        params: event.payload[:params].except('controller', 'action').to_json,
        method: event.payload[:method],
        path: event.payload[:path],
        status: event.payload[:status],
        duration: event.duration,
        time: Time.zone.now,
        request_id: event.payload[:request_id]
      }
    end
  end
end

4. ログの冒頭タグを外す
※ActiveSupport::TaggedLogging はログの頭に勝手にタグを付与するので、ログメッセージが JSON と見做されなくなってしまいます。
config/environments/production.rb

-  config.log_tags = [ :request_id ]
-  config.logger   = ActiveSupport::TaggedLogging.logger(STDOUT)
+  config.logger   = ActiveSupport::Logger.new(STDOUT)

※ステージング環境も同様に設定が必要であれば同様に設定をお願いします。

以上でDataDogにRailsのログを送信する準備が整いました。
DataDogのLogsに下記画像のようなデータが飛んでいることを確認して下さい。

スクリーンショット 2025-01-15 10.37.57.png

調査手順

お客様より例えばあるデータが勝手に変わっているというお問い合わせを受けた際の手順を記載します。

1. auditsよりお問い合わせ内容のデータが変更されたレコードを特定します。
例えばあるユーザーのデータが書き換わっていたというお問い合わせを受けたとします。
下記のようなSQLで特定します。

SELECT
	*
FROM
	audits
WHERE
	audits.auditable_id = 1
	AND audits.auditable_type = 'User'
ORDER BY
	created_at DESC

2. auditsのデータが表示されるので、audited_changesより変更内容を特定。該当のデータのrequest_uuidを控えます。

3. Datadog > Logsの検索窓に下記のように入力して検索します。

@request_id:<uuid>

4. 変更されたログを開きます。

ログより

  • どの画面で(referer)
  • どのController、Actionによって
  • どの環境で(ua)
  • どのユーザーが行ったのか(login_user)

が特定できるようになりました!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?