J'ai un projet complet, déployé, basé sur Express, avec de nombreuses instructions console.log () et console.error (). Le projet s'exécute de manière permanente, en dirigeant stdout et stderr vers 2 fichiers distincts.
Tout fonctionne assez bien, mais il me manque maintenant des horodatages - pour savoir exactement quand des erreurs se sont produites.
Je peux effectuer une sorte de recherche/remplacement dans tout mon code, ou utiliser un module npm qui remplace la console dans chaque fichier, mais je ne souhaite pas toucher à tous les fichiers modèle/route, sauf obligation absolue.
Existe-t-il un moyen, peut-être un middleware Express, qui me permettrait d’ajouter un horodatage à chaque appel passé ou dois-je l’ajouter manuellement?
En fin de compte, vous pouvez écraser les fonctions de la console situées en haut du fichier app.js et les appliquer à tous les autres modules. J'ai eu des résultats mitigés car l'un de mes modules est transformé en child_process
. Une fois que j'ai copié la ligne au début de ce fichier aussi, tout fonctionne.
Pour mémoire, j’ai installé le module console-stamp (npm install console-stamp --save
), et a ajouté cette ligne en haut des fichiers app.js et childProcess.js:
// add timestamps in front of log messages
require('console-stamp')(console, '[HH:MM:ss.l]');
Mon problème maintenant était que le :date
Le format du consignateur de connexion utilise le format UTC, plutôt que celui que j'utilise dans les autres appels de la console. Cela a été facilement résolu en enregistrant mon propre format d’heure (et en tant qu’effet secondaire, nécessitant le module dateformat
que console stamp
vient avec, plutôt que d’en installer un autre):
// 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'));
Maintenant, mes fichiers de log semblent organisés (et mieux encore, analysables):
[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
...
Créez un fichier avec les éléments suivants:
var log = console.log;
console.log = function(){
log.apply(console, [Date.now()].concat(arguments));
};
Exigez-le dans votre application avant de vous connecter quoi que ce soit. Faites de même pour console.error
Si nécessaire.
Notez que cette solution détruira l'insertion de variable (console.log("he%s", "y") // "hey"
) si vous l'utilisez. Si vous en avez besoin, enregistrez d'abord l'horodatage:
log.call(console, Date.now());
log.apply(console, arguments);
module: "log-timestamp" fonctionne pour moi.
voir https://www.npmjs.com/package/log-timestamp
npm install log-timestamp
Simple à utiliser
console.log('Before log-timestamp');
require('log-timestamp');
console.log('After log-timestamp');
Résultat
Before log-timestamp
[2012-08-23T20:08:32.000Z] After log-timestamp
Vous pouvez également utiliser le package log-timestamp . C'est assez simple, et personnalisable aussi.
Si vous souhaitez une solution sans autre dépendance externe mais que vous souhaitez conserver toutes les fonctionnalités de console.log (paramètres multiples, insertion de variable), vous pouvez utiliser le code suivant:
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));
};
Vous pouvez modifier la fonction formatConsoleDate pour formater la date comme vous le souhaitez.
Ce code ne doit être écrit qu'une seule fois par-dessus votre fichier JavaScript principal.
console.log("he%s", "y")
imprimera quelque chose comme ceci:
[12:22:55.053] hey
app.use(morgan('[:date[web]] :method :url :status :res[content-length] - :remote-addr - :response-time ms'))
Vous pouvez utiliser une fonction util.log
de https://nodejs.org/api/util.html .
Cette implémentation est simple, prend en charge les fonctionnalités d'origine de console.log (passage d'un seul objet et substitution de variable), n'utilise pas de modules externes et affiche tout dans un seul appel à 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 );
};
Ce n'est pas une réponse directe, mais avez-vous examiné Winston.js? Il a beaucoup plus d'options de journalisation, y compris la journalisation dans un fichier json ou une base de données. Ceux-ci ont toujours des horodatages par défaut. Juste une pensée.
Utilisez un écouteur d'événement comme celui-ci,
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)
});
bonne codage :)