17

Rails3でDeviseを使用しています。production.logにcurrent_userの名前を表示したいと思います。

次のようにレールを構成したいと思います。

config.log_tags = [:user_name]
4

12 に答える 12

21

私はこの少しトリッキーですが実用的な解決策を見つけました。

Wardenはユーザー情報をセッションに保存しますが、req.sessionはロギングに使用できません。

したがって、これをconfig/application.rbに追加する必要があります

config.middleware.delete(ActionDispatch::Cookies)
config.middleware.delete(ActionDispatch::Session::CookieStore)
config.middleware.insert_before(Rails::Rack::Logger, ActionDispatch::Session::CookieStore)
config.middleware.insert_before(ActionDispatch::Session::CookieStore, ActionDispatch::Cookies)

次に、ファイルconfig / initializers/logging.rbを作成します

Rails.configuration.log_tags = [
  proc do |req|
    if req.session["warden.user.user.key"].nil?
      "Anonym"
    else
      "user_id:#{req.session["warden.user.user.key"][0][0]}"
    end
  end
]

今、私は匿名のためにこれを見ます:

[Anonym] Served asset ...

そしてこれはユーザーのために:

[user_id:1] Served asset ...
于 2012-06-19T13:33:22.287 に答える
14

私はWojtekKruszewskiのこのソリューションを使用しました:https ://gist.github.com/WojtekKruszewski

プロジェクトにidのみを含めるように少し調整しましたが、基本的には同じです。

# config/application.rb

config.log_tags = [
  ->(req){
    if user_id = WardenTaggedLogger.extract_user_id_from_request(req)
      user_id.to_s
    else
      "?"
    end
  }
]

そして、この初期化子を作成します

# initializers/warden_tagged_logger.rb

module WardenTaggedLogger
  def self.extract_user_id_from_request(req)
    session_key = Rails.application.config.session_options[:key]
    session_data = req.cookie_jar.encrypted[session_key]
    warden_data = session_data["warden.user.user.key"]
    warden_data[0][0]
    rescue
      nil
  end
end
于 2015-01-23T19:26:53.077 に答える
5

2013年3月7日追加:

Rails 4では、encrypted_cookie_storeがデフォルトのセッションストアです。これは、セッションデータにアクセスする方法です。

session_data = req.cookie_jar.signed[ "_qnaire_session" ]

また、新しいアプリではwarden_dataの外観が異なるように見えます。たとえば[[542], "$2a$10$e5aYxr/PIp6OOj8jzE7mke"]、最初のアイテムはユーザーIDです。

これが私の現在のスニペットです:https ://gist.github.com/wojt-eu/5109643

前のバージョン:

これは私が思いついたものです:

config.log_tags = [
  :remote_ip,
  ->(req){
    session_data = req.cookie_jar.signed[ "_qnaire_session" ]
    warden_data = session_data["warden.user.provider_user.key"]
    if warden_data
      '#' + warden_data[1][0].to_s
    else
      "guest"
    end
  }
]

_qnaire_sessioninstance.config.session_options[:key]シングルトンと、またはシングルトンを介して置き換えることができます:Rails.application.config.session_options[:key]

私はProviderUserモデルを持っているので、warden.user.provider_user.key。ユーザーモデルでは、これはだと思いますwarden.user.user.key

面倒ですが、通常の認証プロセスやミドルウェアのスタック順序などには影響しません。一部の更新中に破損した場合は、タグ付けログのみが影響を受けます。これは、開発ログを見ているとすぐにわかります。

于 2012-12-11T11:13:28.453 に答える
3

これは、Rails 5.1でログにタグを付けるために使用するCookie復号化ツールuser_idで、Cookieに保存されています。基本的にsession[:user_id]、生のCookieから同等のコントローラーにアクセスできます

environment / Production.rb:

config.log_tags = [
  :request_id,
  :remote_ip,
  lambda do |req|
    session_data = CookieDecrypter.new(req).session_data
    "user_id:#{session_data['user_id']}"
  end
]

app / models / cookie_decrypter.rb:

class CookieDecrypter
  attr_reader :request

  def initialize(request)
    @request = request
  end

  def session_data
    cookie = request.cookies[session_key]
    return {} unless cookie.present?
    cookie = CGI::unescape(cookie)
    key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
    secret = key_generator.generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len]
    sign_secret = key_generator.generate_key(signed_salt)
    encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
    encryptor.decrypt_and_verify(cookie) || {}
  end

  private

  def session_key
    Rails.application.config.session_options[:key]
  end

  def secret_key_base
    Rails.application.secrets[:secret_key_base]
  end

  def salt
    Rails.application.config.action_dispatch.encrypted_cookie_salt
  end

  def signed_salt
    Rails.application.config.action_dispatch.encrypted_signed_cookie_salt
  end
end
于 2017-06-19T20:14:50.353 に答える
2

Rails::Rack::Logger残念ながら、ログタグは、(ミドルウェアで)要求委任の最初に一度だけ評価されます。この段階ではコントローラーがないため、current_userヘルパーはまだ使用できません。監視員やセッションはまだ設定されていませんが、少なくともcookiejarがあるため、session_idをそこに保存すると、代わりにセッションを復元するか、session_idを直接ログに記録できます。

config.log_tags = [ lambda { |req| req.cookie_jar["_session_id"].to_s } ]

最善の代替策は、ユーザー名をlog_inのCookieに直接保存し、セッションで破棄することだと思います。

config.log_tags = [ lambda { |req| req.cookie_jar["user_name"] || 'Noone' } ]

動作していません:

しかし、deviseを使用する場合は、warden raackミドルウェアを使用するため、env['warden']利用可能である必要があります。試してみてください。

