2008-12-03 32 views

Trả lời

144

Bạn có thể tự tạo đối tượng Logger từ bên trong bất kỳ mô hình nào. Chỉ cần vượt qua tên tập tin để các nhà xây dựng và sử dụng các đối tượng như Rails thường 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 

Ở đây tôi sử dụng một thuộc tính lớp để memoize logger. Bằng cách này nó sẽ không được tạo ra cho mỗi đối tượng người dùng duy nhất được tạo ra, nhưng bạn không cần phải làm điều đó. Hãy nhớ rằng bạn có thể tiêm phương thức my_logger trực tiếp vào lớp ActiveRecord::Base (hoặc vào một số siêu lớp của riêng bạn nếu bạn không thích khỉ vá quá nhiều) để chia sẻ mã giữa các mô hình ứng dụng của bạn.

+3

Nếu bạn muốn thay đổi tất cả ghi nhật ký mặc định cho mô hình cụ thể đó, bạn có thể sử dụng đơn giản 'User.logger = Logger.new (STDOUT)' hoặc bất cứ nơi nào bạn muốn để đăng nhập. Trong cùng một cách, 'ActiveRecord :: Base.logger = Logger.new (STDOUT)' sẽ thay đổi tất cả ghi nhật ký cho tất cả các mô hình. – Dave

+0

Bất cứ ai cũng biết cách tạo thư mục cho mỗi nhật ký? –

+1

@Dave Tôi đã thử đề xuất của bạn và không thành công. 'User.logger = Logger.new (STDOUT)' thay đổi tất cả ghi nhật ký cho tất cả các mô hình. Vâng, nó đã thay đổi 'ActiveRecord :: Base.logger' – fetsh

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 
31

Một lựa chọn phong nha mà làm việc cho tôi là chỉ cần thêm một lớp khá đơn giản vào thư mục app/models của bạn như 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 

sau đó trong điều khiển của bạn, hoặc thực sự gần như bất cứ nơi nào mà bạn có thể tham khảo một mô hình lớp học từ trong ứng dụng đường ray của bạn, tức là bất cứ nơi nào bạn có thể làm Post.create(:title => "Hello world", :contents => "Lorum ipsum"); hoặc một cái gì đó tương tự bạn có thể đăng nhập vào tập tin tùy chỉnh của bạn như thế này

MyLog.debug "Hello world" 
+0

Bạn là người đàn ông! – Bijan

+2

Giải pháp thông minh và đơn giản! – Anwar

35

Cập nhật

Tôi đã tạo một đá quý dựa trên giải pháp bên dưới, được gọi là multi_logger. Chỉ cần làm điều này trong initializer:

MultiLogger.add_logger('post') 

và gọi

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

và bạn đã làm xong.

Nếu bạn muốn mã đó cho mình, xem dưới đây:


Một giải pháp hoàn chỉnh hơn sẽ được đặt sau đây trong thư mục của bạn lib/ hoặc config/initializers/.

Lợi ích là bạn có thể thiết lập trình định dạng thành dấu thời gian tiền tố hoặc mức độ nghiêm trọng cho nhật ký một cách tự động. Điều này có thể truy cập từ bất cứ nơi nào trong Rails, và trông neater bằng cách sử dụng mẫu đơn.

# 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

Tôi khuyên bạn nên sử dụng Log4r gem để ghi nhật ký tùy chỉnh. Mô tả trích dẫn từ trang của nó:

Log4r là thư viện khai thác toàn diện và linh hoạt được viết bằng Ruby để sử dụng trong chương trình Ruby. Nó có hệ thống đăng nhập phân cấp của bất kỳ số lượng mức độ nào là mức độ , tên cấp tùy chỉnh, thừa kế nhật ký, nhiều đích đầu ra cho mỗi sự kiện nhật ký, theo dõi thực thi, định dạng tùy chỉnh, safteyness luồng, XML và cấu hình YAML, v.v.

0

Khung ghi nhật ký, với tên đơn giản, tinh tế, có sự tinh tế mà bạn mong muốn!

Làm theo các hướng dẫn rất ngắn logging-rails để bắt đầu lọc ra tiếng ồn, nhận cảnh báo và chọn đầu ra theo cách tinh vi và cấp cao.

Tự vỗ về mặt sau khi bạn hoàn tất. Đăng nhập, hàng ngày. Đáng giá cho điều đó một mình.

3

Đây là logger tùy chỉnh của tôi:

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 
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') 
2

Định nghĩa một lớp logger trong (nói) ứng dụng/mô hình/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 

khởi tạo logger trong (nói) config/initializers/special_log.rb:

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

Anyw ở đây trong ứng dụng của bạn, bạn có thể đăng nhập bằng:

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

Cảm ơn, hoạt động như một sự quyến rũ! –

Các vấn đề liên quan