web-dev-qa-db-fra.com

Node: connecte un fichier à la place de la console

Puis-je configurer console.log pour que les journaux soient écrits sur un fichier au lieu d'être imprimés dans la console?

140
Randomblue

Mise à jour 2013 - Ceci a été écrit autour des nœuds v0.2 et v0.4; Il existe maintenant de bien meilleures utilisations pour la journalisation. Je recommande fortement Winston

Mise à jour, fin 2013 - Nous utilisons toujours winston, mais maintenant avec une bibliothèque de consignateurs pour regrouper les fonctionnalités relatives à la journalisation des objets personnalisés et à la mise en forme. Voici un échantillon de notre logger.js https://Gist.github.com/rtgibbons/7354879


Devrait être aussi simple que cela. 

var access = fs.createWriteStream(dir + '/node.access.log', { flags: 'a' })
      , error = fs.createWriteStream(dir + '/node.error.log', { flags: 'a' });

// redirect stdout / stderr
proc.stdout.pipe(access);
proc.stderr.pipe(error);
61
Ryan Gibbons

Vous pouvez également simplement surcharger la fonction console.log par défaut:

var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;

console.log = function(d) { //
  log_file.write(util.format(d) + '\n');
  log_stdout.write(util.format(d) + '\n');
};

L'exemple ci-dessus se connectera à debug.log et à stdout.

Edit:Voir la version multiparamètre de Clément également sur cette page.

156
ceeroover

Si vous recherchez quelque chose en production Winston est probablement le meilleur choix.

Si vous voulez juste faire rapidement du matériel de développement, exportez-le directement dans un fichier (je pense que cela ne fonctionne que pour les systèmes * nix):

Nohup node simple-server.js > output.log &
47
alessioalex

J'utilise souvent plusieurs arguments pour console.log () et console.error () , ma solution serait donc:

var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream('log.txt', { flags: 'a' });
  // Or 'w' to truncate the file every time the process starts.
var logStdout = process.stdout;

console.log = function () {
  logFile.write(util.format.apply(null, arguments) + '\n');
  logStdout.write(util.format.apply(null, arguments) + '\n');
}
console.error = console.log;
47
Clément Désiles

Winston est un module npm très populaire utilisé pour la journalisation. 

Voici un guide pratique.
Installez winston dans votre projet en tant que:

npm install winston --save

Voici une configuration prête à l'emploi que j'utilise fréquemment dans mes projets en tant que logger.js sous utils.

 /**
 * Configurations of logger.
 */
const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');

const consoleConfig = [
  new winston.transports.Console({
    'colorize': true
  })
];

const createLogger = new winston.Logger({
  'transports': consoleConfig
});

