¿Puedo configurar console.logpara que los registros se escriban en un archivo en lugar de imprimirse en la consola?
¿Puedo configurar console.logpara que los registros se escriban en un archivo en lugar de imprimirse en la consola?
Respuestas:
Actualización 2013: esto se escribió alrededor del Nodo v0.2 y v0.4; Hay utilidades mucho mejores ahora alrededor del registro. Recomiendo mucho Winston
Actualización a fines de 2013: todavía usamos winston, pero ahora con una biblioteca de registradores para ajustar la funcionalidad en torno al registro de objetos personalizados y el formato. Aquí hay una muestra de nuestro logger.js https://gist.github.com/rtgibbons/7354879
Debería ser tan simple como esto.
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);
console.log(whatever);Todavía va a la consola, no al archivo.
process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })
También podría sobrecargar la función predeterminada console.log:
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');
};
El ejemplo anterior se registrará en debug.log y stdout.
Editar: Vea la versión multiparamétrica de Clément también en esta página.
Si está buscando algo en producción, Winston es probablemente la mejor opción.
Si solo quiere hacer cosas de desarrollo rápidamente, envíe directamente a un archivo (creo que esto funciona solo para sistemas * nix):
nohup node simple-server.js > output.log &
>para redirigir STDOUT también funciona en Windows. nohupno lo hace
nohup* nix, es decir node simple-server.js > output.log. Entonces, si desea seguir el registro tal como está escritotail -f output.log
A menudo uso muchos argumentos para console.log () y console.error () , por lo que mi solución sería:
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;
Winston es un módulo npm muy popular utilizado para el registro.
Aquí hay un tutorial.
Instale winston en su proyecto como:
npm install winston --save
Aquí hay una configuración lista para usar lista para usar que uso con frecuencia en mis proyectos como logger.js en 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
};
Y luego simplemente importe donde sea necesario como esto:
const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Entonces puede registrar el éxito como:
successlog.info(`Success Message and variables: ${variable}`);
y errores como:
errorlog.error(`Error Message : ${error}`);
También registra todos los registros de éxito y de error en un archivo en el directorio de registros según la fecha, como puede ver aquí.

winston& winston-daily-rotate-file) una vez si las configuraciones están bien. Deben crearse dentro de una carpeta nombrada logsen el directorio raíz del proyecto. Perdón por la respuesta tardía.
const winston = require('winston'); const winstonRotator = require('winston-daily-rotate-file'); Y const errorLog = require('../util/logger').errorlog; const successlog = require('../util/logger').successlog; donde quieras registrar algo.
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;
Para usarlo, haga algo como:
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
Console.prototypeteclas, solo configúrelas explícitamente this.error.
console.log . Cambia su comportamiento, aunque puede restaurar el comportamiento anterior llamando console.file().
Si esto es para una aplicación, probablemente sea mejor usar un módulo de registro. Te dará más flexibilidad. Algunas sugerencias.
Otra solución que aún no se menciona es enganchar las Writablesecuencias en process.stdouty process.stderr. De esta manera, no necesita anular todas las funciones de la consola que salen a stdout y stderr. Esta implementación redirige tanto stdout como stderr a un archivo de registro:
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')
Debería imprimir en la consola
a
b
c
d
e
f
y en el archivo de registro:
c
d
Para obtener más información, consulte esta esencia .
Para casos simples, podríamos redirigir las secuencias de Salida estándar (STDOUT) y Error estándar (STDERR) directamente al archivo mediante '>' y '2> & 1'
Ejemplo:
// test.js
(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");
})();
nodo test.js> test.log 2> & 1
Según el estándar POSIX, los flujos de 'entrada', 'salida' y 'error' se identifican mediante los descriptores de archivo entero positivo (0, 1, 2). es decir, stdin es 0, stdout es 1 y stderr es 2.
'2> & 1' redirigirá de 2 (stderr) a 1 (stdout)
'>' redirigirá desde 1 (stdout) al archivo (test.log)
Sobrescribir console.log es el camino a seguir. Pero para que funcione en los módulos necesarios, también debe exportarlo.
module.exports = console;
Para ahorrarse la molestia de escribir archivos de registro, rotar y demás, puede considerar usar un módulo de registro simple como 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;
globalobjeto. ¿por qué module.exports?
MÉTODO STDOUT Y STDERR
Este enfoque puede ayudarlo (uso algo similar en mis proyectos) y funciona para todos los métodos, incluidos console.log, console.warn, console.error, console.info
Este método escribe los bytes escritos en stdout y stderr en el archivo. Es mejor que cambiar los métodos console.log, console.warn, console.error, console.info, porque la salida será exactamente la misma que la salida de estos métodos
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)
Directamente desde los documentos API de nodejs en la consola
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
Ahora puedes usar Caterpillar que es un sistema de registro basado en flujos, que le permite iniciar sesión en él y luego canalizar la salida a diferentes transformaciones y ubicaciones.
La salida a un archivo es tan fácil como:
var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');
Ejemplo completo en el sitio web de Caterpillar
También puede echar un vistazo a este módulo npm: https://www.npmjs.com/package/noogger
simple y directo ...
Asumí la idea de cambiar la secuencia de salida a mi secuencia.
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;
Mejora en Andres Riofrio, para manejar cualquier cantidad de argumentos
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');
};
Acabo de construir un paquete para hacer esto, espero que les guste;) https://www.npmjs.com/package/writelog
Yo mismo simplemente tomé el ejemplo de Winston y agregué el log(...)método (porque Winston lo nombrainfo(..) :
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;
Luego simplemente use en su código:
const console = require('Console')
Ahora puede simplemente usar las funciones de registro normales en su archivo y creará un archivo Y lo registrará en su consola (mientras se depura / desarrolla). Debido a if (process.env.NODE_ENV !== 'production') {(en caso de que lo desee también en producción) ...