3

要件

次のような特定のイベントの監査ログを保持したいと考えています。

  • ユーザーが正常にログインしました
  • ユーザーがログインできませんでした (理由: パスワードが間違っている、未確認など)。
  • SuperUser が別のユーザーの詳細を変更しました (変更内容とともに)

このログには、次のような詳細が含まれている必要があります。

  • アクションを実行しているログイン ユーザー (コントローラの に基づくcurrent_user)
  • 変更中のレコード (スーパー ユーザーの場合の他のユーザー レコードなど)
  • そのアクションのリクエストの IP アドレス

このログは、後でマシン上の別のサービスによって取得できるように、データベース テーブルではなく、ファイル システム上のファイルにも保存する必要があります。

いくつかの可能性

これまでに検討したアプローチの短いリストを次に示します。

ActiveRecord::オブザーバー

オブザーバーは、これらの特定のイベントを監視する優れた方法を提供します。
その後、オブザーバーをログ ファイルに追加できますが、そのような呼び出しの結果 (ログインの失敗や機能など) を簡単に取得できるかどうかはわかりません。何らかの方法でコントローラーを呼び出す必要があります。current_userログインしているユーザーを特定し、IP アドレスを取得するための HTTP リクエストを取得するメソッド。

監査ジェム (audited、auditable、paper_trail など)

これらの gem は、現在のユーザーと IP アドレスでコントローラーにアクセスする方法を知っているという便利さを備えていますが、データベース内の監査テーブルにすべてログを記録します。AuditableARコールバックだけでなく、オブジェクトのメソッド呼び出しを監査できるため、特に優れていますが、データベースではなくファイルに書き込むようにパッチを当てる必要があるかもしれません..または何か?

ActiveSupport::通知

これについてはまだ詳しく調べる必要がありますが、レール内の低レベルのイベントをサブスクライブする低レベルの方法を提供していると思います。これはこの状況には低すぎるかもしれませんが、さらに調査する必要があります。

Log4r

これは良いログ ファイルになるようですが、イベントを監視する方法はないと思います。これは問題の一部にすぎません。

何かアドバイス?

これを行うベストプラクティスの方法はありますか? 以前の経験から学んだ宝石や教訓をお勧めできますか? 他に考慮すべきことはありますか?

4

4 に答える 4

2

回答ありがとうございます。
キャスパー、私は何かカスタムを構築することに決めました.

とにかくローカルデータベースに書き込むというあなたの要点はわかりますが、このプロジェクトの要件はログファイルをダンプすることです。これにより、より精巧なログ解析サービスがファイルを調べ、他のソースからの情報と組み合わせることができます。

モデルとコントローラーの両方からログを取得するために、オブザーバーと の両方に含めるモジュールを作成することになりましたApplicationController

モジュールは次のようになります。

module MyEventLogger
  mattr_accessor :logged_current_user
  mattr_accessor :logged_remote_ip

  def log_event(message)
    @@logger ||= Logger.new(Rails.root.join('log', 'audit.log'))
    @@logger.info "#{Time.now} | #{logged_current_user}@#{logged_remote_ip} | #{message}"
  end

  def logged_current_user
    @@logged_current_user || "SYSTEM"
  end

  def logged_remote_ip
    @@logged_remote_ip || "NO IP ADDRESS"
  end
end

ApplicationController は次のようになります。

include MyEventLogger
before_filter :setup_logger

...

def setup_logger
  MyEventLogger.logged_current_user = current_user
  MyEventLogger.logged_ip_address = request.remote_ip
end

オブザーバーは必要なだけで、メソッドと現在のユーザーと IP アドレスにinclude MyEventLoggerアクセスできます。log_event例えば:

class UserObserver < ActiveRecord::Observer
  include MyEventLogger

  def after_save(user)
    log_event "The User #{user} was saved by #{logged_current_user}"
  end

end
于 2012-06-08T03:57:22.337 に答える
1

いくつかの考え:

監査宝石は、あなたが望むものに最も近い音を出します。それらのソース コードを見ると、それらはそれほど複雑ではなく、実際にはほとんどが Rails Observer を中心に構築されているようです。それらのコードをベースとして簡単に使用して、独自の特殊バージョンを作成できます。

たとえば、Audited のコードを見ると、current_user(独自の実装を展開する場合)を格納するのは実際には非常に簡単であることがわかります。

https://github.com/collectiveidea/audited/blob/master/lib/audited/sweeper.rb

監査データを DB に置くことが必ずしも悪いとは思いません。ある日、以前の何千ものトランザクションから複雑な問題を追跡する必要があるときに、実際に役立つと思うかもしれません。必要に応じて、データをログファイル形式にダンプする単純な Rake タスクをいつでも作成できます。

しかし、これLog4rは非常に優れていると言えます。私自身、いくつかのプロジェクトで使用しました。しかし、監査タイプのニーズはありませんでした。デバッグとトラブルシューティングのための基本的なログ記録のみ。

必要に応じて、独自の Observer タイプのシステムのようなものを DB ドライバーの代わりに Log4r ドライバーと組み合わせることも検討できます。いずれにせよ、Observer システムが提供するもの以外でロギング イベントをトリガーする必要があるように聞こえるからです。つまり、既存の gem に拡張機能を実装するか、gem をベースとして使用し、独自の機能で拡張する必要があります。

とにかく - DB アプローチは実際には利点であり、監査証跡でクエリを実行できるのはクールだと思います。そのようなものは害を及ぼすことはありません(Log4rところで、カスタムの「出力ドライバー」もサポートされているため、DBへのログインにも使用できます)。

于 2012-06-06T05:42:37.673 に答える
0

それを行う1つの方法は、ログに記録されたアクションを実行したい場所で、ブロックで実行することです

Russ Olsen による Eloquent Ruby の第 18 章http://books.google.com/books?id=-s2xL0pVsLUC&lpg=PA219&ots=l7I3oAK3M2&dq=eloquent%20ruby%20chapter%2018&pg=PA219#v=onepage&q&f=falseを見ることを強くお勧めします。おそらく、Gregory Brown の Ruby Best Practices の第 2 章の「Using Blocks」http://majesticseacreature.com/rbp-book/pdfs/rbp_1-0.pdf

例えば

def with_logging(description)
 begin
    @logger.debug( "Starting #{description}" ) 
    yield # this is when the code in the block executes
    @logger.debug( "Completed #{description}" )
  rescue
    @logger.error( "#{description} failed!!") 
    raise
  end
end

with_logging('code example') { puts "just printing something" }

また: graylog http://graylog2.org/about/gelfなどのツールを調べる価値があるかもしれません ( http://arrrrcamp.be/videos/2011/lennart-koopmann---managing-the-logs-ofを参照してください) -your-rails-applications/ ) またはこれらの投稿http://openmymind.net/2012/4/4/You-Really-Should-Log-Client-Side-Error/ (javascript)、https://github.com /TwP/logginghttp: //amon.cx/

于 2012-06-06T04:06:53.893 に答える
0

これで私の個人的な経験を共有するだけです:

ここで言及したものと非常によく似たものを作成しました。データベースでテーブルを使用し、関連するリクエストを application_controller でトラップpostし、ログ テーブルに関連付けられたモデルに情報を渡しました。ロジックは非常に簡単で、必要なすべてのコントロールがありました。唯一の努力は、特定のトランザクションを選択/拒否し、すべての有用なパラメーターをテキスト フィールドにうまく収まるように再構築することでした。

もしあなたがそのルートを取ることに決めたら、私は喜んで詳細を共有します。

幸運を。

于 2012-06-06T03:37:36.150 に答える