Tüm konsol mesajlarına zaman damgası ekleme


93

Baştan sona pek çok console.log () ve console.error () ifadesi bulunan eksiksiz, konuşlandırılmış , Express tabanlı bir projem var. Proje, stdout ve stderr'i 2 ayrı dosyaya yönlendirerek sonsuza kadar çalışır.

Her şey oldukça iyi çalışıyor, ancak şimdi zaman damgalarını kaçırıyorum - hataların tam olarak ne zaman oluştuğunu bilmek.

Kodum boyunca bir tür arama / değiştirme yapabilir veya her dosyada konsolu geçersiz kılan bazı npm modüllerini kullanabilirim, ancak kesinlikle mecbur olmadıkça her model / rota dosyasına dokunmak istemiyorum.

Yapılan her aramaya bir zaman damgası eklememe izin verecek bir Express ara katman yazılımı olabilir mi yoksa manuel olarak eklemem mi gerekir?


Yanıtlar:


117

Size, çıkıyor olabilir app.js dosyasının en üstünde konsol işlevlerini geçersiz kılmak ve her diğer modülünde etkili olması gerekir. Karışık sonuçlar aldım çünkü modüllerimden biri bir child_process. Satırı o dosyanın en üstüne de kopyaladığımda, hepsi çalışıyor.

Kayıt için, modül konsol damgasını ( npm install console-stamp --save) yükledim ve bu satırı app.js ve childProcess.js'nin üstüne ekledim:

// add timestamps in front of log messages
require('console-stamp')(console, '[HH:MM:ss.l]');

Şimdiki sorunum :date, bağlantı kaydedicinin formatının diğer konsol çağrılarında kullandığım format yerine UTC formatını kullanmasıydı. Bu, kendi saat formatımı kaydettirerek (ve bir yan etki olarak, başka bir tane kurmak yerine birlikte gelen dateformatmodülü gerektirerek) kolayca düzeltildi console stamp:

// 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'));

Artık günlük dosyalarım düzenli görünüyor (ve daha da iyisi, ayrıştırılabilir):

[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
...

2
Dokümanları bulamadım, ancak görünen o ki ": mm" aya atıfta bulunacak ve ": MM" aslında kullanmak istediğiniz format
Laurent Sigal,

2
@ user603124'e göre dakika bölümünü değiştirmelisiniz. Dakikalar için dize : MM ( github.com/starak/node-console-stamp )
sucotronic

Yorum için teşekkürler. Düzeltildi!
Traveling Tech Guy

2
Görünüşe göre artık HH: MM: ss.l'yi parantez içine almanız gerekmiyor - otomatik olarak yapıyor
Jeff


34

module: "log-timestamp" benim için çalışıyor.

https://www.npmjs.com/package/log-timestamp adresine bakın

npm install log-timestamp

Kullanımı kolay

console.log('Before log-timestamp');
require('log-timestamp');
console.log('After log-timestamp');

Sonuç

Before log-timestamp
[2012-08-23T20:08:32.000Z] After log-timestamp

26

Aşağıdakilerle bir dosya oluşturun:

var log = console.log;

console.log = function(){
  log.apply(console, [Date.now()].concat(arguments));
};

Herhangi bir şey kaydetmeden önce bunu uygulamanızda gerekli kılın. console.errorGerekirse aynısını yapın .

Bunu kullanıyorsanız bu çözümün değişken insertion ( console.log("he%s", "y") // "hey") işlevini yok edeceğini unutmayın . Buna ihtiyacınız varsa, önce zaman damgasını kaydedin:

log.call(console, Date.now());
log.apply(console, arguments);

2
Aynı uygulama / süreçse değil. Konsol küresel bir nesnedir, bu nedenle işlevlerinden birini bu şekilde ele geçirirseniz, bu küresel nesneyi paylaşan tüm dosyalar için ele geçirilmeye devam edecektir.
Andreas Hultgren

Öyleyse, bu app.js dosyasına yerleştirilmeli / yerleştirilebilir mi?
Traveling Tech Guy

1
Evet. <min 15 karakter ...>
Andreas Hultgren

1
Bunun yerine konsol damgası kullanmanızı
öneririm

1
Bu iyi bir çözüm değildir - ya değişken eklemeyi ortadan kaldırır (bu nedenle yedek olarak kullanılamaz) ya da farklı satırlara tarih ve günlük çıktısını yazdırır.
George Y.

16

Başka bir dış bağımlılık olmadan bir çözüm istiyorsanız, ancak console.log'un tüm işlevlerini (birden çok parametre, değişken ekleme) korumak istiyorsanız, aşağıdaki kodu kullanabilirsiniz:

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));
};

Tarihi istediğiniz gibi biçimlendirmek için formatConsoleDate işlevini değiştirebilirsiniz.

Bu kodun ana JavaScript dosyanızın üzerine yalnızca bir kez yazılması gerekir.

console.log("he%s", "y") şunun gibi bir şey yazdıracak:

[12:22:55.053] hey

4
Teşekkürler, bu "bağımlılık yok" yanıtı tam da ihtiyacım olan şeydi.
RdR


3
app.use(morgan('[:date[web]] :method :url :status :res[content-length] - :remote-addr - :response-time ms'))

2

Bu uygulama basittir, console.log'un orijinal işlevselliğini destekler (tek bir nesneyi iletme ve değişken değiştirme), harici modülleri kullanmaz ve her şeyi tek bir console.log çağrısında yazdırır:

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 );
};

2

İsterseniz, Düğümün yapısını "Konsol" sınıfında genişleterek uygulamanız için özel bir kaydedici oluşturabilirsiniz. Lütfen aşağıdaki uygulamaya bakın

"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); 
}());

Bundan sonra, kodunuzda şu şekilde kullanabilirsiniz:

const logger = require('./logger');

logger.log('hello world', 123456);
logger.error('some error occurred', err);


1

Bu doğrudan bir cevap değil, ancak winston.js'yi incelediniz mi? Bir json dosyasına veya veritabanına günlük kaydı dahil olmak üzere bir ton daha fazla günlük kaydı seçeneğine sahiptir. Bunların varsayılan olarak her zaman zaman damgaları vardır. Sadece bir düşünce.


Pek çok şeye baktım, şu anda mevcut, konuşlandırılmış bir projeye bir şeyler eklemek istiyorum - koda çok fazla dokunmadan
Traveling Tech Guy


1

consoleNesnenin üzerine yazmaya çalışıyorum - iyi çalışıyor gibi görünüyor. Kullanmak için, aşağıdaki kodu bir dosyaya kaydedin ve ardından proxy nesnesinin üzerine yazmak için içe aktarın ve ardından normal şekilde kullanın.

(Bunun babel transpilasyonu gerektirdiğini ve ProxyIE 11 gibi JavaScript yapıcısını desteklemeyen ortamlarda çalışmayacağını unutmayın ).

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],
  }
)

Temel olarak bir JavaScript proxy nesnesi ile konsol nesnesinin üzerine yazıyorum. Aradığın zaman.log ,.warn, Vb. üzerine yazılan konsol, aradığınız şeyin bir işlev olup olmadığını kontrol eder, öyleyse, ilk parametre olarak günlük ifadesine bir tarih ve ardından tüm parametrelerinizi enjekte eder.

consoleNesnenin aslında çok şey yaptığını düşünüyorum ve tam olarak anlamıyorum. I Bu yüzden sadece yolunu kesmek console.log, console.info, console.warn, console.errorçağırır.


-1

Olay dinleyicisini bunun gibi kullanın,

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)
});

mutlu kodlama :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.