met vs logger dans les tâches de râteau de rails

108

Dans une tâche rake, si j'utilise la commande met, je vois la sortie sur la console. Cependant, je ne verrai pas ce message dans le fichier journal lorsque l'application est déployée en production.

Cependant si je dis Rails.logger.info alors en mode développement je ne vois rien sur la console. Je dois aller au fichier journal et le suivre.

Je voudrais idéalement utiliser Rails.logger.info et en mode développement dans la tâche rake, la sortie de l'enregistreur devrait également être envoyée à la console.

Y a-t-il un moyen d'y parvenir?

Nick Vanderbilt
la source

Réponses:

57

Mettez ceci dans application.rb, ou dans une tâche rake, initialisez le code

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

Il s'agit du code Rails 3. Notez que cela remplacera la journalisation dans development.log. Si vous voulez les deux STDOUTet que development.logvous aurez besoin d'une fonction wrapper.

Si vous souhaitez ce comportement uniquement dans la console Rails, placez le même bloc de code dans votre fichier ~/.irbrc.

Shmichael
la source
26
Ne serait-il pas plus facile de simplement mettre Rails.logger = Logger.new(STDOUT)development.rb?
ghempton
Pour les rails 2, mettez ceci dans votre development.rb:config.logger = Logger.new(STDOUT)
jsarma
38

Vous pouvez créer une nouvelle tâche de râteau pour que cela fonctionne.

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

De cette façon, lorsque vous exécutez votre tâche rake, vous pouvez d'abord ajouter to_stdout pour obtenir les messages du journal stdout ou ne pas l'inclure pour que les messages soient envoyés au fichier journal par défaut

rake to_stdout some_task
Pete Brumm
la source
11

Les tâches de rake sont exécutées par un utilisateur, sur une ligne de commande. Tout ce qu'ils ont besoin de savoir immédiatement ("traité 5 lignes") doit être affiché sur le terminal avecputs .

Tout ce qui doit être conservé pour la postérité ("e-mail d'avertissement envoyé à [email protected]") doit être envoyé au Rails.logger.

Jonathan Julian
la source
17
Il n'est pas rare d'exécuter des tâches de rake avec cron.
Johannes Gorset
2
Vrai. Si vous souhaitez que les messages du journal vous soient envoyés par e-mail lorsque la tâche cron est terminée, crachez-les dans $ stdout ou $ stderr.
Jonathan Julian
10

Je dirais que l'utilisation Rails.logger.infoest la voie à suivre.

Vous ne pourrez pas le voir dans la console du serveur car il ne fonctionnera pas via le serveur. Ouvrez simplement une nouvelle console et tail -fle fichier journal, cela fera l'affaire.

De nombreux utilisateurs connaissent la commande UNIX® 'tail', qui peut être utilisée pour afficher les dernières lignes d'un gros fichier. Cela peut être utile pour afficher les fichiers journaux, etc.

Le paramètre «-f» de la commande «tail» est encore plus utile dans certaines situations. Cela fait que tail «suit» la sortie du fichier. Au départ, la réponse sera la même que pour 'tail' seul - les dernières lignes du fichier seront affichées. Cependant, la commande ne revient pas à l'invite et continue à «suivre» le fichier. Lorsque des lignes supplémentaires sont ajoutées au fichier, elles seront affichées sur le terminal. Ceci est très utile pour regarder les fichiers journaux, ou tout autre fichier qui peut être ajouté au fil du temps. Tapez 'man tail' pour plus de détails à ce sujet et sur d'autres options de queue.

( via )

Marcgg
la source
Mais ce n'est pas très confortable lorsque vous travaillez sur la machine locale car vous ne voyez pas la sortie dans la même fenêtre où vous avez appelé la tâche. Surtout si vous ne disposez pas d'un grand écran pour accueillir plusieurs fenêtres côte à côte.
Tomas Markauskas
10
Mieux encore, utilisez tailf"Il est similaire à tail -f mais n'accède pas au fichier lorsqu'il ne grandit pas" (depuis la page de manuel). Il est aussi plus court
MBO
@tomas pourquoi ne pas minimiser la console de journal du serveur et n'avoir qu'une seule console avec le tail-f en cours d'exécution? Quoi qu'il en soit, ce n'est pas un vrai problème ... Je cours comme 8 consoles traçant ce qui se passe dans mon application, il suffit de basculer entre les onglets lorsque vous travaillez sur une partie spécifique du système, pas grand-chose à mon humble avis
marcgg
@mbo nice :) halas il ne semble pas être disponible sur ma machine (mac os @ leopard)
marcgg
1
@marcgg: Je n'ai pas de "console serveur" (j'utilise passager), mais la question concerne les tâches de rake et si vous exécutez une tâche à partir d'une fenêtre de terminal, vous ne voyez rien de l'enregistreur dans cette fenêtre. Vous devez avoir une autre fenêtre avec le development.log pour voir la sortie. Idéalement, j'ajouterais en quelque sorte stdout comme un autre flux de sortie à Rails.logger, mais je ne supprimerais pas l'original.
Tomas Markauskas
9

Code

Pour les Rails 4 et plus récents, vous pouvez utiliser la diffusion Logger .

Si vous souhaitez obtenir à la fois STDOUT et la journalisation des fichiers pour les tâches de rake en mode développement, vous pouvez ajouter ce code dans 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

Tester

Voici une petite tâche Rake pour tester le code ci-dessus:

# 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

Exécution des rake stdout_and_log:testsorties

HELLO FROM PUTS
HELLO FROM LOGGER

tandis que

HELLO FROM LOGGER

a été ajouté à log/development.log.

Exécution des rake stdout_and_log:test RAILS_ENV=productionsorties

HELLO FROM PUTS

tandis que

HELLO FROM LOGGER

a été ajouté à log/production.log.

Eric Duminil
la source
Dans Rails 5, l' basename($0) == 'rake'astuce ne fonctionne plus, car la railscommande elle-même s'exécute rake. J'adorerais trouver un bon remplacement pour cela au-delà de la tâche qui configure le broadcast. (Cette partie, au moins, fonctionne toujours bien.)
Brent Royal-Gordon
@ BrentRoyal-Gordon Il n'y a pas besoin de ce conditionnel en développement, vous pouvez simplement ajouter le code Rakefileà la racine de votre projet
Mauricio Pasquier Juan
4

Que diriez-vous de créer un assistant d'application qui détecte quel environnement est en cours d'exécution et fait ce qu'il faut?

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

Appelez ensuite output_debug au lieu de put ou logger.info

naven87
la source
5
Je ne pense pas que ce soit une bonne idée. L'enregistreur Rails est censé être configurable, mais au lieu d'utiliser cette configurabilité, vous empilez simplement plus de couches dessus ici.
Sijmen Mulder
Oui, ce n'est pas une bonne idée car la même vérification sera effectuée chaque fois que vous souhaitez enregistrer quelque chose.
furiabhavesh
3

Dans Rails 2.X pour rediriger l'enregistreur vers STDOUT dans les modèles:

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

Pour rediriger l'enregistreur dans les contrôleurs:

ActionController::Base.logger = Logger.new(STDOUT)
Tania R
la source
J'ai aussi trouvé cet article, très utile sepcot.com/blog/2009/08/rails-logging-to-stdout
Tania R
2

Exécutez un travail d'arrière-plan avec '&' et ouvrez le script / la console ou autre. De cette façon, vous pouvez exécuter plusieurs commandes dans la même fenêtre.

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 Peut devenir rapidement bâclé lorsqu'il y a beaucoup de sortie de journalisation.

Tom Maeckelberghe
la source