Czy mogę skonfigurować console.logtak, aby dzienniki były zapisywane w pliku zamiast drukować w konsoli?
Czy mogę skonfigurować console.logtak, aby dzienniki były zapisywane w pliku zamiast drukować w konsoli?
Odpowiedzi:
Aktualizacja 2013 - została napisana wokół Node v0.2 i v0.4; Wokół logowania jest teraz dużo lepszych narzędzi. Bardzo polecam Winston
Aktualizacja pod koniec 2013 r. - Nadal używamy winston, ale teraz z biblioteką rejestratora, aby zawinąć funkcjonalność wokół rejestrowania niestandardowych obiektów i formatowania. Oto próbka naszego logger.js https://gist.github.com/rtgibbons/7354879
Powinno być takie proste.
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);nadal idzie do konsoli, a nie do pliku.
process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })
Możesz także po prostu przeładować domyślną funkcję 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');
};
Powyższy przykład będzie logował się do debug.log i stdout.
Edycja: Zobacz wersję wieloparametrową Clémenta również na tej stronie.
Jeśli szukasz czegoś w produkcji, winston jest prawdopodobnie najlepszym wyborem.
Jeśli chcesz po prostu szybko robić rzeczy deweloperskie, wyślij bezpośrednio do pliku (myślę, że działa to tylko w systemach * nix):
nohup node simple-server.js > output.log &
>z przekierowania STDOUT działa również w systemie Windows. nohupnie.
nohupon * nix, tj node simple-server.js > output.log. W takim razie, jeśli chcesz śledzić dziennik tak, jak jest napisanytail -f output.log
Często używam wielu argumentów do console.log () i console.error () , więc moim rozwiązaniem byłoby:
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 to bardzo popularny moduł npm używany do logowania.
Oto instrukcja.
Zainstaluj Winston w swoim projekcie jako:
npm install winston --save
Oto konfiguracja gotowa do użycia po wyjęciu z pudełka, której często używam w moich projektach jako logger.js w ramach narzędzi.
/**
* 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
};
A następnie po prostu zaimportuj w dowolnym miejscu:
const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Następnie możesz zarejestrować sukces jako:
successlog.info(`Success Message and variables: ${variable}`);
i błędy jak:
errorlog.error(`Error Message : ${error}`);
Rejestruje również wszystkie dzienniki sukcesów i dzienniki błędów w pliku w katalogu dzienników według daty, jak widać tutaj.

winston& winston-daily-rotate-file) raz, jeśli konfiguracja jest w porządku. Powinny zostać utworzone w folderze o nazwie logsw katalogu głównym projektu. Przepraszam za opóźnioną odpowiedź.
const winston = require('winston'); const winstonRotator = require('winston-daily-rotate-file'); i const errorLog = require('../util/logger').errorlog; const successlog = require('../util/logger').successlog; wszędzie tam, gdzie chcesz coś zarejestrować.
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;
Aby go użyć, zrób coś takiego:
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.prototypekluczy, po prostu jawnie ustaw this.errortylko.
console.log. Zmienia swoje zachowanie, chociaż możesz przywrócić stare zachowanie, dzwoniąc console.file().
Jeśli dotyczy to aplikacji, prawdopodobnie lepiej będzie użyć modułu logowania. Zapewni Ci większą elastyczność. Jakieś sugestie.
Innym rozwiązaniem, o którym jeszcze nie wspomniano, jest podpięcie Writablestrumieni do process.stdouti process.stderr. W ten sposób nie musisz nadpisywać wszystkich funkcji konsoli, które wyświetlają dane wyjściowe na stdout i stderr. Ta implementacja przekierowuje zarówno stdout, jak i stderr do pliku dziennika:
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')
Powinien wydrukować się w konsoli
a
b
c
d
e
f
aw pliku dziennika:
c
d
Aby uzyskać więcej informacji, zapoznaj się z tym streszczeniem .
W prostych przypadkach możemy przekierować strumienie Standard Out (STDOUT) i Standard Error (STDERR) bezpośrednio do pliku za pomocą „>” i „2> & 1”
Przykład:
// 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");
})();
node test.js> test.log 2> & 1
Zgodnie ze standardem POSIX, strumienie „wejścia”, „wyjścia” i „błędu” są identyfikowane przez deskryptory plików z dodatnimi liczbami całkowitymi (0, 1, 2). tj. stdin to 0, stdout to 1, a stderr to 2.
„2> & 1” przekieruje z 2 (stderr) do 1 (stdout)
'>' przekieruje z 1 (stdout) do pliku (test.log)
Nadpisanie console.log jest drogą do zrobienia. Ale aby działał w wymaganych modułach, musisz go również wyeksportować.
module.exports = console;
Aby zaoszczędzić sobie kłopotów z zapisywaniem plików dziennika, obracaniem i innymi rzeczami, możesz rozważyć użycie prostego modułu rejestratora, takiego jak 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;
globalobiekcie. dlaczego module.exports?
METODA STDOUT I STDERR
To podejście może ci pomóc (używam czegoś podobnego w moich projektach) i działa dla wszystkich metod, w tym console.log, console.warn, console.error, console.info
Ta metoda zapisuje bajty zapisane w stdout i stderr do pliku. Jest lepsze niż zmiana metod console.log, console.warn, console.error, console.info, ponieważ dane wyjściowe będą dokładnie takie same, jak te metody.
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)
Prosto z dokumentacji API nodejs na konsoli
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
Możesz teraz używać Caterpillar, który jest systemem rejestrowania opartym na strumieniach, umożliwiającym logowanie się do niego, a następnie przesyłanie danych wyjściowych do różnych transformacji i lokalizacji.
Wyprowadzanie do pliku jest tak proste, jak:
var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');
Pełny przykład w witrynie internetowej firmy Caterpillar
Możesz również rzucić okiem na ten moduł npm: https://www.npmjs.com/package/noogger
proste i proste ...
Podjąłem pomysł zamiany strumienia wyjściowego na mój strumień.
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;
Ulepsz Andres Riofrio, aby obsłużyć dowolną liczbę argumentów
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');
};
Po prostu zbudowałem pakiet, aby to zrobić, mam nadzieję, że ci się spodoba;) https://www.npmjs.com/package/writelog
Ja dla siebie po prostu wziąłem przykład z winstona i dodałem log(...)metodę (ponieważ winston nazywa ją 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;
Następnie po prostu użyj w swoim kodzie:
const console = require('Console')
Teraz możesz po prostu użyć normalnych funkcji dziennika w swoim pliku, a utworzy on plik ORAZ zaloguje go do konsoli (podczas debugowania / programowania). Ponieważ if (process.env.NODE_ENV !== 'production') {(jeśli chcesz go również w produkcji) ...