Bağımsız bir günlük dosyasında Rails'te bir şey nasıl kaydedilir?


157

Raylarda bazı bilgileri standart development.log veya production.log dosyasına değil, farklı bir günlük dosyasına kaydetmek istiyorum. Bu günlük kaydını bir model sınıfından yapmak istiyorum.

Yanıtlar:


187

Herhangi bir modelin içinden kendiniz bir Logger nesnesi oluşturabilirsiniz. Sadece dosya adını yapıcıya iletin ve nesneyi her zamanki Rails gibi kullanın 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

Burada logger'ı not etmek için bir sınıf niteliği kullandım. Bu şekilde, oluşturulan her bir Kullanıcı nesnesi için oluşturulmaz, ancak bunu yapmanız gerekmez. Ayrıca , kodu uygulamanızın modelleri arasında paylaşmak için my_loggeryöntemi doğrudan ActiveRecord::Basesınıfa (veya çok fazla yama yapmak istemiyorsanız kendi süper sınıfına) enjekte edebileceğinizi unutmayın .


5
Söz konusu model için tüm varsayılan günlük kaydını değiştirmek User.logger = Logger.new(STDOUT)istiyorsanız, oturum açmak istediğiniz veya istediğiniz yeri kullanabilirsiniz. Aynı şekilde, ActiveRecord::Base.logger = Logger.new(STDOUT)tüm modeller için tüm günlüğü değiştirir.
Dave

Herkes her günlüğüne nasıl klasör oluşturacağını biliyor mu?
Mauro Dias

2
@Dave öneriyi denedim ve başarısız oldu. User.logger = Logger.new(STDOUT)tüm modeller için günlük kaydını değiştirdi. Peki, değiştiActiveRecord::Base.logger
fetsh

@ilzoff Evet, bu davranış Rails'te 3 yıl önce değişmiş olabilir. Bunu söylediğin için teşekkürler.
Dave

Teşekkürler. Yerleştirerek hemen hemen benim denetleyicileri için aynı mı my_loggeriçinde application_controller.rb.
kstratis

40

Güncelleme

Ben multi_logger denilen, aşağıdaki çözüm dayalı bir mücevher yaptı . Bunu başlatıcıda yapın:

MultiLogger.add_logger('post')

ve Çağrı yap

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

ve işiniz bitti.

Kendiniz kodlamak istiyorsanız, aşağıya bakın:


Daha eksiksiz bir çözüm aşağıdakileri sizin dizininize lib/veya config/initializers/dizininize yerleştirmek olacaktır.

Bunun faydası, zaman damgalarını veya günlüklerin önem derecesini otomatik olarak önek olarak biçimlendirmek için biçimlendiriciyi ayarlamanızdır. Bu Rails herhangi bir yerden erişilebilir ve singleton desen kullanarak daha temiz görünüyor.

# 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
Ne #{$$}için?
Daniel Costa


37

Benim için işe yarayan iyi bir seçenek, app/modelsklasörünüze oldukça basit bir sınıf eklemektir .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

daha sonra denetleyicinizde veya bir modelin sınıfını raylar uygulamanızdan referans alabileceğiniz hemen hemen her yerde, yani yapabileceğiniz herhangi bir yerde Post.create(:title => "Hello world", :contents => "Lorum ipsum");veya benzer bir şey bu gibi özel dosyanızda oturum açabilirsiniz

MyLog.debug "Hello world"

2
Akıllı ve basit bir çözüm!
Anwar

9

(Say) app / models / special_log.rb dosyasında bir kayıt sınıfı tanımlayın:

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

logger'ı (say) config / initializers / special_log.rb içinde başlatın:

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

Uygulamanızın herhangi bir yerinde, şunlarla giriş yapabilirsiniz:

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

4

İşte benim özel günlükçü:

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

Özel günlük kaydı için Log4r gem kullanmanızı öneririm . Sayfasından açıklama alıntılanıyor:

Log4r, Ruby programlarında kullanılmak üzere Ruby'de yazılmış kapsamlı ve esnek bir günlük kütüphanesidir. İstenen sayıda düzey, hiyerarşik günlük sistemi, özel düzey adları, günlükçü devralma, günlük olayı başına birden çok çıkış hedefi, yürütme izleme, özel biçimlendirme, iş parçacığı güvenliği, XML ve YAML yapılandırması ve daha birçok özelliğe sahiptir.


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

Günlüğe kaydetme çerçevesi, aldatıcı basit adıyla, istediğiniz karmaşıklığa sahiptir!

Tomruk raylarının çok kısa talimatlarını izleyinGürültüyü filtrelemeye, uyarı almaya ve çıkışı hassas ve üst düzey bir şekilde seçmeye başlamak için .

İşiniz bittiğinde kendinizi arkaya vurun. Günlük haddeleme, günlük. Yalnız buna değer.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.