TypeScript में ऑब्ज़र्वेबिलिटी: ब्लैक बॉक्स से पारदर्शी सिस्टम तक
\n\nकल्पना करें कि आपका TypeScript एप्लिकेशन हज़ारों गियरों से बना एक जटिल तंत्र है। सब कुछ पूरी तरह से काम करता है, जब तक कि कुछ टूट न जाए। और फिर आपको एक संदेश मिलता है: "साइट धीमी हो रही है।" समस्या कहाँ खोजें? डेटाबेस? API? या बस एक माइक्रोसर्विस डाउन हो गई?
\n\nऑब्ज़र्वेबिलिटी (अवलोकनीयता) के बिना, आप डफली बजाने वाले जादूगर की तरह अनुमान लगाएंगे। ऑब्ज़र्वेबिलिटी के साथ, आप पूरी तस्वीर देखते हैं: प्रदर्शन कहाँ गिरा, किस अनुरोध ने त्रुटि उत्पन्न की, और मेमोरी क्यों लीक हुई।
\n\nइस लेख में, हम ऑब्ज़र्वेबिलिटी के तीन स्तंभों — ट्रेसिंग, मेट्रिक्स और लॉग — को समझेंगे और वास्तविक उदाहरणों के साथ उन्हें TypeScript अनुप्रयोगों में लागू करना सीखेंगे। आप जानेंगे कि अपने एप्लिकेशन को ब्लैक बॉक्स से एक पारदर्शी सिस्टम में कैसे बदलें, जिसका मिनटों में निदान किया जा सके।
\n\nTypeScript अनुप्रयोगों के लिए ऑब्ज़र्वेबिलिटी क्यों महत्वपूर्ण है?
\n\nTypeScript केवल JavaScript पर एक आवरण नहीं है। यह एक ऐसी भाषा है जिसमें उच्च-लोड सिस्टम, माइक्रोसर्विसेज और यहां तक कि CLI टूल के लिए बैकएंड लिखा जाता है। और सिस्टम जितना जटिल होगा, यह समझना उतना ही महत्वपूर्ण होगा कि इसमें क्या हो रहा है।
\n\nपारंपरिक लॉगिंग अच्छी है, लेकिन पर्याप्त नहीं है। जब आपके पास 50 माइक्रोसर्विसेज हों, तो लॉग सफेद शोर में बदल जाते हैं। आपको चाहिए:
\n\n- \n
- ट्रेसिंग — एक अनुरोध के पथ को सभी सेवाओं में ट्रैक करने के लिए। \n
- मेट्रिक्स — यह देखने के लिए कि RAM तेजी से बढ़ रही है। \n
- संरचित लॉग — घास के ढेर में सुई न खोजने के लिए। \n
आइए इसे एक वास्तविक एप्लिकेशन में लागू करें।
\n\nTypeScript में ट्रेसिंग: व्यवहार में OpenTelemetry
\n\nट्रेसिंग (ट्रेसिंग) एक अनुरोध की जीवन कहानी है। आप देखते हैं कि प्रत्येक चरण में कितना समय लगा: HTTP अनुरोध से लेकर डेटाबेस क्वेरी तक। TypeScript में, OpenTelemetry डी-फैक्टो मानक बन गया है।
\n\nOpenTelemetry की स्थापना और कॉन्फ़िगरेशन
\n\nnpm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-jaeger\n\nट्रेसिंग को आरंभ करने के लिए एक फ़ाइल tracing.ts बनाएं:
import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { JaegerExporter } from '@opentelemetry/exporter-jaeger';\nimport { Resource } from '@opentelemetry/resources';\nimport { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';\n\nconst jaegerExporter = new JaegerExporter({\n endpoint: 'http://localhost:14268/api/traces',\n serviceName: 'my-typescript-app',\n});\n\nconst sdk = new NodeSDK({\n resource: new Resource({\n [SemanticResourceAttributes.SERVICE_NAME]: 'my-typescript-app',\n [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',\n }),\n traceExporter: jaegerExporter,\n instrumentations: [getNodeAutoInstrumentations()],\n});\n\nsdk.start();\n\n\nअब प्रत्येक HTTP अनुरोध, प्रत्येक डेटाबेस कॉल स्वचालित रूप से ट्रेस होगा। आप Jaeger UI (या Grafana Tempo) में कॉल का पूरा मानचित्र देखेंगे।
\n\nमैन्युअल रूप से स्पैन बनाना
\n\nऑटो-इंस्ट्रूमेंटेशन बहुत अच्छा है, लेकिन कभी-कभी आपको अपने स्वयं के लेबल जोड़ने की आवश्यकता होती है। उदाहरण के लिए, जटिल व्यावसायिक तर्क के निष्पादन समय को मापना:
\n\nimport { trace } from '@opentelemetry/api';\n\nconst tracer = trace.getTracer('business-logic');\n\nasync function processOrder(orderId: string): Promise<void> {\n const span = tracer.startSpan('process-order', {\n attributes: { 'order.id': orderId },\n });\n\n try {\n // आपका ऑर्डर प्रोसेसिंग तर्क\n await validateOrder(orderId);\n await chargePayment(orderId);\n await sendConfirmation(orderId);\n\n span.setStatus({ code: 1 }); // OK\n } catch (error) {\n span.recordException(error as Error);\n span.setStatus