จะบันทึกบางอย่างใน 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

ที่นี่ฉันใช้ class attribute เพื่อบันทึก logger วิธีนี้จะไม่ถูกสร้างสำหรับวัตถุผู้ใช้ทุกชิ้นที่ถูกสร้างขึ้น แต่คุณไม่จำเป็นต้องทำเช่นนั้น โปรดจำไว้ว่าคุณสามารถฉีดmy_loggerวิธีลงในActiveRecord::Baseชั้นเรียนโดยตรง(หรือลงในซูเปอร์คลาสของคุณเองถ้าคุณไม่ชอบการปะแก้ลิงมากเกินไป) เพื่อแชร์รหัสระหว่างรุ่นแอปของคุณ


5
หากคุณต้องการเปลี่ยนการบันทึกเริ่มต้นทั้งหมดสำหรับรูปแบบเฉพาะนั้นคุณสามารถใช้User.logger = Logger.new(STDOUT)หรือทุกที่ที่คุณต้องการเข้าสู่ระบบ ในทำนองเดียวกันActiveRecord::Base.logger = Logger.new(STDOUT)จะเปลี่ยนการบันทึกทั้งหมดสำหรับทุกรุ่น
เดฟ

ใครรู้วิธีสร้างโฟลเดอร์ในแต่ละบันทึก?
Mauro Dias

2
@Dave ฉันได้ลองข้อเสนอแนะของคุณแล้วและล้มเหลว User.logger = Logger.new(STDOUT)เปลี่ยนการบันทึกทั้งหมดสำหรับทุกรุ่น ดีก็เปลี่ยนActiveRecord::Base.logger
fetsh

@ilzoff ใช่มันเป็นไปได้มากที่พฤติกรรมนี้มีการเปลี่ยนแปลงใน Rails ตั้งแต่ 3 ปีที่แล้ว ขอบคุณที่โทรมา
เดฟ

ขอบคุณ ไม่สวยมากเหมือนกันสำหรับตัวควบคุมของฉันด้วยการวางในmy_logger application_controller.rb
kstratis

40

ปรับปรุง

ฉันทำอัญมณีซึ่งเป็นไปตามวิธีการดังต่อไปนี้เรียกว่าmulti_logger เพียงทำสิ่งนี้ใน initializer:

MultiLogger.add_logger('post')

และโทร

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

และคุณทำเสร็จแล้ว

หากคุณต้องการโค้ดด้วยตนเองดูด้านล่าง:


โซลูชั่นที่สมบูรณ์มากขึ้นจะไปยังสถานที่ต่อไปนี้ในของคุณlib/หรือconfig/initializers/ไดเรกทอรี

ประโยชน์คือคุณสามารถตั้งค่าฟอร์แมตเตอร์เป็นคำนำหน้าบันทึกเวลาหรือความรุนแรงของบันทึกได้โดยอัตโนมัติ สิ่งนี้สามารถเข้าถึงได้จากทุกที่ใน Rails และดู neater โดยใช้รูปแบบซิงเกิล

# 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

กำหนดคลาสตัวบันทึกใน (พูด) แอพ / รุ่น / 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สำหรับการบันทึกที่กำหนดเอง อ้างคำอธิบายจากหน้า:

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

กรอบการบันทึกด้วยชื่อที่เรียบง่ายหลอกลวงมีความซับซ้อนที่คุณปรารถนา!

ทำตามคำแนะนำสั้น ๆ ของการบันทึกรางเพื่อเริ่มกรองสัญญาณรบกวนรับการแจ้งเตือนและเลือกเอาท์พุทอย่างละเอียดและระดับสูง

ลูบตัวเองที่ด้านหลังเมื่อเสร็จแล้ว ล็อกกลิ้งทุกวัน มันคุ้มค่าสำหรับคนเดียว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.