Posso configurar console.logpara que os logs sejam gravados em um arquivo em vez de serem impressos no console?
Posso configurar console.logpara que os logs sejam gravados em um arquivo em vez de serem impressos no console?
Respostas:
Atualização 2013 - Isso foi escrito em torno dos nós v0.2 e v0.4; Agora existem utilitários muito melhores para o registro. Eu recomendo Winston
Atualização no final de 2013 - Ainda usamos o winston, mas agora com uma biblioteca de criadores de log para envolver a funcionalidade no registro de objetos e formatação personalizados. Aqui está uma amostra do nosso logger.js https://gist.github.com/rtgibbons/7354879
Deve ser tão simples quanto isso.
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);ainda vai para o console, não para o arquivo.
process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })
Você também pode sobrecarregar a função console.log padrão:
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');
};
O exemplo acima registrará em debug.log e stdout.
Edit: Veja a versão multiparâmetros por Clément também nesta página.
Se você está procurando algo em produção, o winston é provavelmente a melhor escolha.
Se você quiser fazer coisas rapidamente com dev, envie diretamente para um arquivo (acho que isso funciona apenas para sistemas * nix):
nohup node simple-server.js > output.log &
>para redirecionar o STDOUT também funciona no Windows. nohupnão.
nohupno * nix, ie node simple-server.js > output.log. Então, se você gostaria de seguir o log como a sua escrita apenastail -f output.log
Costumo usar muitos argumentos para console.log () e console.error () , então minha solução seria:
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;
O Winston é um módulo npm muito popular usado para registro.
Aqui está um tutorial.
Instale o winston no seu projeto como:
npm install winston --save
Aqui está uma configuração pronta para usar pronta para usar que eu uso frequentemente em meus projetos como logger.js em 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
};
E então simplesmente importe onde for necessário, como este:
const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Então você pode registrar o sucesso como:
successlog.info(`Success Message and variables: ${variable}`);
e erros como:
errorlog.error(`Error Message : ${error}`);
Ele também registra todos os logs de êxito e erros em um arquivo no diretório logs em data, como você pode ver aqui.

winston& winston-daily-rotate-file) uma vez se as configurações estiverem corretas. Eles devem ser criados dentro de uma pasta nomeada logsno diretório raiz do projeto. Perdoe-me pela resposta atrasada.
const winston = require('winston'); const winstonRotator = require('winston-daily-rotate-file'); E const errorLog = require('../util/logger').errorlog; const successlog = require('../util/logger').successlog; onde você quiser 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 usá-lo, faça 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, apenas defina explicitamente this.errorapenas.
console.log. Ele muda seu comportamento, embora você possa restaurar o comportamento antigo chamando console.file().
Se isso é para um aplicativo, você provavelmente está melhor usando um módulo de log. Isso lhe dará mais flexibilidade. Algumas sugestões.
Outra solução ainda não mencionada é conectar os Writablefluxos em process.stdoute process.stderr. Dessa forma, você não precisa substituir todas as funções do console que geram stdout e stderr. Esta implementação redireciona stdout e stderr para um arquivo de log:
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')
Ele deve imprimir no console
a
b
c
d
e
f
e no arquivo de log:
c
d
Para mais informações, consulte esta essência .
Em casos simples, poderíamos redirecionar os fluxos de saída padrão (STDOUT) e erro padrão (STDERR) diretamente para o arquivo por '>' e '2> & 1'
Exemplo:
// 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");
})();
nó test.js> test.log 2> & 1
De acordo com o padrão POSIX, os fluxos 'input', 'output' e 'error' são identificados pelos descritores de arquivos inteiros positivos (0, 1, 2). ou seja, stdin é 0, stdout é 1 e stderr é 2.
'2> & 1' redirecionará de 2 (stderr) para 1 (stdout)
'>' será redirecionado de 1 (stdout) para o arquivo (test.log)
Substituir console.log é o caminho a percorrer. Mas para que ele funcione nos módulos necessários, você também precisa exportá-lo.
module.exports = console;
Para poupar o trabalho de gravar arquivos de log, girar e outras coisas, considere usar um módulo simples de logger como o 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 que module.exports?
MÉTODO STDOUT AND STDERR
Essa abordagem pode ajudá-lo (eu uso algo semelhante em meus projetos) e funciona para todos os métodos, incluindo console.log, console.warn, console.error, console.info
Este método grava os bytes escritos em stdout e stderr no arquivo. É melhor do que alterar os métodos console.log, console.warn, console.error, console.info, porque a saída será exatamente igual à saída dos 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)
Diretamente dos documentos da API do nodejs no 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
Agora você pode usar a Caterpillar, que é um sistema de registro baseado em fluxos, permitindo que você faça logon nele e depois canalize a saída para diferentes transformações e locais.
A saída para um arquivo é tão fácil quanto:
var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');
Exemplo completo no site da Caterpillar
Você também pode dar uma olhada neste módulo npm: https://www.npmjs.com/package/noogger
simples e direto ...
Tomei a ideia de trocar o fluxo de saída para o meu fluxo.
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;
Melhore em Andres Riofrio, para lidar com qualquer número 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');
};
Acabei de criar um pacote para fazer isso, espero que você goste;) https://www.npmjs.com/package/writelog
Eu, por mim mesmo, simplesmente peguei o exemplo do winston e adicionei o log(...)método (porque o winston o nomeia 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;
Em seguida, basta usar no seu código:
const console = require('Console')
Agora você pode simplesmente usar as funções normais de log no seu arquivo e ele criará um arquivo E registrará no seu console (durante a depuração / desenvolvimento). Por causa de if (process.env.NODE_ENV !== 'production') {(no caso de você querer também em produção) ...