Як записати щось у Rails у незалежний файл журналу?


157

У рейках я хочу занести деяку інформацію в інший файл журналу, а не в стандартний 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

Тут я використав атрибут класу для запам'ятовування реєстратора. Таким чином, він не буде створений для кожного створеного об'єкту користувача, але робити це не потрібно. Пам'ятайте також, що ви можете ввести 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
фетш

@ilzoff Так, цілком можливо, що така поведінка змінилася в Рейліс з 3 років тому. Дякуємо, що зателефонували.
Дейв

Дякую. Зробив майже те ж саме для моїх контролерів шляхом розміщення 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
Для чого це #{$$}?
Даніель Коста


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
Розумне та просте рішення!
Анвар

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 / inicijalizers / 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

Рамка ведення лісозаготівлі, з її оманливо простою назвою, має вишуканість, якої ви прагнете!

Дотримуйтесь дуже коротких вказівок рейкових колод, щоб почати фільтрувати шум, отримувати сповіщення та вибирати вихід дрібнозернистим та високим рівнем.

Погладьте себе по спині, коли закінчите. Колода журналу, щодня. Варто лише цього.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.