सभी कंसोल संदेशों में टाइमस्टैम्प जोड़ना


93

मेरे पास संपूर्ण, परिनियोजित , एक्सप्रेस-आधारित परियोजना है, जिसमें कई कंसोल.लॉग () और कंसोल.रोर () स्टेटमेंट हैं। परियोजना हमेशा के लिए उपयोग करती है, स्टडआउट और 2 अलग फ़ाइलों के लिए stderr निर्देशित।

यह सब काफी अच्छी तरह से काम करता है, लेकिन अब मैं टाइमस्टैम्प को याद कर रहा हूं - यह जानने के लिए कि त्रुटियां कब हुईं।

मैं अपने कोड में किसी प्रकार की खोज / प्रतिस्थापन कर सकता हूं, या कुछ एनपीएम मॉड्यूल का उपयोग कर सकता हूं जो प्रत्येक फ़ाइल में कंसोल को ओवरराइड करता है, लेकिन मैं हर मॉडल / रूट फ़ाइल को स्पर्श नहीं करना चाहता, जब तक कि मुझे पूरी तरह से नहीं करना पड़े।

क्या कोई रास्ता है, शायद एक एक्सप्रेस मिडलवेयर, जो मुझे हर कॉल के लिए टाइमस्टैम्प जोड़ने की अनुमति देगा, या क्या मुझे इसे मैन्युअल रूप से जोड़ना होगा?


जवाबों:


116

यह पता चला है, आप app.js फ़ाइल के शीर्ष पर कंसोल फ़ंक्शन को ओवरराइड कर सकते हैं, और हर दूसरे मॉड्यूल में इसका प्रभाव होता है। मुझे मिश्रित परिणाम मिले क्योंकि मेरे एक मॉड्यूल को एक के रूप में कांटा गया है child_process। एक बार जब मैंने लाइन को उस फ़ाइल के शीर्ष पर कॉपी किया, तो सभी काम करता है।

रिकॉर्ड के लिए, मैंने मॉड्यूल कंसोल-स्टैम्प ( npm install console-stamp --save) स्थापित किया , और इस लाइन को app.js और childProcess.js के शीर्ष पर जोड़ा:

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