config.log_tags = [ lambda { |req| user = req.env['warden'].user; user && user.name || 'Noone'; } ]

警告がなくても、を介してセッションを利用できるのでenv['rack.session']、ユーザーIDをセッションに保存すると、次のようなことができます。

config.log_tags = [ lambda { |req| user = User.find_by_id(req.env['rack.session']['user_id']); user && user.name || 'Noone'; }
于 2012-05-30T09:01:19.370 に答える
2

これが私が追加したものconfig/initializers/logging.rbです:

Rails.configuration.log_tags = [
  :uuid,   # request UUID
  lambda { |req|
    # Credentials are (currently) in the format of:
    #
    #   <session_hash>::<user_id>
    #
    # So we have to split by '::' to obtain the user_id for logging.
    #
    # This will just output "User: nil" if there is no current session.
    "User: #{req.cookies['user_credentials'].to_s.split('::')[1]}"
  }
]

これはAuthlogic用です。あなたがする必要があることは変わるかもしれないので、あなたは本当に掘り下げて、あなたのデータがあなたにすでに何を公開しているかを見る必要があります。

ステップ1:

reqオブジェクトが利用できるものを確認してください。これをに追加しconfig/initializers/logging.rbます:

Rails.configuration.log_tags = [
  lambda { |req|
    req.inspect
  }
]

次に、ページをヒットして、何がダンプされるかを確認します。

ステップ2:同じ手法を使用して、Cookiejarに十分な情報があるかどうかを確認します。

Rails.configuration.log_tags = [
  lambda { |req|
    req.cookies.inspect
  }
]

(リクエストをヒット)

余談ですが、ユーザー名/メールをログに記録する必要はありません。ユーザーIDで十分です。データベースで検索して、必要な追加のメタデータを取得できます。

于 2012-06-13T21:11:55.063 に答える
2

そして今、完全に異なる何かのために...

https://github.com/roidrage/lograge/issues/23#issuecomment-11709861

Rails 4、最新のDeviseとLogrageでこれを試しました。

于 2013-03-08T10:03:37.667 に答える
2

私にとってほとんどうまくいったのは(Rails 3.2.22.2)、ここからの答えです:http: //benjit.com/rails/logger/2016/02/26/getting-admin-user-into-rails-logfile/

cookie_jarこれは、オブジェクトがに応答することを前提としていますencrypted。しかし、それは私には当てはまりませんでした。最終的に私のために働いたのは次のとおりです。

config/initializers/logging.rb

Rails.configuration.log_tags = [
  lambda { |req|
    session_key = Rails.application.config.session_options[:key]
    session_data = req.cookie_jar.signed[Rails.application.config.session_options[:key] ]
    warden_data = ( session_data["warden.user.user.key"]|| [[]])
    admin_user = warden_data[0][0]
    "u: #{admin_user || 0}"
  }
]
于 2017-03-01T19:42:31.803 に答える
1

@viktortronが初期化時に彼の回答で述べたようにlog_tags、適切なオブジェクトは利用できませんsessionsession_id、リクエストに含まれています。

私の場合のように、_database session_store_を使用している場合は、セッションをアドホックに再構築できます。

session = ActiveRecord::SessionStore::Session.find_by_session_id(request.cookie_jar["_session_id"])

これが私log_tagsの定義方法です。

# config/initializers/rails_log.rb
def get_user_id(req)
  session = ActiveRecord::SessionStore::Session.find_by_session_id(req.cookie_jar["_session_id"])
  result = session ? session.data["user_id"] : 0

  "%07d" % result
end

log_tags = []
log_tags << lambda { |req| Time.now.strftime("%F %T.%L") }
log_tags << lambda { |req| req.uuid.first(8) }
log_tags << lambda { |req| get_user_id(req) }

Rails.configuration.log_tags = log_tags

結果は次のようになります。

[2013-01-22 13:51:36.659] [e52435d1] [0036484] <the log line>
于 2013-01-22T13:00:26.523 に答える
1

私はSwardsソリューションを使用していますが、それは魅力のように機能します。ただしbegin..rescue、Hash#has_keyの代わりに使用しますか?パフォーマンスキラーです

require 'benchmark/ips'

good_hash = { 'warden.user.admin_user.key' => [[1]]}
bad_hash = {}

Benchmark.ips do |x|
  x.report('begin+rescue good hash') { good_hash['warden.user.admin_user.key'][0][0] }
  x.report('has_key good hash') do
    good_hash.has_key?('warden.user.admin_user.key') &&
        good_hash['warden.user.admin_user.key'][0][0]
  end

  x.report('begin+rescue bad hash') { bad_hash['warden.user.admin_user.key'][0][0] rescue nil }
  x.report('has_key bad hash') do
    if bad_hash.has_key?('warden.user.admin_user.key')
      bad_hash['warden.user.admin_user.key'][0][0]
    end
  end

  # Compare the iterations per second of the various reports!
  x.compare!
end

結果はそれ自体を物語っています

Comparison:
    has_key bad hash:  4870164.1 i/s
begin+rescue good hash:  3544134.7 i/s - 1.37x slower
   has_key good hash:  2127500.6 i/s - 2.29x slower
begin+rescue bad hash:     4468.2 i/s - 1089.95x slower
于 2015-08-07T16:54:30.840 に答える
0

迅速で醜い回避策として、リクエストが処理された後に2行目をログに記録することができます。

この500ServerErrorは、次のユーザーによって提示されています:#{username}

于 2014-01-18T05:40:02.050 に答える
-2

Redis :: Storeを使用している人にとって、@fjuillenの答えは次のようになります。

redis = Redis::Store.new
redis.select 3 # only if you use a different database
result = redis.get req.cookie_jar["_session_id"]

レール4でテスト済み。

于 2013-09-24T18:13:50.273 に答える