const successLogger = createLogger;
successLogger.add(winstonRotator, {
  'name': 'access-file',
  'level': 'info',
  'filename': './logs/access.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

const errorLogger = createLogger;
errorLogger.add(winstonRotator, {
  'name': 'error-file',
  'level': 'error',
  'filename': './logs/error.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

module.exports = {
  'successlog': successLogger,
  'errorlog': errorLogger
};

Et puis importez simplement là où vous le souhaitez:

const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;

Ensuite, vous pouvez enregistrer le succès en tant que:

successlog.info(`Success Message and variables: ${variable}`);

et des erreurs comme:

errorlog.error(`Error Message : ${error}`);

Il enregistre également tous les journaux de réussite et d’erreur dans un fichier sous le répertoire des journaux, comme vous pouvez le voir ici.
 log direcotry

24
keshavDulal
const fs = require("fs");
const {keys} = Object;
const {Console} = console;

/**
 * Redirect console to a file.  Call without path or with false-y
 * value to restore original behavior.
 * @param {string} [path]
 */
function file(path) {
    const con = path ? new Console(fs.createWriteStream(path)) : null;

    keys(Console.prototype).forEach(key => {
        if (path) {
            this[key] = (...args) => con[key](...args);
        } else {
            delete this[key];
        }
    });
};

// patch global console object and export
module.exports = console.file = file;

Pour l'utiliser, faites quelque chose comme:

require("./console-file");
console.file("/path/to.log");
console.log("write to file!");
console.error("also write to file!");
console.file();    // go back to writing to stdout
11
rich remer

S'il s'agit d'une application, il est probablement préférable d'utiliser un module de journalisation. Cela vous donnera plus de flexibilité. Quelques suggestions.

10
Marco

Une autre solution non encore mentionnée consiste à relier les flux Writable dans process.stdout et process.stderr. De cette façon, vous n'avez pas besoin de remplacer toutes les fonctions de la console cette sortie vers stdout et stderr. Cette implémentation redirige stdout et stderr vers un fichier journal:

var log_file = require('fs').createWriteStream(__dirname + '/log.txt', {flags : 'w'})

function hook_stream(stream, callback) {
    var old_write = stream.write

    stream.write = (function(write) {
        return function(string, encoding, fd) {
            write.apply(stream, arguments)  // comments this line if you don't want output in the console
            callback(string, encoding, fd)
        }
    })(stream.write)

    return function() {
        stream.write = old_write
    }
}

console.log('a')
console.error('b')

var unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

var unhook_stderr = hook_stream(process.stderr, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

console.log('c')
console.error('d')

unhook_stdout()
unhook_stderr()

console.log('e')
console.error('f')

Il faut imprimer dans la console

a
b
c
d
e
f

et dans le fichier journal:

c
d

Pour plus d'informations, cochez Gist .

3
reliasn

Écraser console.log est la voie à suivre. Mais pour que cela fonctionne dans les modules requis, vous devez également l'exporter.

module.exports = console;

Pour vous épargner le temps nécessaire à l'écriture des fichiers journaux, à la rotation et à d'autres tâches, vous pouvez envisager d'utiliser un simple module de journalisation comme winston:

// Include the logger module
var winston = require('winston');
// Set up log file. (you can also define size, rotation etc.)
winston.add(winston.transports.File, { filename: 'somefile.log' });
// Overwrite some of the build-in console functions
console.error=winston.error;
console.log=winston.info;
console.info=winston.info;
console.debug=winston.debug;
console.warn=winston.warn;
module.exports = console;
3
Simon Rigét

Directement des documents API de nodejs sur Console

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
const count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5
1
Mr. 14

METHODE STDOUT ET STDERR

Cette approche peut vous aider (j'utilise quelque chose de similaire dans mes projets) et fonctionne pour toutes les méthodes, y compris console.log, console.warn, console.error, console.info

Cette méthode écrit les octets écrits dans stdout et stderr dans un fichier. C'est mieux que de changer les méthodes console.log, console.warn, console.error, console.info, car la sortie sera exactement la même que la sortie de cette méthode


var fs= require("fs")
var os= require("os")
var HOME= os.homedir()
var stdout_r = fs.createWriteStream(HOME + '/node.stdout.log', { flags: 'a' })
var stderr_r = fs.createWriteStream(HOME + '/node.stderr.log', { flags: 'a' })

var attachToLog= function(std, std_new){

    var originalwrite= std.write
    std.write= function(data,enc){
        try{
            var d= data
            if(!Buffer.isBuffer(d))
                d= Buffer.from(data, (typeof enc === 'string') ? enc : "utf8")
            std_new.write.apply(std_new, d)
        }catch(e){}
        return originalwrite.apply(std, arguments)
    }


}
attachToLog(process.stdout, stdout_r)
attachToLog(process.stderr, stderr_r)

// recommended catch error on stdout_r and stderr_r
// stdout_r.on("error", yourfunction)
// stderr_r.on("error", yourfunction)

Vous pouvez maintenant utiliser Caterpillar , un système de journalisation basé sur les flux, vous permettant de vous connecter à ce dernier, puis de diriger la sortie vers différents transformations et emplacements.

La sortie dans un fichier est aussi simple que:

var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');

Exemple complet sur le site Web Caterpillar

1
balupton

J'ai eu l'idée de permuter le flux de sortie en un flux.

const LogLater                = require ('./loglater.js');
var logfile=new LogLater( 'log'+( new Date().toISOString().replace(/[^a-zA-Z0-9]/g,'-') )+'.txt' );


var PassThrough = require('stream').PassThrough;

var myout= new PassThrough();
var wasout=console._stdout;
myout.on('data',(data)=>{logfile.dateline("\r\n"+data);wasout.write(data);});
console._stdout=myout;

var myerr= new PassThrough();
var waserr=console._stderr;
myerr.on('data',(data)=>{logfile.dateline("\r\n"+data);waserr.write(data);});
console._stderr=myerr;

loglater.js:

const fs = require('fs');

function LogLater(filename, noduplicates, interval) {
    this.filename = filename || "loglater.txt";
    this.arr = [];
    this.timeout = false;
    this.interval = interval || 1000;
    this.noduplicates = noduplicates || true;
    this.onsavetimeout_bind = this.onsavetimeout.bind(this);
    this.lasttext = "";
    process.on('exit',()=>{ if(this.timeout)clearTimeout(this.timeout);this.timeout=false; this.save(); })
}

LogLater.prototype = {
    _log: function _log(text) {
        this.arr.Push(text);
        if (!this.timeout) this.timeout = setTimeout(this.onsavetimeout_bind, this.interval);
    },
    text: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text);
    },
    line: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text + '\r\n');
    },
    dateline: function dateline(text) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(((new Date()).toISOString()) + '\t' + text + '\r\n');
    },
    onsavetimeout: function onsavetimeout() {
        this.timeout = false;
        this.save();
    },
    save: function save() { fs.appendFile(this.filename, this.arr.splice(0, this.arr.length).join(''), function(err) { if (err) console.log(err.stack) }); }
}

module.exports = LogLater;
0
Shimon Doodkin

Pour des cas simples, nous pourrions rediriger les flux Standard Out (STDOUT) et Standard Error (STDERR) vers un fichier par> et 2> & 1

Exemple:

(function() {
    // Below outputs are sent to Standard Out (STDOUT) stream
    console.log("Hello Log");
    console.info("Hello Info");
    // Below outputs are sent to Standard Error (STDERR) stream
    console.error("Hello Error");
    console.warn("Hello Warning");
})();

noeud test.js> test.log 2> & 1

Selon le standard POSIX, les flux 'input', 'output' et 'error' sont identifiés par l'entier positifdes descripteurs de fichier(0, 1, 2). c'est-à-dire, stdin est 0, stdout est 1 et stderr est 2.  

'2> & 1' redirigera 2 (stderr) vers 1 (stdout)

'>' va rediriger 1 (stdout) vers le fichier

0
SridharKritha

Pour ma part, j’ai simplement pris l’exemple de Winston et ajouté la méthode log(...) (parce que Winston l’appelle info(..):

Console.js:

"use strict"

// Include the logger module
const winston = require('winston');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
        //
        // - Write to all logs with level `info` and below to `combined.log`
        // - Write all logs error (and below) to `error.log`.
        //
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' })
    ]
});

//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
    logger.add(new winston.transports.Console({
        format: winston.format.simple()
    }));
}

// Add log command
logger.log=logger.info;

module.exports = logger;

Ensuite, utilisez simplement dans votre code:

const console = require('Console')

Maintenant, vous pouvez simplement utiliser les fonctions de journal normales dans votre fichier et il va créer un fichier ET le connecter à votre console (pendant le débogage/développement). En raison de if (process.env.NODE_ENV !== 'production') { (au cas où vous le voudriez aussi en production) ...

0
TechupBusiness

Je viens de construire un pack pour le faire, j'espère que vous l'aimerez;) https://www.npmjs.com/package/writelog

0
Phung Thang

Vous pouvez également consulter le module npm suivant: https://www.npmjs.com/package/noogger

noogger

simple et direct ...

0
Xsmael

Améliorer sur Andres Riofrio, pour gérer un nombre quelconque d'arguments

var fs = require('fs');
var util = require('util');

var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;

console.log = function(...args) {
    var output = args.join(' ');
    log_file.write(util.format(output) + '\r\n');
    log_stdout.write(util.format(output) + '\r\n');
};
0
Liran BarNiv