Mam kompletny, wdrożony projekt oparty na Express, z wieloma instrukcjami console.log () i console.error (). Projekt działa przy użyciu forever, kierując stdout i stderr do 2 oddzielnych plików.
Wszystko działa całkiem dobrze, ale teraz brakuje mi sygnatur czasowych - żeby dokładnie wiedzieć, kiedy wystąpiły błędy.
Mogę wyszukiwać / zamieniać w całym kodzie lub używać modułu npm, który zastępuje konsolę w każdym pliku, ale nie chcę dotykać każdego pliku modelu / trasy, chyba że absolutnie muszę.
Czy istnieje sposób, być może oprogramowanie pośredniczące Express, które pozwoliłoby mi dodać sygnaturę czasową do każdego wykonanego połączenia, czy też muszę dodawać go ręcznie?
Odpowiedzi:
Okazuje się, że możesz przesłonić funkcje konsoli w górnej części pliku app.js i zastosować je w każdym innym module. Otrzymałem mieszane wyniki, ponieważ jeden z moich modułów jest rozwidlony jako plik
child_process
. Po skopiowaniu wiersza również na początek tego pliku wszystko działa.Dla
npm install console-stamp --save
przypomnienia , zainstalowałem moduł console-stamp ( ) i dodałem ten wiersz na górze app.js i childProcess.js:// add timestamps in front of log messages require('console-stamp')(console, '[HH:MM:ss.l]');
Mój problem polegał na tym, że
:date
format rejestratora połączeń używa formatu UTC, a nie tego, którego używam w innych wywołaniach konsoli. Można to łatwo naprawić, rejestrując mój własny format czasu (i jako efekt uboczny, wymagającdateformat
modułu, któryconsole stamp
jest dołączony, zamiast instalowania innego):// since logger only returns a UTC version of date, I'm defining my own date format - using an internal module from console-stamp express.logger.format('mydate', function() { var df = require('console-stamp/node_modules/dateformat'); return df(new Date(), 'HH:MM:ss.l'); }); app.use(express.logger('[:mydate] :method :url :status :res[content-length] - :remote-addr - :response-time ms'));
Teraz moje pliki dziennika wyglądają na uporządkowane (a jeszcze lepiej, możliwe do przeanalizowania):
[15:09:47.746] staging server listening on port 3000 [15:09:49.322] connected to database server xxxxx successfully [15:09:52.743] GET /product 200 - - 127.0.0.1 - 214 ms [15:09:52.929] GET /stylesheets/bootstrap-cerulean.min.css 304 - - 127.0.0.1 - 8 ms [15:09:52.935] GET /javascripts/vendor/require.js 304 - - 127.0.0.1 - 3 ms [15:09:53.085] GET /javascripts/product.js 304 - - 127.0.0.1 - 2 ms ...
źródło
logger
zostało zastąpione przezmorgan
github.com/senchalabs/connect#middlewaremoduł: "log-timestamp" działa dla mnie.
zobacz https://www.npmjs.com/package/log-timestamp
Prosty w użyciu
console.log('Before log-timestamp'); require('log-timestamp'); console.log('After log-timestamp');
Wynik
Before log-timestamp [2012-08-23T20:08:32.000Z] After log-timestamp
źródło
Utwórz plik zawierający:
var log = console.log; console.log = function(){ log.apply(console, [Date.now()].concat(arguments)); };
Wymagaj tego w swojej aplikacji, zanim cokolwiek zarejestrujesz. Zrób to samo dla
console.error
razie potrzeby.Zwróć uwagę, że to rozwiązanie zniszczy zmienną insertion (
console.log("he%s", "y") // "hey"
), jeśli tego używasz. Jeśli tego potrzebujesz, po prostu zaloguj najpierw znacznik czasu:log.call(console, Date.now()); log.apply(console, arguments);
źródło
Jeśli potrzebujesz rozwiązania bez innej zależności zewnętrznej, ale chcesz zachować pełną funkcjonalność console.log (wiele parametrów, wstawianie zmiennych), możesz użyć następującego kodu:
var log = console.log; console.log = function () { var first_parameter = arguments[0]; var other_parameters = Array.prototype.slice.call(arguments, 1); function formatConsoleDate (date) { var hour = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); var milliseconds = date.getMilliseconds(); return '[' + ((hour < 10) ? '0' + hour: hour) + ':' + ((minutes < 10) ? '0' + minutes: minutes) + ':' + ((seconds < 10) ? '0' + seconds: seconds) + '.' + ('00' + milliseconds).slice(-3) + '] '; } log.apply(console, [formatConsoleDate(new Date()) + first_parameter].concat(other_parameters)); };
Możesz zmodyfikować funkcję formatConsoleDate, aby sformatować datę, jak chcesz.
Ten kod musi być napisany tylko raz w głównym pliku JavaScript.
console.log("he%s", "y")
wypisze coś takiego:[12:22:55.053] hey
źródło
Możesz również użyć pakietu log-timestamp . Jest to dość proste i również konfigurowalne.
źródło
app.use(morgan('[:date[web]] :method :url :status :res[content-length] - :remote-addr - :response-time ms'))
źródło
Ta implementacja jest prosta, obsługuje oryginalną funkcjonalność console.log (przekazywanie pojedynczego obiektu i podstawianie zmiennych), nie używa zewnętrznych modułów i wypisuje wszystko w jednym wywołaniu console.log:
var origlog = console.log; console.log = function( obj, ...placeholders ){ if ( typeof obj === 'string' ) placeholders.unshift( Date.now() + " " + obj ); else { // This handles console.log( object ) placeholders.unshift( obj ); placeholders.unshift( Date.now() + " %j" ); } origlog.apply( this, placeholders ); };
źródło
Jeśli chcesz, możesz utworzyć niestandardowy program rejestrujący dla swojej aplikacji, rozszerzając kompilację węzła w klasie „Console”. Prosimy zapoznać się z następującą implementacją
"use strict"; const moment = require('moment'); const util = require('util'); const Console = require('console').Console; class Logger extends Console { constructor(stdout, stderr, ...otherArgs) { super(stdout, stderr, ...otherArgs); } log(...args) { super.log(moment().format('D MMM HH:mm:ss'), '-', util.format(...args)); } error(...args) { super.error(moment().format('D MMM HH:mm:ss'), '-', util.format(...args)); } } module.exports = (function() { return new Logger(process.stdout, process.stderr); }());
Następnie możesz użyć go w swoim kodzie jako:
const logger = require('./logger'); logger.log('hello world', 123456); logger.error('some error occurred', err);
źródło
To nie jest bezpośrednia odpowiedź, ale czy zajrzałeś do winston.js? Ma o wiele więcej opcji rejestrowania, w tym logowanie do pliku json lub bazy danych. Te zawsze mają domyślnie sygnatury czasowe. Tylko myśl.
źródło
Możesz użyć funkcji
util.log
z https://nodejs.org/api/util.html .Należy pamiętać, że od wersji 6.0.0 jest przestarzały.
W przypadku wyższych wersji należy „Zamiast tego użyć modułu innej firmy”.
źródło
Próbuję nadpisać
console
obiekt - wygląda na to, że działa dobrze. Aby użyć, zapisz poniższy kod w pliku, a następnie zaimportuj, aby nadpisać obiekt proxy, a następnie użyj normalnie.(Zauważ, że wymaga to transpilacji Babel i nie będzie działać w środowiskach, które nie obsługują
Proxy
konstruktora JavaScript, takich jak IE 11).import console from './console-shadow.js' console.log(...) console.warn(...) console.error(...)
// console-shadow.js // Only these functions are shadowed by default const overwrites = ['log', 'warn', 'info', 'error'] export default new Proxy( // Proxy (overwrite console methods here) {}, // Handler { get: (obj, prop) => prop in obj ? obj[prop] : overwrites.includes(prop) ? (...args) => console[prop].call(console, new Date(), ...args) : console[prop], } )
Zasadniczo nadpisuję obiekt konsoli obiektem proxy JavaScript. Kiedy dzwonisz
.log
,.warn
itp. Nadpisana konsola sprawdzi, czy to, co wywołujesz, jest funkcją, jeśli tak, wstrzyknie datę do instrukcji log jako pierwszy parametr, a po niej wszystkie parametry.Myślę, że
console
obiekt naprawdę dużo robi i nie do końca go rozumiem. Więc tylko przechwytującaconsole.log
,console.info
,console.warn
,console.error
wzywa.źródło
Użyj detektora zdarzeń w ten sposób,
process.on('error', function() { console.log('Error Occurred.'); var d = Date(Date.now()).toString(); console.log.call(console, d); // Wed Aug 07 2019 23:40:07 GMT+0100 (GMT+01:00) });
miłego kodowania :)
źródło