16

私の意見では、ほとんどのレールユーザーにとって問題であるに違いありませんが、まだ解決策を見つけることができませんでした。

たとえば、サイズが大きくなる可能性のあるバイナリ ファイルのファイル アップロードを実行し、それをデータベースに保存する場合、開発モードでこの特定のフィールド (ログ ファイル、stdout) をレールまたは ActiveRecord に記録させたくありません。かなり大きなファイルの場合、これによりクエリの実行が中断され、端末がほとんど停止します。

特定のフィールドのロギングを無効にする、信頼できる非ハッキーな方法はありますか? リクエスト パラメータのロギングを無効にすることについて話しているのではないことを思い出してください。これはかなりうまく解決されています。

それについての情報をありがとう!

4

10 に答える 10

6

これが誰かに役立つ場合は、上記のスニペットの Rails 4.1 互換バージョンを次に示します。これには、非バイナリ バインド パラメータ (テキストまたは json 列など) のリダクションも含まれており、リダクション前にログを 100 文字に増やします。ここでみんなの助けをありがとう!

class ActiveRecord::ConnectionAdapters::AbstractAdapter
  protected

  def log_with_binary_truncate(sql, name="SQL", binds=[], statement_name = nil, &block)
    binds = binds.map do |col, data|
      if data.is_a?(String) && data.size > 100
        data = "#{data[0,10]} [REDACTED #{data.size - 20} bytes] #{data[-10,10]}"
      end
      [col, data]
    end

    sql = sql.gsub(/(?<='\\x[0-9a-f]{100})[0-9a-f]{100,}?(?=[0-9a-f]{100}')/) do |match|
      "[REDACTED #{match.size} chars]"
    end

    log_without_binary_truncate(sql, name, binds, statement_name, &block)
  end

  alias_method_chain :log, :binary_truncate
end
于 2014-02-12T15:13:17.020 に答える
5

ActiveRecord::ConnectionAdapters::AbstractAdapter次のように変更する config/initializers にファイルを作成します。

class ActiveRecord::ConnectionAdapters::AbstractAdapter
   protected

   def log_with_trunkate(sql, name="SQL", binds=[], &block)
     b = binds.map {|k,v|
       v = v.truncate(20) if v.is_a? String and v.size > 20
       [k,v]
     }
     log_without_trunkate(sql, name, b, &block)
   end

   alias_method_chain :log, :trunkate
end

これにより、出力ログで 20 文字を超えるすべてのフィールドが切り捨てられます。

于 2012-10-31T11:57:31.317 に答える
4

注: Rails 3 で動作しますが、明らかに 4 では動作しません (この質問に回答した時点ではリリースされていませんでした)。

application.rb ファイルで:

config.filter_parameters << :parameter_name

これにより、その属性がログに表示されなくなり、[FILTERED] 次のように置き換えられます。パラメーターをフィルター処理する一般的な使用例はもちろんパスワードですが、バイナリ ファイル フィールドで機能しない理由はわかりません。

于 2012-10-24T18:33:26.353 に答える
0

私もこれについてはあまり見つけませんでしたが、あなたにできることの1つは

ActiveRecord::Base.logger = nil

ロギングを完全に無効にしますが、おそらくそうしたくないでしょう。より良い解決策は、ActiveRecordロガーを特定のサイズを超えるメッセージをログに記録しないカスタムサブクラスに設定するか、大きすぎるメッセージの特定のセクションを解析するために何か賢い方法を実行することです。

これは理想的ではないようですが、具体的な実装の詳細については見ていないので、実行可能な解決策のようです。私はもっ​​と良い解決策を聞いて本当に興味があります。

于 2012-10-24T15:19:56.073 に答える
0

私は同じ問題に遭遇しましたが、問題の明確な解決策を見つけることができませんでした。最終的に、blob を除外する Rails ロガー用のカスタム フォーマッタを作成しました。

上記のコードは config/initializers に配置する必要があり、file_data を削除するfile_name列と正規表現の後に表示される列に置き換えます。

于 2013-01-03T06:48:24.823 に答える
0

Rails 5.2 以降のバージョン

module LogTruncater
  def render_bind(attr, value)
    num_chars = Integer(ENV['ACTIVERECORD_SQL_LOG_MAX_VALUE']) rescue 120
    half_num_chars = num_chars / 2

    if attr.is_a?(Array)
      attr = attr.first
    elsif attr.type.binary? && attr.value
      value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
    end

    if value.is_a?(String) && value.size > num_chars
      value = "#{value[0,half_num_chars]} [REDACTED #{value.size - num_chars} chars] #{value[-half_num_chars,half_num_chars]}"
    end

    [attr && attr.name, value]
  end

end

class ActiveRecord::LogSubscriber
  prepend LogTruncater
end
于 2018-10-17T22:24:58.133 に答える