web-dev-qa-db-fra.com

Redirection de stdout vers le fichier nodejs

J'ai créé:

var access = fs.createWriteStream('/var/log/node/api.access.log', { flags: 'w' });

Puis canalisé:

process.stdout.pipe(access);

Puis essayé:

console.log("test");

Et rien ne figure dans /var/log/node/api.access.log. Cependant, cette méthode fonctionne:

process.stdout.pipe(access).write('test');

Quelqu'un pourrait-il expliquer ce que je fais mal?

15
Supervision

J'ai résolu ce problème de la manière suivante:

var access = fs.createWriteStream('/var/log/node/api.access.log');
process.stdout.write = process.stderr.write = access.write.bind(access);

Bien sûr, vous pouvez également séparer stdout et stderr si vous le souhaitez.

Je recommande également fortement de gérer les exceptions non capturées:

process.on('uncaughtException', function(err) {
  console.error((err && err.stack) ? err.stack : err);
});

Cela couvrira les situations suivantes:

  • process.stdout.write
  • process.stderr.write
  • console.log
  • console.dir
  • console.error
  • someStream.pipe (process.stdout);
  • lancer une nouvelle erreur ('Crash');
  • lance 'ne fais jamais ça';
  • jeter non défini;
23
user3173842

Checkout console.Console, la classe parente de la console normale. 

var myLogFileStream = fs.createWriteStream(pathToMyLogFile);

var myConsole = new console.Console(myLogFileStream, myLogFileStream);

Vous pouvez ensuite utiliser myConsole.log, myConsole.error, myConsole.dir, etc. et écrire directement dans votre fichier.

Vous pouvez également monkey patchprocess.stdout.write comme suit: 

var fn = process.stdout.write;

function write() {
  fn.apply(process.stdout, arguments);
  myLogFileStream.write.apply(myLogFileStream, arguments);
}

process.stdout.write = write;

il existe également d'autres options pour écraser console._stdout en fonction de la motivation pour consigner la stdout dans un fichier. 

3
richardpringle

process.stdout est un enregistrable. pipe est une méthode de Readable (documentation C StreamAPI: https://nodejs.org/api/stream.html

Vous pouvez voir la documentation de process.stdout ici: https://nodejs.org/api/process.html#process_process_stdout

Il est surprenant que vous puissiez faire process.stdout.pipe(...); sans erreur. Mais je suppose que cet appel ne fait rien. Excepté le renvoi d'un nouveau flux enregistrable lié à stdout (ou peut-être qu'il renvoie process.stdout lui-même. Il n'y a aucune spécification à ce sujet dans la documentation).

Si vous voulez rediriger stdout vers un fichier, vous avez plusieurs solutions:

  • Utilisez simplement votre ligne de commande pour le faire. Style Windows: node myfile.js > api.access.log.
  • Remplacez l'objet console par votre propre objet. Et vous pouvez réécrire les méthodes de la console.
  • Je ne suis pas sûr, mais il est peut-être possible de remplacer process.stdout par votre propre flux (et vous pouvez faire ce que vous voulez avec cela).
2
Magus

@ user3173842 pour la réponse sur J'ai résolu ce problème de la manière suivante:

var access = fs.createWriteStream('/var/log/node/api.access.log');
process.stdout.write = process.stderr.write = access.write.bind(access);

vous comprenez bien que process.stdout continue après process.on('exit') et que, par conséquent, fs.WriteStream se ferme après avec process.stdout, selon https://github.com/nodejs/node/issues/7606

la question demeure donc, si le développeur souhaitait que la fonction fs.Writestream.write() retrouve ses fonctionnalités normales et que fs.Writestream.end soit appelé, le programme Writestream se ferme. Comment le développeur s'y prendrait-il?

a_l = asyncify_listener
p_std_stream_m is a process stream manager object

p_std_stream_m.std_info.p_stdout_write = process.stdout.write   

process.stdout.write = w_stream.write.bind(w_stream)

process.once('beforeExit', a_l(   p_std_stream_m.handler,process.stdout,w_stream   )   )       

     where in the 'beforeExit' event listener I did
process.stdout.write = p_std_stream_m.std_info.p_stdout_write

w_stream.end()

Cela fonctionne et vous utilisez la méthode once car le process.stdout semble faire beaucoup de travail à l'heure actuelle ... est-ce une bonne pratique, voudriez-vous faire ceci ou que feriez-vous dans cette situation ... Tout le monde peut se sentir libre de répondre.

0
MIchael Odumosu