如何在Rails中的独立日志文件中记录某些内容?


157

在Rails中,我想将一些信息记录在其他日志文件中,而不是标准的development.log或production.log中。我想从模型类中进行此日志记录。

Answers:


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

在这里,我使用了class属性来记录记录器。这样,就不会为创建的每个用户对象都创建它,但是您不需要这样做。还要记住,您可以将my_logger方法直接注入到ActiveRecord::Base类中(如果您不想过多地修补猴子,则可以注入到自己的某些超类中),以在应用程序的模型之间共享代码。


5
如果要更改该特定模型的所有默认日志记录,则可以简单地使用User.logger = Logger.new(STDOUT)或在任何要登录的地方进行记录。以相同的方式,ActiveRecord::Base.logger = Logger.new(STDOUT)将更改所有模型的所有日志记录。
戴夫

有人知道如何为每个日志创建文件夹吗?
Mauro Dias

2
@戴夫我尝试了您的建议,但失败了。User.logger = Logger.new(STDOUT)更改了所有模型的所有日志记录。好吧,它改变了ActiveRecord::Base.logger
fetsh

@ilzoff是的,很可能这种行为自3年前在Rails中已经改变。感谢您提出来。
戴夫

谢谢。通过放置my_logger,对我的控制器做了几乎相同的操作application_controller.rb
kstratis

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

然后在您的控制器中,或者实际上几乎是您可以在Rails应用程序中引用模型类的任何位置,即您可以执行的任何操作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框架以其看似简单的名称,具有您所渴望的复杂性!

按照日志记录栏的简短说明开始,以细粒度和高级的方式过滤掉噪音,获取警报并选择输出。

完成后,轻拍自己的背部。每天进行日志滚动。仅此一项就值得。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.