ставит vs logger в задачи rails rake

108

В задаче rake, если я использую команду put, я вижу вывод на консоли. Однако я не увижу это сообщение в файле журнала, когда приложение будет развернуто на производстве.

Однако если я скажу Rails.logger.info, тогда в режиме разработки я ничего не вижу на консоли. Мне нужно перейти к файлу журнала и следить за ним.

В идеале я хотел бы использовать Rails.logger.info, а в режиме разработки внутри задачи rake вывод логгера также должен быть отправлен на консоль.

Есть ли способ добиться этого?

Ник Вандербильт
источник

Ответы:

57

Поместите это application.rbили в код инициализации задачи rake

if defined?(Rails) && (Rails.env == 'development')
  Rails.logger = Logger.new(STDOUT)
end

Это код Rails 3. Обратите внимание, что это переопределит регистрацию в development.log. Если вам нужно и то, STDOUTи другое, и development.logвам понадобится функция-оболочка.

Если вам нужно такое поведение только в консоли Rails, поместите тот же блок кода в свой ~/.irbrc.

Шмайкл
источник
26
Разве не было бы проще просто добавить Rails.logger = Logger.new(STDOUT)development.rb?
ghempton
Для rails 2 поместите это в свой development.rb:config.logger = Logger.new(STDOUT)
jsarma
38

Вы можете создать новую задачу с граблями, чтобы заставить это работать.

desc "switch logger to stdout"
task :to_stdout => [:environment] do
 Rails.logger = Logger.new(STDOUT)
end

Таким образом, когда вы выполняете свою задачу rake, вы можете сначала добавить to_stdout, чтобы получать сообщения журнала stdout, или не включать его, чтобы сообщения отправлялись в файл журнала по умолчанию

rake to_stdout some_task
Пит Брамм
источник
11

Задачи Rake запускаются пользователем из командной строки. Все, что им нужно знать сразу («обработанные 5 строк»), следует вывести на терминал с помощью puts.

Все, что необходимо сохранить для потомков («отправлено письмо с предупреждением на адрес jsmith@example.com»), следует отправлять на адрес Rails.logger.

Джонатан Джулиан
источник
17
Выполнение задач rake с помощью cron - не редкость.
Йоханнес Горсет
2
Правда. Если вы хотите, чтобы сообщения журнала отправлялись вам по электронной почте после завершения задания cron, отправьте их в $ stdout или $ stderr.
Джонатан Джулиан,
10

Я бы сказал, что использование Rails.logger.info- это лучший способ.

Вы не сможете увидеть его в консоли сервера, потому что он не будет работать через сервер. Просто откройте новую консоль и tail -fфайл журнала, это поможет.

Многие пользователи знают о команде UNIX® "хвост", которую можно использовать для отображения последних нескольких строк большого файла. Это может быть полезно для просмотра файлов журнала и т. Д.

В некоторых ситуациях даже более полезным является параметр «-f» команды «хвост». Это заставляет tail "следовать" за выводом файла. Первоначально ответ будет таким же, как и для «хвоста» сам по себе - будут отображаться последние несколько строк файла. Однако команда не возвращается к приглашению, а вместо этого продолжает «следовать» за файлом. Когда в файл добавляются дополнительные строки, они будут отображаться на терминале. Это очень полезно для просмотра файлов журнала или любого другого файла, который может добавляться с течением времени. Введите «человеческий хвост», чтобы получить более подробную информацию об этом и других вариантах хвоста.

( через )

