Làm thế nào để đăng nhập một cái gì đó trong Rails trong một tệp nhật ký độc lập?


157

Trong rails tôi muốn đăng nhập một số thông tin trong một tệp nhật ký khác và không phải là Development.log hoặc sản xuất tiêu chuẩn. Tôi muốn làm việc đăng nhập này từ một lớp mô hình.

Câu trả lời:


187

Bạn có thể tự tạo một đối tượng Logger từ bên trong bất kỳ mô hình nào. Chỉ cần chuyển tên tệp cho hàm tạo và sử dụng đối tượng như Rails thông 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 để ghi nhớ logger. Bằng cách này, nó sẽ không được tạo cho mọi đối tượng Người dùng duy nhất được tạo, nhưng bạn không bắt buộc phải làm điều đó. Cũng cần nhớ rằng bạn có thể đưa my_loggerphương thức trực tiếp vào ActiveRecord::Baselớp (hoặc vào một số siêu lớp của riêng bạn nếu bạn không muốn vá khỉ quá nhiều) để chia sẻ mã giữa các mô hình ứng dụng của bạn.


5
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 chỉ cần sử dụng User.logger = Logger.new(STDOUT)hoặc bất cứ nơi nào bạn muốn đăng nhập. Theo cùng một cách, ActiveRecord::Base.logger = Logger.new(STDOUT)sẽ thay đổi tất cả các bản ghi cho tất cả các mô hình.
Dave

Bất cứ ai cũng biết làm thế nào để tạo các thư mục cho mỗi bản ghi?
Mauro Dias

2
@ Tôi đã thử đề xuất của bạn và nó đã thất bại. User.logger = Logger.new(STDOUT)thay đổi tất cả các bản ghi cho tất cả các mô hình. Chà, nó đã thay đổiActiveRecord::Base.logger
fetsh

@ilzoff Yep, rất có thể hành vi này đã thay đổi trong Rails từ 3 năm trước. Cảm ơn đã gọi nó ra.
Dave

Cảm ơn. Đã làm khá nhiều điều tương tự cho bộ điều khiển của tôi bằng cách đặt my_loggervào application_controller.rb.
kstratis

40

Cập nhật

Tôi đã tạo ra một viên ngọc 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 trình khởi tạo:

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 đã hoàn thành.

Nếu bạn muốn tự viết mã, xem bên dưới:


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

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 đối với nhật ký. Điều này có thể truy cập từ bất cứ nơi nào trong Rails và trông gọn gàng hơn bằng cách sử dụng mẫu singleton.

# 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
Để làm gì #{$$}?
Daniel Costa


37

Một tùy chọn phù hợp với tôi là chỉ cần thêm một lớp khá đơn giản vào app/modelsthư mục của bạn, chẳng hạ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 bộ điều khiển của bạn hoặc thực sự gần như bất cứ nơi nào bạn có thể tham chiếu lớp của một mô hình từ trong ứng dụng rails của mình, 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 tùy chỉnh của mình như thế này

MyLog.debug "Hello world"

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

9

Xác định một lớp logger trong (giả sử) ứ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 / khởi tạo / Special_log.rb:

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

Bất cứ nơi nào 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")

4

Đâ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

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

Tôi sẽ đề nghị sử dụng đá quý Log4r để đăng nhập tùy chỉnh. Trích dẫn mô tả từ trang của nó:

Log4r là một thư viện ghi nhật ký toàn diện và linh hoạt được viết bằng Ruby để sử dụng trong các chương trình Ruby. Nó có một hệ thống ghi nhật ký phân cấp của bất kỳ số cấp độ nào, tên cấp độ tùy chỉnh, kế thừa logger, 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, cấu hình XML và YAML, v.v.


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

Khung Logging, với cái tên đơn giản mang tính giả dối, có sự tinh tế mà bạn khao khát!

Thực hiện theo các hướng dẫn rất ngắn về đường ray đăng nhập để bắt đầu lọc tiếng ồn, nhận thông báo và chọn đầu ra theo cách chi tiết và cao cấp.

Hãy vỗ nhẹ vào lưng khi bạn đã hoàn thành. Đăng nhập, hàng ngày. Đáng giá cho điều đó một mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.