अब मेरी समस्या यह थी कि :dateकनेक्ट लॉगर का प्रारूप यूटीसी प्रारूप का उपयोग करता है, बजाय इसके कि मैं दूसरे कंसोल कॉल्स में उपयोग कर रहा हूं। यह आसानी से मेरे अपने समय प्रारूप को पंजीकृत करके तय किया गया था (और एक साइड इफेक्ट के रूप में, उस dateformatमॉड्यूल की आवश्यकता होती है जो 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'));

अब मेरी लॉग फाइलें व्यवस्थित दिखती हैं (और बेहतर अभी तक, पारगम्य):

[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
मैं इसके लिए डॉक्स नहीं खोज सका, लेकिन ऐसा प्रतीत होता है कि ": mm" महीने को संदर्भित करेगा, और ": MM" वह प्रारूप है जिसका आप वास्तव में उपयोग करना चाहते हैं
लौरेंत सिगल

2
आप @ उपयोगकर्ता 603124 के अनुसार मिनट के भाग को बदल सकते हैं। मिनटों के लिए स्ट्रिंग है : MM ( github.com/starak/node-console-stamp )
सूक्रोट्रॉनिक

टिप्पणी के लिए धन्यवाद। सही किया!
टेक गाइ

2
लगता है कि अब आपको HH: MM: को कोष्ठक में लपेटने की आवश्यकता नहीं है - यह अपने आप हो रहा है
Jeff

3
FYI करें loggerको morgan github.com/senchalabs/connect#middleware
vtellier

34

मॉड्यूल: "लॉग-टाइमस्टैम्प" मेरे लिए काम करता है।

देख https://www.npmjs.com/package/log-timestamp

npm install log-timestamp

उपयोग करने के लिए सरल

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

परिणाम

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

26

निम्नलिखित के साथ एक फ़ाइल बनाएँ:

var log = console.log;

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

कुछ भी लॉग करने से पहले अपने ऐप में इसकी आवश्यकता है। के लिए ही करेंconsole.errorअगर जरूरत हो तो ।

ध्यान दें कि console.log("he%s", "y") // "hey"यदि आप इसका उपयोग कर रहे हैं तो यह समाधान चर सम्मिलन ( ) को नष्ट कर देगा । यदि आपको इसकी आवश्यकता है, तो पहले टाइमस्टैम्प लॉग करें:

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

2
नहीं अगर यह एक ही app / प्रक्रिया है। कंसोल एक वैश्विक वस्तु है इसलिए यदि आप इसके किसी एक कार्य को इस तरह से हाईजैक करते हैं तो यह उन सभी फाइलों के लिए अपहृत होता रहेगा जो उस वैश्विक वस्तु को साझा करते हैं।
एंड्रियास हॉल्टग्रेन 18

तो यह app.js फ़ाइल में रखा जाना चाहिए /?
ट्रेवलिंग गाइ


1
मैं इसके बजाय कंसोल-स्टैम्प का उपयोग करने की सलाह देता हूं
जसक पिटाल

1
यह अच्छा समाधान नहीं है - यह या तो चर सम्मिलन को नष्ट कर देता है (इस प्रकार इसका उपयोग प्रतिस्थापन के रूप में नहीं किया जा सकता है), या अलग-अलग लाइनों में दिनांक और लॉग आउटपुट को प्रिंट करता है।
जॉर्ज वाई।

16

यदि आप एक और बाहरी निर्भरता के बिना एक समाधान चाहते हैं, लेकिन आप कंसोल की पूर्ण कार्यक्षमता रखना चाहते हैं। (कई मापदंडों, चर प्रविष्टि) आप निम्नलिखित कोड का उपयोग कर सकते हैं:

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

आप जिस रूप में चाहते हैं, उस प्रारूप को प्रारूपित करने के लिए formatConsoleDate फ़ंक्शन को संशोधित कर सकते हैं।

इस कोड को आपकी मुख्य जावास्क्रिप्ट फ़ाइल के ऊपर केवल एक बार लिखा जाना चाहिए।

console.log("he%s", "y") कुछ इस तरह छपेगा:

[12:22:55.053] hey

4
धन्यवाद, यह "कोई निर्भरता नहीं" उत्तर था, जिसकी मुझे आवश्यकता थी।
RdR


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

2

यह कार्यान्वयन सरल है, कंसोल.लॉग की मूल कार्यक्षमता का समर्थन करता है (एकल ऑब्जेक्ट, और चर प्रतिस्थापन) गुजरता है, बाहरी मॉड्यूल का उपयोग नहीं करता है और कंसोल कॉल में सब कुछ प्रिंट करता है:

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

यदि आप चाहें, तो आप "कंसोल" वर्ग में नोड के निर्माण का विस्तार करके अपने आवेदन के लिए एक कस्टम लॉगर बना सकते हैं। कृपया निम्नलिखित कार्यान्वयन को देखें

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

उसके बाद, आप इसे अपने कोड में उपयोग कर सकते हैं:

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

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


1

यह एक सीधा जवाब नहीं है, लेकिन क्या आपने winston.js में देखा है? इसमें एक टन अधिक लॉगिंग विकल्प हैं, जिसमें एक json फाइल या डेटाबेस में लॉग इन करना शामिल है। इनमें हमेशा डिफ़ॉल्ट रूप से टाइमस्टैम्प होते हैं। सिर्फ एक विचार।


मैंने कई चीजों पर ध्यान दिया है, अभी, मैं एक मौजूदा, परिनियोजित प्रोजेक्ट में कुछ जोड़ना चाहूंगा - बहुत अधिक कोड को छुए बिना
ट्रैवल टेक

1

आप https://nodejs.org/api/util.htmlutil.log से एक फ़ंक्शन का उपयोग कर सकते हैं ।

ज्ञात हो कि 6.0.0 संस्करण के बाद से इसे हटा दिया गया था।

उच्चतर संस्करणों के लिए आपको "इसके बजाय किसी तीसरे पक्ष के मॉड्यूल का उपयोग करना चाहिए ।"


4
पदावनत: एक तीसरे पक्ष के मॉड्यूल का उपयोग करें।
जोश अनगर

1

मैं consoleऑब्जेक्ट को ओवरराइट करने की कोशिश कर रहा हूं - लगता है कि अच्छी तरह से काम कर रहा है। उपयोग करने के लिए, किसी फ़ाइल में नीचे दिए गए कोड को सहेजें, और फिर प्रॉक्सी ऑब्जेक्ट को अधिलेखित करने के लिए आयात करें, और फिर सामान्य रूप से उपयोग करें।

(ध्यान दें कि इसके लिए बैबल ट्रांसप्लिकेशन की आवश्यकता होती है और यह वातावरण में काम नहीं करेगा जो कि जावास्क्रिप्ट Proxyकंस्ट्रक्टर जैसे 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],
  }
)

मूल रूप से मैं एक जावास्क्रिप्ट प्रॉक्सी ऑब्जेक्ट के साथ कंसोल ऑब्जेक्ट को ओवरराइट करता हूं। जब आप फोन करते हैं .log,.warn आदि ओवरराइट सांत्वना अगर तुम क्या कह रहे एक समारोह है की जाँच करेगा, यदि ऐसा है तो यह अपने सभी मापदंडों के बाद पहले पैरामीटर के रूप लॉग बयान में एक तारीख इंजेक्षन जाएगा।

मुझे लगता है कि consoleवस्तु वास्तव में बहुत कुछ करती है, और मैं इसे पूरी तरह से नहीं समझता हूं। मैं तो केवल अवरोधन console.log, console.info, console.warn, console.errorकहता है।


-1

इस तरह घटना श्रोता का उपयोग करें,

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

खुश कोडिंग :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.