Чи можу я налаштувати console.logтак, щоб журнали записувались у файл, а не друкувалися в консолі?
Чи можу я налаштувати console.logтак, щоб журнали записувались у файл, а не друкувалися в консолі?
Відповіді:
Оновлення 2013 - це було написано навколо Node v0.2 та v0.4; Зараз навколо ведення журналу є набагато кращі утиліти. Дуже рекомендую Вінстон
Оновлення наприкінці 2013 року - ми все ще використовуємо winston, але тепер з бібліотекою реєстраторів, щоб обернути функціональність навколо журналу користувацьких об'єктів та форматування. Ось зразок нашого logger.js https://gist.github.com/rtgibbons/7354879
Повинно бути таким же простим.
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);все ще йде в консоль, а не файл.
process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })
Ви також можете просто перевантажити функцію 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');
};
Наведений вище приклад увійде до debug.log та stdout.
Редагувати: Дивіться багатопараметричну версію від Clément також на цій сторінці.
Якщо ви шукаєте щось у виробництві, Вінстон - це, мабуть, найкращий вибір.
Якщо ви просто хочете зробити Dev речі швидко, виведіть безпосередньо у файл (я думаю, що це працює лише для * nix систем):
nohup node simple-server.js > output.log &
>для переадресації STDOUT працює і в Windows. nohupне робить.
nohup* nix, тобто node simple-server.js > output.log. Тоді, якщо ви хочете слідкувати за журналом так, як його написано простоtail -f output.log
Я часто використовую багато аргументів для console.log () та console.error () , тому моїм рішенням буде:
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 - дуже популярний npm-модуль, що використовується для ведення журналів.
Ось як зробити.
Встановіть winston у своєму проекті:
npm install winston --save
Ось конфігурація, готова до використання у звичайних програмах, що я часто використовую у своїх проектах як logger.js під утилітами.
/**
* 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
};
А потім просто імпортуйте, куди потрібно:
const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Тоді ви можете зареєструвати успіх як:
successlog.info(`Success Message and variables: ${variable}`);
та помилки як:
errorlog.error(`Error Message : ${error}`);
Він також реєструє всі журнали успіху та журнали помилок у файлі, що знаходиться в каталозі журналів, як це можна побачити тут.

winston& winston-daily-rotate-file) один раз, чи конфігурації добре. Їх слід створити всередині папки, названої logsв кореневому каталозі проекту. Вибачте мене за затримку відповіді.
const winston = require('winston'); const winstonRotator = require('winston-daily-rotate-file'); І const errorLog = require('../util/logger').errorlog; const successlog = require('../util/logger').successlog; де б ви хотіли щось увійти.
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;
Щоб використовувати його, виконайте щось на кшталт:
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ключі, просто явно встановіть this.errorлише.
console.log. Це змінює свою поведінку, хоча ви можете відновити стару поведінку, зателефонувавши console.file().
Якщо це для програми, вам, ймовірно, краще використовувати модуль реєстрації. Це дасть вам більше гнучкості. Деякі пропозиції.
Ще одне рішення, про яке ще не було сказано, - підключення Writableпотоків у process.stdoutта process.stderr. Таким чином, вам не потрібно перекривати всі функції консолі, які виводять на stdout та stderr. Ця реалізація перенаправляє і stdout, і stderr у файл журналу:
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')
Він повинен друкуватись у консолі
a
b
c
d
e
f
і у файлі журналу:
c
d
Для отримання додаткової інформації перегляньте цю суть .
У простих випадках ми можемо перенаправити потоки Standard Out (STDOUT) та Standard Error (STDERR) безпосередньо до файлу за допомогою ">" та "2> & 1"
Приклад:
// 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");
})();
вузол test.js> test.log 2> & 1
Відповідно до стандарту POSIX потоки 'введення', 'вихід' та 'помилка' ідентифікуються дескрипторами файлів додатних цілих чисел (0, 1, 2). тобто stdin дорівнює 0, stdout - 1, а stderr - 2.
'2> & 1' переспрямує з 2 (stderr) на 1 (stdout)
'>' буде перенаправляти з 1 (stdout) у файл (test.log)
Переписування console.log - це шлях. Але для того, щоб він працював у необхідних модулях, вам також потрібно його експортувати.
module.exports = console;
Щоб заощадити собі проблему запису файлів журналів, обертання та інших матеріалів, ви можете скористатися простим модулем реєстратора, як 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;
globalоб’єкт. чому це робити module.exports?
МЕТОД РЕЗУЛЬТАТИ ТА СТДЕР
Цей підхід може вам допомогти (я використовую щось подібне у своїх проектах) і працює для всіх методів, включаючи console.log, console.warn, console.error, console.info
Цей метод записує байти, написані у stdout та stderr у файл. Краще, ніж змінити console.log, console.warn, console.error, console.info методи, тому що вихід буде точно таким же, як і ці методи виведення
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)
Прямо з документів API nodejs на консолі
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
Тепер ви можете використовувати Caterpillar, який є системою реєстрації потоків на основі потоків, що дозволяє вам увійти до нього, а потім передавати вихід у різні перетворення та місця.
Виведення файлу так само просто, як:
var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');
Повний приклад на веб-сайті Caterpillar
Ви також можете ознайомитися з цим модулем npm: https://www.npmjs.com/package/noogger
простий і прямий вперед ...
Я взяв на себе ідею заміни вихідного потоку на мій потік.
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;
Поліпшити Андреса Ріофріо, щоб обробити будь-яку кількість аргументів
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');
};
Я просто будую пакет для цього, сподіваюся, вам сподобається;) https://www.npmjs.com/package/writelog
Я для себе просто взяв приклад з Вінстона і додав log(...)метод (адже Вінстон його називає 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;
Тоді просто використовуйте у своєму коді:
const console = require('Console')
Тепер ви можете просто використовувати звичайні функції журналу у вашому файлі, і він створить файл І введе його до вашої консолі (під час налагодження / розробки). Через if (process.env.NODE_ENV !== 'production') {(якщо ви хочете і на виробництві) ...