pone vs logger en rieles tareas de rastrillo

108

En una tarea de rake, si utilizo el comando put, veo el resultado en la consola. Sin embargo, no veré ese mensaje en el archivo de registro cuando la aplicación se implemente en producción.

Sin embargo, si digo Rails.logger.info, en el modo de desarrollo no veo nada en la consola. Necesito ir al archivo de registro y seguirlo.

Idealmente, me gustaría usar Rails.logger.info y en el modo de desarrollo dentro de la tarea de rake, la salida del registrador también debe enviarse a la consola.

¿Hay alguna forma de lograrlo?

Nick Vanderbilt
fuente

Respuestas:

57

Pon esto en application.rb, o en una tarea de rake, inicializa el código

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

Este es el código de Rails 3. Tenga en cuenta que esto anulará el registro en development.log. Si desea ambos STDOUTy development.lognecesitará una función contenedora.

Si desea este comportamiento solo en la consola de Rails, coloque el mismo bloque de código en su ~/.irbrc.

shmichael
fuente
26
¿No sería más fácil simplemente poner Rails.logger = Logger.new(STDOUT)en desarrollo.rb?
ghempton
Para rieles 2, ponga esto en su desarrollo.rb:config.logger = Logger.new(STDOUT)
jsarma
38

Puede crear una nueva tarea de rake para que esto funcione.

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

De esta manera, cuando ejecuta su tarea de rake, puede agregar to_stdout primero para obtener los mensajes de registro de stdout o no incluirlo para que los mensajes se envíen al archivo de registro predeterminado

rake to_stdout some_task
Pete Brumm
fuente
11

Las tareas de rake las ejecuta un usuario, en una línea de comandos. Todo lo que necesiten saber de inmediato ("5 filas procesadas") debe enviarse al terminal con puts.

Todo lo que deba guardarse para la posteridad ("correo electrónico de advertencia enviado a [email protected]") debe enviarse a Rails.logger.

Jonathan Julian
fuente
17
No es raro ejecutar tareas de rake con cron.
Johannes Gorset
2
Cierto. Si desea que los mensajes de registro se le envíen por correo electrónico cuando se complete el trabajo cron, escúpelos en $ stdout o $ stderr.
Jonathan Julian
10

Yo diría que consumir Rails.logger.infoes el camino a seguir.

No podrá verlo en la consola del servidor porque no se ejecutará a través del servidor. Simplemente abra una nueva consola y tail -fel archivo de registro, funcionará.

Muchos usuarios conocen el comando 'tail' de UNIX®, que se puede utilizar para mostrar las últimas líneas de un archivo grande. Esto puede resultar útil para ver archivos de registro, etc.

Aún más útil en algunas situaciones, es el parámetro '-f' del comando 'tail'. Esto hace que tail "siga" la salida del archivo. Inicialmente, la respuesta será la misma que para 'tail' por sí sola: se mostrarán las últimas líneas del archivo. Sin embargo, el comando no regresa al indicador y, en cambio, continúa "siguiendo" el archivo. Cuando se agregan líneas adicionales al archivo, se mostrarán en el terminal. Esto es muy útil para ver archivos de registro o cualquier otro archivo que se pueda agregar con el tiempo. Escriba 'cola de hombre' para obtener más detalles sobre esta y otras opciones de cola.

( vía )

Marcgg
fuente
Pero no es muy cómodo mientras trabaja en la máquina local, ya que no ve la salida en la misma ventana donde llamó a la tarea. Especialmente si no tiene una pantalla grande para colocar varias ventanas una al lado de la otra.
Tomas Markauskas
10
Aún mejor es usar tailf"Es similar a tail -f pero no accede al archivo cuando no está creciendo" (desde la página de manual). También es más corto
MBO
@tomas, ¿por qué no minimizar la consola de registro del servidor y solo tener una consola con tail-f en ejecución? De todos modos, no es un problema real ... Estoy ejecutando como 8 consolas rastreando lo que está sucediendo en mi aplicación, simplemente cambie entre pestañas cuando esté trabajando en una parte específica del sistema, no es gran cosa, en mi humilde opinión
marcgg
@mbo agradables :) Halas que no parece que esté disponible en mi máquina (Mac OS @ leopardo)
marcgg
1
@marcgg: No tengo una "consola de servidor" (uso pasajero), pero la pregunta es sobre las tareas de rake y si ejecuta una tarea desde una ventana de terminal, no ve nada del registrador en esa ventana. Debe tener otra ventana con el archivo development.log para ver el resultado. Idealmente, agregaría stdout como otro flujo de salida a Rails.logger, pero no eliminaría el original.
Tomas Markauskas
9

Código

Para Rails 4 y posteriores, puede usar la transmisión de Logger .

Si desea obtener tanto STDOUT como el registro de archivos para tareas de rake en modo de desarrollo, puede agregar este código en 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

Prueba

Aquí hay una pequeña tarea de Rake para probar el código anterior:

# 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:testSalidas en ejecución

HELLO FROM PUTS
HELLO FROM LOGGER

mientras

HELLO FROM LOGGER

se ha agregado a log/development.log.

rake stdout_and_log:test RAILS_ENV=productionSalidas en ejecución

HELLO FROM PUTS

mientras

HELLO FROM LOGGER

se ha agregado a log/production.log.

Eric Duminil
fuente
En Rails 5, el basename($0) == 'rake'truco ya no funciona, porque railsse ejecuta el comando en sí rake. Me encantaría encontrar un buen reemplazo para él más allá de depender de una tarea que configure el broadcast. (Esa parte, al menos, todavía funciona bien.)
Brent Royal-Gordon
@ BrentRoyal-Gordon No hay necesidad de este condicional en el desarrollo, solo puede agregar el código a Rakefilela raíz de su proyecto
Mauricio Pasquier Juan
4

¿Qué tal crear un asistente de aplicación que detecte qué entorno se está ejecutando y hace lo correcto?

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

Luego llame a output_debug en lugar de put o logger.info

naven87
fuente
5
No creo que sea una buena idea. El registrador Rails está diseñado para ser configurable, pero en lugar de usar esa capacidad de configuración, solo está acumulando más capas encima.
Sijmen Mulder
Sí, no es una buena idea, ya que se realizará la misma verificación cada vez que desee registrar algo.
furiabhavesh
3

En Rails 2.X para redirigir el registrador a STDOUT en modelos:

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

Para redirigir el registrador en los controladores:

ActionController::Base.logger = Logger.new(STDOUT)
Tania R
fuente
También encontré este artículo, muy útil sepcot.com/blog/2009/08/rails-logging-to-stdout
Tania R
2

Ejecute un trabajo en segundo plano con '&' y abra el script / consola o lo que sea. De esa manera, puede ejecutar varios comandos en la misma ventana.

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 Puede volverse descuidado rápidamente cuando hay mucha salida de registro.

Tom Maeckelberghe
fuente