आपका एप्लिकेशन एक ब्लैक बॉक्स है? इसे ठीक करने का समय आ गया है
\n\nक्या आपने कभी सोचा है, "मेरा Node.js सर्विस धीमा क्यों चल रहा है, जबकि कोड परफेक्ट है?" या फिर यूज़र से शिकायत मिली, लेकिन समझ नहीं आया कि गलती कहाँ हुई? यह परिचित लगता है? तो आप उस दुनिया में हैं जहाँ JavaScript में Observability के बिना आप अंधों की तरह काम कर रहे हैं।
\n\nObservability (अवलोकनीयता) सिर्फ एक ट्रेंडी शब्द नहीं है। यह एक ऐसा दृष्टिकोण है जो आपके कोड को ब्लैक बॉक्स से एक पारदर्शी सिस्टम में बदल देता है। हम सीखेंगे कि कैसे इससे सवाल पूछें: "गलती किसकी है?" (ट्रेसिंग), "अभी क्या हो रहा है?" (मेट्रिक्स) और "कल रात 3:15 बजे क्या हुआ था?" (लॉग्स)।
\n\nइस लेख में हम Node.js में Observability के तीन स्तंभों को समझेंगे: ट्रेसिंग, मेट्रिक्स और लॉग्स। आपको तैयार कोड उदाहरण मिलेंगे और पता चलेगा कि इन प्रैक्टिसेज को आज ही कैसे लागू करें। चलिए शुरू करते हैं!
\n\nJavaScript में ट्रेसिंग: रिक्वेस्ट की यात्रा
\n\nकल्पना करें कि एक यूज़र "ऑर्डर करें" बटन दबाता है। यह रिक्वेस्ट API Gateway, ऑथराइज़ेशन सर्विस, कार्ट, पेमेंट गेटवे और डेटाबेस से होकर गुज़रती है। अगर कुछ टूट गया, तो कहाँ खोजें? ट्रेसिंग (या distributed tracing) आपको इस यात्रा का नक्शा देता है।
\n\nसरल शब्दों में ट्रेसिंग क्या है
\n\nट्रेसिंग एक तरीका है जिससे किसी विशेष रिक्वेस्ट का सभी माइक्रोसर्विसेज और फंक्शन्स के माध्यम से पथ ट्रैक किया जाता है। हर कदम एक span है, और पूरी चेन एक trace है। आप देख सकते हैं कि हर चरण में कितना समय लगा और कहाँ एरर हुई।
\n\nOpenTelemetry: JavaScript में Observability के लिए मानक
\n\nOpenTelemetry (OTel) ट्रेस, मेट्रिक्स और लॉग्स इकट्ठा करने का इंडस्ट्री स्टैंडर्ड है। इसे सभी बड़े क्लाउड और टूल्स (Jaeger, Zipkin, Grafana) सपोर्ट करते हैं।
\n\nइंस्टॉलेशन:
\nnpm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node\n\nExpress एप्लिकेशन के लिए बेसिक ट्रेसिंग उदाहरण:
\nconst { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');\nconst { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');\nconst { ConsoleSpanExporter } = require('@opentelemetry/exporter-console');\nconst { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');\nconst { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');\n\nconst provider = new NodeTracerProvider();\nprovider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));\nprovider.register();\n\nconst { getTracer } = require('@opentelemetry/api');\nconst tracer = getTracer('my-app');\n\n// HTTP और Express के लिए ऑटोमैटिक ट्रेसिंग\nconst { registerInstrumentations } = require('@opentelemetry/instrumentation');\nregisterInstrumentations({\n tracerProvider: provider,\n instrumentations: [\n new ExpressInstrumentation(),\n new HttpInstrumentation()\n ]\n});\n\n// अब हर रिक्वेस्ट spans के साथ trace बनाएगा\nconst express = require('express');\nconst app = express();\n\napp.get('/api/order', async (req, res) => {\n // बिज़नेस लॉजिक के लिए मैन्युअल span\n const span = tracer.startSpan('processPayment');\n try {\n // ... आपका लॉजिक\n await new Promise(r => setTimeout(r, 100)); // सिमुलेशन\n span.setStatus({ code: 1 }); // OK\n } catch (err) {\n span.setStatus({ code: 2, message: err.message }); // ERROR\n throw err;\n } finally {\n span.end();\n }\n res.send('Order created');\n});\n\napp.listen(3000);\n\nअब कंसोल में आपको स्ट्रक्चर्ड डेटा दिखेगा: कौन सी रिक्वेस्ट, हर middleware में कितना समय लगा, एरर कहाँ थी। यह observability javascript असल में काम करता है।
\n\nमेट्रिक्स: आपके एप्लिकेशन की नब्ज
\n\nट्रेसिंग अलग-अलग रिक्वेस्ट के लिए अच्छी है, लेकिन पूरी तस्वीर के बारे में क्या? प्रति सेकंड कितनी रिक्वेस्ट्स? कितनी देरी? आपका Node.js कितनी मेमोरी खा रहा है? इसके लिए मेट्रिक्स जिम्मेदार हैं।
\n\nPrometheus और Node.js के लिए क्लाइंट
\n\nPrometheus मेट्रिक्स इकट्ठा करने का डी-फैक्टो स्टैंडर्ड है। यह आपके एप्लिकेशन से HTTP के ज़रिए डेटा "खींचता" है।