Marcgg
источник
Но это не очень удобно при работе на локальной машине, так как вы не видите результат в том же окне, где вы вызывали задачу. Особенно, если у вас нет большого экрана, на котором можно разместить несколько окон рядом.
Томас Маркаускас
10
Еще лучше использовать tailf«Он похож на tail -f, но не обращается к файлу, когда он не увеличивается» (из man-страницы). Он тоже короче
MBO
@tomas, почему бы не свернуть консоль журнала сервера и не использовать только одну консоль с запущенным tail-f? В любом случае, это не настоящая проблема ... Я работаю как 8 консолей, отслеживая то, что происходит в моем приложении, просто переключайтесь между вкладками, когда вы работаете над определенной частью системы, ничего
страшного,
@mbo nice :) халяс, похоже, он не доступен на моей машине (mac os @ leopard)
marcgg
1
@marcgg: у меня нет "серверной консоли" (я использую пассажира), но вопрос касается задач с граблями, и если вы запустите задачу из одного окна терминала, вы не увидите ничего из регистратора в этом окне. У вас должно быть другое окно с development.log, чтобы увидеть результат. В идеале я бы как-то добавил stdout в качестве другого потока вывода в Rails.logger, но не удалял исходный.
Томас Маркаускас
9

Код

Для Rails 4 и новее вы можете использовать трансляцию Logger .

Если вы хотите получить и STDOUT, и журнал файлов для задач rake в режиме разработки, вы можете добавить этот код в config/environments/development.rb:

  if File.basename($0) == 'rake'
    # http://stackoverflow.com/questions/2246141/puts-vs-logger-in-rails-rake-tasks
    log_file     = Rails.root.join("log", "#{Rails.env}.log")
    Rails.logger = ActiveSupport::Logger.new(log_file)
    Rails.logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT)))
  end

Тест

Вот небольшая задача Rake для проверки приведенного выше кода:

# lib/tasks/stdout_and_log.rake
namespace :stdout_and_log do
  desc "Test if Rails.logger outputs to STDOUT and log file"
  task :test => :environment do
    puts "HELLO FROM PUTS"
    Rails.logger.info "HELLO FROM LOGGER"
  end
end

Текущие rake stdout_and_log:testвыходы

HELLO FROM PUTS
HELLO FROM LOGGER

пока

HELLO FROM LOGGER

был добавлен в log/development.log.

Текущие rake stdout_and_log:test RAILS_ENV=productionвыходы

HELLO FROM PUTS

пока

HELLO FROM LOGGER

был добавлен в log/production.log.

Эрик Думинил
источник
В Rails 5 basename($0) == 'rake'трюк больше не работает, потому что railsвыполняется сама команда rake. Я бы хотел найти ему хорошую замену вне зависимости от задачи, которая устанавливает broadcast. (По крайней мере, эта часть все еще работает нормально.)
Брент Роял-Гордон
@ BrentRoyal-Gordon Нет необходимости в этом условном условии в разработке, вы можете просто добавить код Rakefileв корень вашего проекта
Маурисио Паскье Хуан
4

Как насчет создания помощника приложения, который определяет, какая среда запущена, и делает правильные вещи?

def output_debug(info)
   if RAILS_ENV == "development"
      puts info
   else
      logger.info info
   end
end

Затем вызовите output_debug вместо put или logger.info

naven87
источник
5
Не думаю, что это хорошая идея. Регистратор Rails должен быть настраиваемым, но вместо того, чтобы использовать эту возможность настройки, вы просто накладываете на него больше слоев.
Sijmen Mulder
Да, это плохая идея, поскольку одна и та же проверка будет выполняться каждый раз, когда вы хотите что-то записать .
furiabhavesh 05
3

В Rails 2.X для перенаправления логгера на STDOUT в моделях:

ActiveRecord::Base.logger = Logger.new(STDOUT)

Чтобы перенаправить регистратор в контроллеры:

ActionController::Base.logger = Logger.new(STDOUT)
Таня Р
источник
Я также нашла эту статью, очень полезную sepcot.com/blog/2009/08/rails-logging-to-stdout
Tania R
2

Выполните фоновое задание с помощью '&' и откройте скрипт / консоль или что-то еще ... Таким образом, вы можете запускать несколько команд в одном окне.

tail -f log/development.log &
script/console
Loading development environment (Rails 2.3.5)
>> Product.all
2011-03-10 11:56:00 18062 DEBUG  Product Load (6.0ms)  SELECT * FROM "products"
[<Product.1>,<Product.2>]

note Примечание Может быстро стать небрежным при большом объеме журналов.

Том Макельберге
источник