Ответы:
Вы можете создать объект 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
Здесь я использовал атрибут класса, чтобы запоминать регистратор. Таким образом, он не будет создан для каждого отдельного объекта User, который создается, но вы не обязаны это делать. Помните также, что вы можете внедрить my_loggerметод непосредственно в ActiveRecord::Baseкласс (или в какой-то собственный суперкласс, если вам не нравится слишком много патчить обезьяны), чтобы поделиться кодом между моделями вашего приложения.
User.logger = Logger.new(STDOUT)поменял все логи для всех моделей. Ну, это изменилосьActiveRecord::Base.logger
my_loggerв application_controller.rb.
Обновить
Я сделал драгоценный камень, основанный на решении ниже, названный 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
#{$$}?
Приличный вариант, который мне подходит, это просто добавить довольно простой класс в вашу 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
затем в вашем контроллере, или практически в любом месте, где вы можете ссылаться на класс модели из вашего приложения rails, то есть где бы вы Post.create(:title => "Hello world", :contents => "Lorum ipsum");ни делали или что-то подобное, вы можете войти в свой пользовательский файл, например так
MyLog.debug "Hello world"
Определите класс логгера в (скажем) app / models / 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")
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
Я бы предложил использовать Gem Log4r для пользовательских журналов. Цитирую описание со своей страницы:
Log4r - это всеобъемлющая и гибкая библиотека журналов, написанная на Ruby для использования в программах на Ruby. Он имеет иерархическую систему ведения журналов любого количества уровней, имен пользовательских уровней, наследования регистратора, нескольких выходных назначений для каждого события журнала, трассировки выполнения, настраиваемого форматирования, безопасности потоков, конфигурации XML и YAML и многого другого.
Фреймворк Logging, с его обманчиво простым именем, обладает утонченностью, которой вы жаждете!
Следуйте очень коротким инструкциям рельсов регистрации, чтобы начать отфильтровывать шум, получать оповещения и выбирать выходные данные детальным и высокоуровневым способом.
По окончании погладьте себя по спине. Бревно, ежедневно. Стоит только этого.
User.logger = Logger.new(STDOUT)или куда вы хотите войти. Таким же образомActiveRecord::Base.logger = Logger.new(STDOUT)будут меняться все журналы для всех моделей.