Kann ich konfigurieren console.log
, dass die Protokolle in eine Datei geschrieben werden, anstatt in der Konsole gedruckt zu werden?
Kann ich konfigurieren console.log
, dass die Protokolle in eine Datei geschrieben werden, anstatt in der Konsole gedruckt zu werden?
Antworten:
Update 2013 - Dies wurde um Node v0.2 und v0.4 herum geschrieben. Es gibt jetzt viel bessere Funktionen für die Protokollierung. Ich kann Winston nur empfehlen
Update Ende 2013 - Wir verwenden immer noch Winston, aber jetzt mit einer Logger-Bibliothek, um die Funktionalität um die Protokollierung von benutzerdefinierten Objekten und die Formatierung zu erweitern. Hier ist ein Beispiel unserer logger.js https://gist.github.com/rtgibbons/7354879
Sollte so einfach sein.
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);
geht immer noch zur Konsole, nicht zur Datei.
process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })
Sie können auch einfach die Standardfunktion console.log überladen:
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');
};
Das obige Beispiel protokolliert in debug.log und stdout.
Bearbeiten: Siehe Multiparameter-Version von Clément auch auf dieser Seite.
Wenn Sie nach etwas in der Produktion suchen, ist Winston wahrscheinlich die beste Wahl.
Wenn Sie nur schnell Entwicklerarbeiten erledigen möchten, geben Sie diese direkt in eine Datei aus (ich denke, dies funktioniert nur für * nix-Systeme):
nohup node simple-server.js > output.log &
>
zum Umleiten von STDOUT funktioniert auch unter Windows. nohup
nicht.
nohup
on * nix, dh node simple-server.js > output.log
. Dann, wenn Sie dem Protokoll folgen möchten, wie es gerade geschrieben wurdetail -f output.log
Ich verwende oft viele Argumente für console.log () und console.error () , daher lautet meine Lösung:
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 ist ein sehr beliebtes npm-Modul, das zur Protokollierung verwendet wird.
Hier ist eine Anleitung.
Installieren Sie Winston in Ihrem Projekt als:
npm install winston --save
Hier ist eine sofort einsatzbereite Konfiguration, die ich in meinen Projekten häufig als logger.js unter Utils verwende.
/**
* 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
};
Und dann einfach importieren, wo immer dies erforderlich ist:
const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Dann können Sie den Erfolg wie folgt protokollieren:
successlog.info(`Success Message and variables: ${variable}`);
und Fehler als:
errorlog.error(`Error Message : ${error}`);
Außerdem werden alle Erfolgsprotokolle und Fehlerprotokolle in einer Datei im Protokollverzeichnis datumsweise protokolliert, wie Sie hier sehen können.
winston
& winston-daily-rotate-file
) einmal, wenn die Konfigurationen in Ordnung sind. Sie sollten in einem Ordner erstellt werden, der logs
im Stammverzeichnis des Projekts benannt ist. Entschuldigen Sie die verspätete Antwort.
const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');
Und const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
wo immer Sie etwas protokollieren möchten.
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;
Um es zu benutzen, machen Sie etwas wie:
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.prototype
Schlüssel zu durchlaufen, setzen Sie sie nur explizit this.error
.
console.log
. Es ändert sein Verhalten, obwohl Sie das alte Verhalten durch Aufrufen wiederherstellen können console.file()
.
Wenn dies für eine Anwendung gilt, ist es wahrscheinlich besser, ein Protokollierungsmodul zu verwenden. Es gibt Ihnen mehr Flexibilität. Einige Vorschläge.
Eine andere noch nicht erwähnte Lösung besteht darin, die Writable
Streams in process.stdout
und einzubinden process.stderr
. Auf diese Weise müssen Sie nicht alle Konsolenfunktionen überschreiben, die an stdout und stderr ausgegeben werden. Diese Implementierung leitet sowohl stdout als auch stderr in eine Protokolldatei um:
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')
Es sollte in der Konsole gedruckt werden
a
b
c
d
e
f
und in der Protokolldatei:
c
d
Weitere Informationen finden Sie in dieser Übersicht .
In einfachen Fällen könnten wir die Streams Standard Out (STDOUT) und Standard Error (STDERR) direkt durch '>' und '2> & 1' in die Datei umleiten.
Beispiel:
// 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");
})();
Knoten test.js> test.log 2> & 1
Gemäß dem POSIX-Standard werden die Streams "Eingabe", "Ausgabe" und "Fehler" durch die positiven Ganzzahl- Dateideskriptoren (0, 1, 2) identifiziert . dh stdin ist 0, stdout ist 1 und stderr ist 2.
'2> & 1' leitet von 2 (stderr) zu 1 (stdout) um
'>' leitet von 1 (stdout) in die Datei (test.log) um
Das Überschreiben von console.log ist der richtige Weg. Damit es jedoch in den erforderlichen Modulen funktioniert, müssen Sie es auch exportieren.
module.exports = console;
Um sich die Mühe zu ersparen, Protokolldateien, Rotationen und ähnliches zu schreiben, sollten Sie ein einfaches Logger-Modul wie Winston verwenden:
// 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;
global
Objekt überschreiben . warum module.exports
?
METHODE STDOUT UND STDERR
Dieser Ansatz kann Ihnen helfen (ich verwende in meinen Projekten etwas Ähnliches) und funktioniert für alle Methoden, einschließlich console.log, console.warn, console.error, console.info
Diese Methode schreibt die in stdout und stderr geschriebenen Bytes in die Datei. Ist besser als das Ändern der Methoden console.log, console.warn, console.error und console.info, da die Ausgabe genau der Ausgabe dieser Methoden entspricht
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)
Direkt aus den API-Dokumenten von nodejs in der Konsole
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
Sie können jetzt Caterpillar verwenden , ein auf Streams basierendes Protokollierungssystem, mit dem Sie sich anmelden und die Ausgabe an verschiedene Transformationen und Speicherorte weiterleiten können.
Die Ausgabe in eine Datei ist so einfach wie:
var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');
Vollständiges Beispiel auf der Caterpillar-Website
Sie können sich auch dieses npm-Modul ansehen: https://www.npmjs.com/package/noogger
einfach und unkompliziert ...
Ich kam auf die Idee, den Ausgabestream gegen einen meiner Streams auszutauschen.
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;
Verbessere Andres Riofrio, um mit einer beliebigen Anzahl von Argumenten umzugehen
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');
};
Ich baue gerade ein Paket, um dies zu tun, hoffe es gefällt euch;) https://www.npmjs.com/package/writelog
Ich selbst habe einfach das Beispiel von Winston genommen und die log(...)
Methode hinzugefügt (weil Winston sie benenntinfo(..)
:
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;
Dann verwenden Sie einfach in Ihrem Code:
const console = require('Console')
Jetzt können Sie einfach die normalen Protokollfunktionen in Ihrer Datei verwenden und es wird eine Datei erstellt UND an Ihrer Konsole protokolliert (während des Debuggens / Entwickelns). Wegen if (process.env.NODE_ENV !== 'production') {
(falls Sie es auch in der Produktion wollen) ...