Railsの何かを独立したログファイルに記録する方法は?


157

Railsでは、標準のdevelopment.logやproduction.logではなく、いくつかの情報を別のログファイルに記録したいと思っています。このロギングをモデルクラスから実行したいと考えています。

回答:


187

Loggerオブジェクトは、任意のモデル内から自分で作成できます。ファイル名をコンストラクタに渡して、通常のRailsのようにオブジェクトを使用するだけですlogger

class User < ActiveRecord::Base
  def my_logger
    @@my_logger ||= Logger.new("#{Rails.root}/log/my.log")
  end

  def before_save
    my_logger.info("Creating user with name #{self.name}")
  end
end

ここでは、ロガーをメモするためにクラス属性を使用しました。これにより、作成されるすべてのUserオブジェクトに対して作成されるわけではありませんが、作成する必要はありません。アプリのモデル間でコードを共有するために、my_loggerメソッドをActiveRecord::Baseクラス(または、あまりパッチを適用したくない場合は独自のスーパークラス)に直接注入できることも覚えておいてください。


5
特定のモデルのすべてのデフォルトのロギングを変更したい場合は、User.logger = Logger.new(STDOUT)またはを使用して、どこにログオンするかを簡単に指定できます。同様にActiveRecord::Base.logger = Logger.new(STDOUT)、すべてのモデルのすべてのログを変更します。
Dave

誰もが各ログにフォルダを作成する方法を知っていますか?
Mauro Dias 2013

2
@デイブ私はあなたの提案を試してみましたが失敗しました。User.logger = Logger.new(STDOUT)すべてのモデルのすべてのログを変更しました。まあ、それは変わりましたActiveRecord::Base.logger
fetsh 2013

@ilzoffはい、3年前からRailsでこの動作が変更された可能性があります。よろしくお願いします。
デイブ、

ありがとう。に配置することmy_loggerで、私のコントローラーでもほとんど同じでしたapplication_controller.rb
kstratis 2017

40

更新

私はmulti_loggerと呼ばれる以下のソリューションに基づいて宝石を作りました。初期化子でこれを行うだけです:

MultiLogger.add_logger('post')

そして電話する

Rails.logger.post.error('hi')
# or call logger.post.error('hi') if it is accessible.

これで完了です。

自分でコーディングする場合は、以下を参照してください。


より完全なソリューションは、lib/またはconfig/initializers/ディレクトリに以下を配置することです。

利点は、タイムスタンプまたは重大度をログに自動的にプレフィックスするようにフォーマッターを設定できることです。これはRailsのどこからでもアクセスでき、シングルトンパターンを使用することで見栄えが良くなります。

# Custom Post logger
require 'singleton'
class PostLogger < Logger
  include Singleton

  def initialize
    super(Rails.root.join('log/post_error.log'))
    self.formatter = formatter()
    self
  end

  # Optional, but good for prefixing timestamps automatically
  def formatter
    Proc.new{|severity, time, progname, msg|
      formatted_severity = sprintf("%-5s",severity.to_s)
      formatted_time = time.strftime("%Y-%m-%d %H:%M:%S")
      "[#{formatted_severity} #{formatted_time} #{$$}] #{msg.to_s.strip}\n"
    }
  end

  class << self
    delegate :error, :debug, :fatal, :info, :warn, :add, :log, :to => :instance
  end
end

PostLogger.error('hi')
# [ERROR 2012-09-12 10:40:15] hi

1
何の#{$$}ためですか?
Daniel Costa、


37

私にとってうまくいく適切なオプションは、次のようなかなりプレーンなクラスをapp/modelsフォルダに追加することですapp/models/my_log.rb

class MyLog
  def self.debug(message=nil)
    @my_log ||= Logger.new("#{Rails.root}/log/my.log")
    @my_log.debug(message) unless message.nil?
  end
end

次に、コントローラ、またはレールアプリ内からモデルのクラスを参照できるほぼすべての場所、つまりできる場所Post.create(:title => "Hello world", :contents => "Lorum ipsum");または同様の何かをこのようなカスタムファイルに記録できます

MyLog.debug "Hello world"

2
スマートでシンプルなソリューション!
Anwar

9

(たとえば)app / models / special_log.rbでロガークラスを定義します。

class SpecialLog
  LogFile = Rails.root.join('log', 'special.log')
  class << self
    cattr_accessor :logger
    delegate :debug, :info, :warn, :error, :fatal, :to => :logger
  end
end

(たとえば)config / initializers / special_log.rbでロガーを初期化します。

SpecialLog.logger = Logger.new(SpecialLog::LogFile)
SpecialLog.logger.level = 'debug' # could be debug, info, warn, error or fatal

アプリのどこにいても、次のようにログに記録できます。

SpecialLog.debug("something went wrong")
# or
SpecialLog.info("life is good")

4

これが私のカスタムロガーです:

class DebugLog
  def self.debug(message=nil)
    return unless Rails.env.development? and message.present?
    @logger ||= Logger.new(File.join(Rails.root, 'log', 'debug.log'))
    @logger.debug(message) 
  end
end

2
class Article < ActiveRecord::Base  

      LOGFILE = File.join(RAILS_ROOT, '/log/', "article_#{RAILS_ENV}.log")  

      def validate  
        log "was validated!"  
      end   

      def log(*args)  
       args.size == 1 ? (message = args; severity = :info) : (severity, message = args)  
       Article.logger severity, "Article##{self.id}: #{message}"  
     end  

     def self.logger(severity = nil, message = nil)  
       @article_logger ||= Article.open_log  
       if !severity.nil? && !message.nil? && @article_logger.respond_to?(severity)  
         @article_logger.send severity, "[#{Time.now.to_s(:db)}] [#{severity.to_s.capitalize}] #{message}\n"  
       end  
       message or @article_logger  
     end  

     def self.open_log  
       ActiveSupport::BufferedLogger.new(LOGFILE)  
     end  

   end  

1

カスタムロギングにはLog4r gemを使用することを勧めします。そのページからの説明の引用:

Log4rは、Rubyプログラムで使用するためにRubyで記述された包括的で柔軟なロギングライブラリです。任意の数のレベルの階層ログシステム、カスタムレベル名、ロガー継承、ログイベントごとの複数の出力先、実行トレース、カスタムフォーマット、スレッドの安全性、XMLおよびYAML構成などを備えています。


1
class Post < ActiveRecord::Base
    def initialize(attributes)
        super(attributes)
        @logger = Logger.new("#{Rails.root}/log/post.log")
    end

    def logger
        @logger
    end

    def some_method
        logger.info('Test 1')
    end
end

ps = Post.new
ps.some_method
ps.logger.info('Test 2')
Post.new.logger.info('Test 3')

0

Loggingフレームワークは、その一見単純な名前で、洗練されています。

logging-railsの非常に短い手順に従って、ノイズのフィルタリング、アラートの取得、およびきめ細かく高レベルな方法での出力の選択を開始します。

終わったら背中を軽くたたいてください。ログローリング、毎日。それだけでそれだけの価値があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.