2010-02-11 8 views
88

Dans une tâche rake si j'utilise la commande puts, 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.puts vs logger dans les rails rake tasks

Cependant si je dis Rails.logger.info alors en mode développement je ne vois rien sur la console. Je dois aller au dossier de journal et la queue cela.

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

Existe-t-il un moyen d'y parvenir?

+2

+1 Je voulais juste poser la même question. –

Répondre

9

Je dirais que l'utilisation de Rails.logger.info est la voie à suivre.

Vous ne pourrez pas le voir dans la console du serveur car il ne fonctionnera pas via le serveur. Il suffit d'ouvrir une nouvelle console et tail -f le fichier journal, ça va faire l'affaire.

De nombreux utilisateurs sont conscients de la commande « queue » UNIX® , qui peut être utilisé pour affichage les dernières lignes d'un fichier volumineux . Cela peut être utile pour l'affichage fichiers journaux, etc.

encore plus utile dans certaines situations, est le paramètre « -f » à la commande « queue » . Cela provoque la queue à «suivre» la sortie du fichier. Initialement, la réponse sera la même que pour 'queue' seule - les dernières lignes du fichier seront affichées. Cependant, la commande ne renvoie pas à l'invite et continue à la place pour 'suivre' le fichier. Lorsque des lignes supplémentaires sont ajoutées au fichier, elles seront affichées sur le terminal . C'est très utile pour regarder les fichiers journaux, ou tout autre fichier qui peut être ajouté au fil du temps. Tapez 'queue de l'homme »pour plus de détails sur cette queue et d'autres options .

(via)

+0

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 n'avez pas un grand écran pour s'adapter à plusieurs fenêtres côte à côte. –

+9

Encore mieux est d'utiliser 'tailf'" Il est similaire à tail -f mais n'accède pas au fichier quand il ne grandit pas "(de manpage). Il est aussi plus court – MBO

+0

@tomas pourquoi ne pas minimiser la console du journal du serveur et avoir seulement une 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 en 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 de problème – marcgg

10

tâches Rake sont gérées par un utilisateur, sur une ligne de commande. Tout ce qu'ils doivent savoir tout de suite ("5 lignes traitées") doit être sorti sur le terminal avec puts.

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

+11

Il n'est pas rare d'exécuter des tâches de rake avec cron. –

+2

True. Si vous souhaitez que les messages de journal vous soient envoyés par e-mail lorsque le travail cron est terminé, crachez-les dans $ stdout ou $ stderr. –

3

Que diriez-vous de créer un assistant d'application qui détecte quel environnement s'exécute et fait la bonne chose?

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

appellent ensuite output_debug au lieu de puts ou Logger.INFO

+4

Je ne pense pas que ce soit une bonne idée. L'enregistreur Rails est conçu pour être configurable, mais au lieu d'utiliser cette configurabilité, vous empilez simplement plus de couches par-dessus. –

+0

Oui, ce n'est pas une bonne idée puisque la même vérification sera faite * chaque fois que vous voulez enregistrer quelque chose. – furiabhavesh

46

Mettre cela en application.rb, ou dans une tâche de râteau initialize Code

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

Ceci est Rails 3 code. Notez que cela annulera la journalisation à development.log.Si vous voulez à la fois STDOUT et development.log vous 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 ~/.irbrc.

+1

Comment est-ce que je fais cela dans les rails 2? – Joelio

+23

Ne serait-il pas plus facile de simplement mettre Rails.logger = Logger.new (STDOUT) 'dans development.rb? – ghempton

+0

Pour les rails 2, mettez ceci dans votre development.rb: 'config.logger = Logger.new (STDOUT)' – jsarma

1

Exécuter un travail d'arrière-plan avec '&' et ouvrir un script/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 obtenir bâclée rapidement quand il y a beaucoup de la production forestière.

2

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

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

Pour rediriger logger dans les contrôleurs:

ActionController::Base.logger = Logger.new(STDOUT) 
+0

J'ai aussi trouvé cet article, très utile http://www.sepcot.com/blog/2009/08/ rails-logging-to-stdout –

24

Vous pouvez créer une nouvelle tâche de râteau pour obtenir ce travail .

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 de rake que vous pouvez ajouter to_stdout premier à obtenir stdout messages journaux ou ne comprennent pas les messages sont envoyés au fichier journal par défaut

rake to_stdout some_task 
+0

excellente idée! –

2

code

Pour Rails 4 et plus récent, vous pouvez utiliser Logger broadcast.

Si vous voulez obtenir le STDOUT et l'enregistrement de fichiers pour des tâches de râteau en mode de 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 

test

Voici une petite tâche Rake pour tester ce qui précède Code:

# 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 rake stdout_and_log:test sorties

HELLO FROM PUTS 
HELLO FROM LOGGER 

tout

HELLO FROM LOGGER 

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

en cours rake stdout_and_log:test RAILS_ENV=production sorties

HELLO FROM PUTS 

tout

HELLO FROM LOGGER 

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

+0

Dans Rails 5, l'astuce 'basename ($ 0) == 'rake'' ne fonctionne plus, car la commande' rails' elle-même exécute 'rake'. J'aimerais trouver un bon remplacement au-delà en fonction d'une tâche qui met en place la «diffusion». (Cette partie, au moins, fonctionne toujours bien.) –