環境: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