読者です 読者をやめる 読者になる 読者になる

Rails でリクエストの HTTP ヘッダを取得してログに出力する

rails

環境:rails 4.2.0

Rails でリクエストの HTTP ヘッダはrequest.headersから取得できる。

すべてログに出力するなら

# すべてログに出力する
request.headers.sort.map { |k, v| logger.info "#{k}:#{v}" }

個別に取得するなら

# ユーザーエージェントを取得する
request.headers[:HTTP_USER_AGENT]

request.envからでも取得できる。

# ユーザーエージェントを取得する
request.env['HTTP_USER_AGENT']

今回やりたいことはクライアント側から HTTP ヘッダに API のバージョンを埋め込んでリクエストしてくるので、すべてのリクエストの API バージョンを取り出してログに出力したい。

リクエストのパラメータを curl で再現すると以下のようなかんじ。

curl localhost:3000 -H 'API_VERSION: 1.0'

共通処理として書きたいのでapplication_controllerのフィルタで書く。
HTTP ヘッダのパラメータ名にはHTTP_という prefix が自動的に付与されるようなので忘れずに追加する。

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception

  before_action :http_header_log

  private

    def http_header_log
      logger.info("api_version:#{request.headers[:HTTP_API_VERSION]}")
    end

end

これですべてのリクエストに対してログ出力できるようになった。

Lograge を使う

続いてlogrageという gem を使って HTTP ヘッダを出力する方法もやってみた。

roidrage/lograge
https://github.com/roidrage/lograge

この gem は Rails のログ出力フォーマットをカスタマイズするもの。
Rails のデフォルトのログは複数行出力されるが、これを使うと Apache のように1リクエスト毎1行で出力されるようになるので見やすい。

gem 追加

gem 'lograge'

反映させたい環境の config に以下を追加すればOK。

# config/environments/production.rb

    config.lograge.enabled = true

今回は HTTP ヘッダのAPI_VERSIONをログ出力に追加するため、さらに以下の設定を追加する。

まずappend_info_to_payloadメソッドを追加し、そこで HTTP ヘッダよりAPI_VERSIONを取得してpayloadハッシュに入れる。

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception

  def append_info_to_payload(payload)
    super

    payload[:api_version] = request.headers[:HTTP_API_VERSION]
  end

end

そして config にcustom_optionsでログ出力に追加するものを指定する。
timeはデフォルトで表示されないのでこれも追加しておく。

# config/environments/production.rb

    config.lograge.enabled = true

    config.lograge.custom_options = lambda do |event|
      {:time => event.time, :api_version => event.payload[:api_version]}
    end

これで以下のようにログ出力されるようになった。

method=GET path=/ format=*/* controller=articles action=index status=200 duration=88.37 view=87.28 db=0.11 time=2015-02-01 17:39:35 +0900 api_version=1.0