В рельсах я хочу записать некоторую информацию в другой файл журнала, а не в стандартный development.log или production.log. Я хочу выполнить этот журнал из класса модели.
Как зарегистрировать что-то в Rails в независимом файле журнала?
Ответ 1
Вы можете создать объект 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 для memoize logger. Таким образом, он не будет создан для каждого объекта User, который создается, но вы не обязаны это делать. Помните также, что вы можете вводить метод my_logger
непосредственно в класс ActiveRecord::Base
(или в какой-либо собственный суперкласс, если вам не нравится слишком много заплаток для обезьян), чтобы разделить код между вашими приложениями.
Ответ 2
Обновление
Я сделал камень, основанный на нижеприведенном решении, называемом 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 и выглядит более аккуратно, используя шаблон 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
Ответ 3
Пригодный для меня вариант - просто добавить довольно простой класс в вашу папку 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"
Ответ 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
Ответ 5
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
Ответ 6
Определите класс регистратора в (скажем) приложении /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")
Ответ 7
Я бы предложил использовать Log4r gem для пользовательского ведения журнала. Описание предложения со своей страницы:
Log4r - это всеобъемлющая и гибкая библиотека регистрации, написанная на Ruby для использования в программах Ruby. Он имеет иерархическую систему ведения журнала любого количества уровни, пользовательские имена уровней, наследование логов, множественные выходные адресаты для каждого события журнала, трассировки выполнения, пользовательского форматирования, безопасности потоков, XML и YAML, и многое другое.
Ответ 8
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')
Ответ 9
Структура ведения журнала с его обманчиво простым именем имеет сложность, которую вы жаждете!
Следуйте очень коротким инструкциям logging-rails, чтобы начать фильтровать шум, получать предупреждения и выбирать вывод в мелкозернистой и высокого уровня.
Постарайтесь на спине, когда закончите. Лог-прокат, ежедневно. Стоит только этого.