NestJS مشاہدہ کا استعمال کیسے کریں: ڈویلپرز کے لیے ایک مشاہداتی ہینڈ بک

مشاہدہ کوئی نیا مسئلہ نہیں ہے، اور NestJS یقینی طور پر اسے حل کرنے والا پہلا ماحولیاتی نظام نہیں ہے۔

لیکن NestJS Observe دلچسپ ہے کیونکہ یہ زیادہ مخصوص سوالات پوچھتا ہے۔ جب مشاہدہ قابل مشاہدہ فریم ورک کو سمجھتا ہے تو کیا ہوتا ہے؟

نفاذ کو دیکھنے سے پہلے، آئیے مسئلہ طے کریں اور دیکھیں کہ فریم ورک کا سیاق و سباق کیوں اہم ہے۔

مشاہداتی مسائل

اگر آپ کسی بھی لمبے عرصے سے سرور ایپلی کیشنز بنا رہے ہیں اور ان کی دیکھ بھال کر رہے ہیں، تو آپ نے شاید ایسے لمحات کا تجربہ کیا ہو گا جہاں آپ کا API کسی وجہ سے سست ہو جاتا ہے اور آپ کو سمجھ نہیں آتی کہ کیوں۔

جب میں لاگ چیک کرتا ہوں تو وہاں کچھ بھی نہیں ہے۔ ڈیٹا بیس کام کر رہا ہے اور کوئی خرابی نہیں ہے۔ اختتامی نقطہ آپ کے کمپیوٹر پر بالکل کام کرتا ہے۔

تو آئیے کچھ لاگز شامل کریں:

11:30:02 AM LOG Starting order creation
11:34:11 AM LOG Inventory checked
11:34:12 AM LOG Payment started
11:39:03 AM LOG Payment completed

اور پھر درخواست دوبارہ چلائیں۔ اب آپ کو اندازہ ہے کہ وقت کیسے گزرتا ہے، ساتھ ہی آپ اپنا بنیادی ٹریکنگ سسٹم بنانا شروع کر دیتے ہیں۔

یہیں سے چیزیں دلچسپ ہوجاتی ہیں۔ جدید ایپلی کیشنز بہت زیادہ معلومات پیدا کر سکتی ہیں، بشمول لاگ، میٹرکس، ٹریس، پروفائلز، غلطیاں، ڈیٹا بیس کے سوالات، HTTP کالز، بیک گراؤنڈ ٹاسک، اور قطار میں لگے پیغامات۔

چیلنج ضروری نہیں ہے۔ مزید معلومات جمع کریں۔ اس سے زیادہ آسان سوال کا جواب دیا جا سکتا ہے۔

میری درخواست کا اصل میں کیا ہوا؟

NestJS ایپس کے لیے، یہ سوال خاص طور پر دلچسپ ہو جاتا ہے کیونکہ Nest پہلے سے ہی سمجھتا ہے کہ کیا ہو رہا ہے۔

میں کنٹرولرز، فراہم کنندگان، مڈل ویئر، گارڈز، انٹرسیپٹرز اور پائپوں کے بارے میں جانتا ہوں۔ ہم جانتے ہیں کہ گراف کیو ایل ریزولور کب چلتا ہے یا جب مائیکرو سروس ہینڈلر کو کوئی پیغام موصول ہوتا ہے۔

تو کیا ہوتا ہے جب مشاہدے کو اس علم کو استعمال کرنے کی اجازت دی جائے؟ اس کے پیچھے ایک خیال ہے۔ NestJS مشاہدہ. یہ وہی ہے جو ہم اس مضمون میں دریافت کریں گے۔

لیکن مشاہدہ کو انسٹال کرنے کے لیے صرف ایک اور پیکج سمجھنے کے بجائے، ہم اسے بڑے خیالات اور سوالات کو سمجھنے کے لیے استعمال کرنا چاہتے ہیں۔ فریم ورک سے آگاہی کا مشاہدہ واقعی ہمیں کیا دیتا ہے، اور یہ کب استعمال کرنے کے قابل ہے؟

آئیے مشاہدے کی بنیادی باتوں کے ساتھ شروع کرتے ہیں، ایک چھوٹی NestJS ایپلیکیشن بنانا، حقیقی دنیا کی کارکردگی کا مسئلہ متعارف کرانا، مشاہدہ کا استعمال کرتے ہوئے اس کا آلہ بنانا، اور پھر اس نقطہ نظر کا OpenTelemetry کی فریم ورک غیر جانبدار دنیا سے موازنہ کرنا۔

شرطیں

ساتھ چلنے کے لیے، آپ کو ٹائپ اسکرپٹ اور NestJS کی بنیادی معلومات، اور HTTP API سے کچھ واقفیت کی ضرورت ہوگی۔

مشاہدے کے پہلے تجربے کی ضرورت نہیں ہے۔ میں تصورات کو متعارف کراؤں گا جیسا کہ ہم بناتے ہیں۔

ہم کیا احاطہ کریں گے:

مشاہدہ دراصل کون سا مسئلہ حل کرتا ہے؟

آئیے مسئلہ کو ٹھوس بنائیں۔ مندرجہ ذیل NestJS ایپلیکیشن کا تصور کریں: POST /orders درخواست آتی ہے اور اس میں تقریباً 3 سیکنڈ لگتے ہیں۔ یہ سب HTTP کلائنٹ ہمیں بتاتا ہے۔

اوپر والا خاکہ ایک ہی دکھاتا ہے۔ POST /orders درخواست ایک درخواست کے اندر سرگرمی کی متعدد پرتوں کو متحرک کر سکتی ہے، جو اس بات کی وضاحت کرتی ہے کہ صرف درخواست کی مدت ہی ہمیں یہ نہیں بتاتی کہ وقت کہاں گزارا گیا تھا۔

ہم کیا جانتے ہیں:

POST /orders → 3 seconds

لیکن یہ اکیلا کافی نہیں ہے۔ ہم جاننا چاہتے ہیں کہ 3 سیکنڈ کہاں سے آتے ہیں:

Controller → Service → Database

یا:

Controller → Service → External API

یا شاید یہ مکمل طور پر کسی اور چیز سے ہے۔

Node.js process → CPU-heavy operation → Event loop contention

یہ وہ مسئلہ ہے جسے مشاہدہ کرنے کی کوشش کرتا ہے۔ NestJS مشاہدہ ایک دلچسپ نقطہ نظر سے اس تک پہنچتا ہے۔ فریم ورک پہلے ہی جواب کا حصہ جانتا ہے۔

مشاہدہ ان انجینئرنگ الفاظ میں سے ایک ہے جو تیزی سے مبہم ہو سکتے ہیں۔ کچھ مفید تعریفیں یہ ہیں:

مشاہداتی صلاحیت کسی نظام کی اندرونی حالت اور رویے کو اس معلومات سے سمجھنے کی صلاحیت ہے جس کے سامنے یہ ہے۔

وہ معلومات ٹیلی میٹری، سب سے زیادہ عام ٹیلی میٹری سگنل ہیں:

  • لاگ

  • میٹرکس

  • ثبوت

  • پروفائل

وہ سب مختلف سوالات کے جوابات دیتے ہیں۔

نوشتہ جات واقعات کی وضاحت کرتے ہیں۔ کیا ہوا؟

مثال کے طور پر:

2026-08-31 14:21:04
Payment provider returned HTTP 502

یہ مفید ہے، لیکن اگر آپ ایک درخواست کی چھان بین کر رہے ہیں، تو آپ کو اس لاگ کو دستی طور پر باقی تمام چیزوں کے ساتھ باندھنے کی ضرورت پڑ سکتی ہے۔

میٹرک کی مجموعی معلومات: یہ کتنی بار ہوا؟

request_count = 1,240,231
error_rate = 2.4%
p95_latency = 840ms

رجحانات کو سمجھنے کے لیے میٹرکس بہترین ہیں، لہذا آپ اس سوال کا فوری جواب دے سکتے ہیں، "کیا کل کی تعیناتی کے بعد سے تاخیر میں اضافہ ہوا ہے؟” تاہم، میٹرکس عام طور پر ایک درخواست کی پوری کہانی کو بیان نہیں کرتے ہیں۔ تو ہمیں بھی ایک ‘ٹریس’ کی ضرورت ہے

ٹریکنگ ایک منطقی کام کی پیروی کرتی ہے: اس کام کے دوران کیا ہوا؟

مثال کے طور پر:

POST /orders
│
├── authentication
├── OrdersController.create()
├── InventoryService.reserve()
├── PaymentService.charge()
└── Payment API

اب آپ پھانسی کا راستہ دیکھ سکتے ہیں۔ زیادہ اہم بات یہ ہے کہ آپ دیکھ سکتے ہیں کہ انفرادی کاموں پر کتنا وقت صرف ہوا۔

پھر پروفائل ہے۔ پروفائلنگ مختلف سوالات کے جوابات دیتی ہے۔ دوسرے الفاظ میں، رن ٹائم استعمال کرنے والے وسائل کہاں ہیں؟ فرض کریں کہ آپ کا اختتامی نقطہ سست ہے، لیکن کوئی ڈیٹا بیس یا HTTP درخواستیں نہیں ہیں جو واضح طور پر سست ہوں۔

CPU پروفائل اشارہ کر سکتا ہے:

CPU
│
├── JSON serialization
├── application code
├── garbage collection
└── cryptographic operations

چار نشانیاں ایک دوسرے کی تکمیل کرتی ہیں۔

یہ ایک مفید ذہنی ماڈل ہے۔

شکل 2: مشاہداتی سیٹ

یہ اعداد و شمار اہم مشاہداتی سگنلز (لاگز، میٹرکس، ٹریس، اور پروفائلز) کو گروپ کرتا ہے تاکہ یہ ظاہر کیا جا سکے کہ ہر سگنل کس طرح ایپلیکیشن کے رویے کا ایک مختلف نظریہ فراہم کرتا ہے اور وہ کس طرح ایک دوسرے کی تکمیل کرتے ہیں۔

عملی طور پر، تمام ایپلی کیشنز کے لیے ضروری نہیں کہ تمام سگنلز درکار ہوں۔ نقطہ یہ ہے کہ آپریشنل سوالات کے جوابات کے لیے کافی معلومات ہوں۔

ایپلیکیشن مانیٹرنگ سے لے کر فریم ورک سے آگاہی تک

روایتی طریقے ٹیلی میٹری جمع کرنے کا ایک مضبوط، معیاری طریقہ فراہم کرتے ہیں۔ تاہم، فریم ورک پہلے سے ہی سمجھتا ہے کہ ایپلیکیشن کی ساخت اور چلتی ہے۔ کیا ہوگا اگر مشاہدہ آپ کی درخواست کو عام عمل کے طور پر استعمال کرنے کے بجائے اس سیاق و سباق کو استعمال کرسکتا ہے؟

مشاہدہ کرنے سے پہلے

بہت سے طریقے ہیں جن سے ہم سست روی تک پہنچ سکتے ہیں۔ /orders اختتامی نقطہ سب سے آسان لاگنگ ہے۔

console.log('Starting payment');
await paymentService.charge();
console.log('Payment completed');

یہ اس وقت تک کام کرتا ہے جب تک کہ آپ کی درخواست بڑھ نہ جائے۔ اس کے بعد آپ میٹرکس متعارف کروا سکتے ہیں۔

payment_latency_ms
orders_created_total
payment_failures_total

اب ہم بہت سی درخواستوں کے رویے کو سمجھ سکتے ہیں۔ اس کے بعد تقسیم شدہ ٹریسنگ متعارف کرائی جا سکتی ہے۔

POST /orders
│
├── OrdersController
├── OrdersService
├── InventoryService
└── PaymentService

یہ وہ جگہ ہے جہاں OpenTelemetry خاص طور پر متعلقہ اور خاص طور پر اہم ہو جاتا ہے۔ OpenTelemetry ٹیلی میٹری بنانے، جمع کرنے اور برآمد کرنے کے لیے ایک وینڈر غیر جانبدار مشاہداتی فریم ورک اور ٹول کٹ ہے۔

یہ جان بوجھ کر مشاہداتی پس منظر نہیں ہے۔ ہم بعد میں اس فرق پر واپس آئیں گے کیونکہ OpenTelemetry اور Observe کا موازنہ کرتے وقت یہ اہم ہو جاتا ہے۔

تو آپ کو NestJS Observe کی ضرورت کیوں ہے؟

یہ وہ جگہ ہے جہاں یہ دلچسپ ہو جاتا ہے۔ ایک عام انسٹرومینٹیشن پرت HTTP درخواستوں کا مشاہدہ کر سکتی ہے، لیکن NestJS جانتا ہے کہ درخواست ایک مخصوص درخواست کے ڈھانچے سے گزری ہے۔

مثال کے طور پر:

HTTP Request → Middleware → Guard → Interceptor → Pipe → Controller → Provider

یہ بے ترتیب جاوا اسکرپٹ فنکشن نہیں ہے۔ یہ ایک ایسا تصور ہے جسے Nest خود سمجھتا ہے۔ اس سے فریم ورک کے قریب مشاہداتی نظاموں سے ممکنہ طور پر قیمتی معلومات دستیاب ہوتی ہیں۔

صرف دیکھنے کے بجائے:

HTTP GET /users/42 (took 4s to execute)

ہم ممکنہ طور پر سمجھ سکتے ہیں:

HTTP GET /users/42 → UsersController.findOne() → UsersService.findUser() → UsersRepository.findById()

یہ فرق وہی ہے جو فریم ورک کی سطح کے آلات کو دلچسپ بناتا ہے۔

فریم ورک سے آگاہی کا مشاہدہ

آئیے آئیڈیا کو ایک نام دیں۔ فریم ورک سے آگاہی کا مشاہدہ اس کا مطلب یہ ہے کہ انسٹرومینٹیشن ایپلیکیشن کو ایک عام عمل کے طور پر سمجھنے کے بجائے فریم ورک کے ایگزیکیوشن ماڈل کو سمجھتی ہے۔

روایتی ماڈل تقریبا اس طرح لگتا ہے:

Application
    ↓
Generic instrumentation
    ↓
OpenTelemetry
    ↓
Collector
    ↓
Observability backend

فریم ورک انضمام کا طریقہ درج ذیل ہے:

NestJS application
    ↓
NestJS lifecycle
    ↓
Framework-aware instrumentation
    ↓
Telemetry
    ↓
Observability backend

فرق ضروری نہیں کہ حتمی ٹیلی میٹری فارمیٹ میں ہو۔ اختلافات درج ذیل ہیں: سیاق و سباق کی مقدار جسے آلہ خود بخود سمجھ سکتا ہے۔.

وہ جگہ ہے۔ مشاہدہ تصویر درج کریں۔

NestJS مشاہدات سے ملیں۔

NestJS Observe ایک سرکاری مشاہداتی ٹول ہے جو خاص طور پر NestJS ایپلی کیشنز کے لیے بنایا گیا ہے۔ یہ پروجیکٹ اوپن سورس ہے۔ مقصد لاگز، میٹرکس، یا نشانات ایجاد کرنا نہیں ہے کیونکہ وہ پہلے سے موجود ہیں اور اچھی طرح سے کام کرتے ہیں۔ اس کی قدر NestJS ایپلیکیشن ماڈل کے ساتھ مشاہداتی صلاحیت کو مربوط کرنے سے حاصل ہوتی ہے۔

موجودہ پروجیکٹ کی دستاویزات NestJS کے عمل درآمد کے متعدد راستوں کے لیے خودکار آلات کی وضاحت کرتی ہیں، بشمول:

  • HTTP

  • گراف کیو ایل

  • مائیکرو سروسز/RPC

  • بل ایم کیو

  • طے شدہ کام

یہ رن ٹائم میٹرکس اور جانچ کے قابل پروفائلنگ کی خصوصیات بھی فراہم کرتا ہے۔

آگے بڑھنے سے پہلے، براہ کرم درج ذیل کو نوٹ کریں: مشاہدہ ابھی بھی NestJS ماحولیاتی نظام کا نسبتاً نیا حصہ ہے۔یہ APIs، تعاون یافتہ انضمام، قیمتوں کا تعین، اور خصوصیات کو تیزی سے تیار کرنے کی اجازت دیتا ہے۔

آئیے اب گپ شپ چھوڑ دیں اور کچھ بنائیں۔

لیکن اس سے پہلے کہ ہم مزید آگے بڑھیں، براہ کرم ایک لمحہ انتظار کریں۔ اگر آپ یہ دیکھنا چاہتے ہیں کہ آپ کی اپنی ایپلیکیشن ترتیب دینے سے پہلے یہ کیسا لگتا ہے، جو اب NestJS پر شائع ہوا ہے۔ ڈیمو ڈیش بورڈ کا مشاہدہ کریں۔ آپ اسے خود دریافت کر سکتے ہیں۔ یہ مصروف خدمات کے ذریعے تیار کردہ ڈیٹاسیٹس پر چلتا ہے، جس سے آپ کو اکاؤنٹ بنائے یا انسٹال کیے بغیر درخواستوں، نشانات، آبشار کے نظارے، غلطیوں، پس منظر کے کاموں، اور الرٹس کو دریافت کرنے کی اجازت ملتی ہے۔

ہمارا مشورہ ہے کہ آپ جاری رکھنے سے پہلے چند منٹ کے لیے کلک کریں۔ خاص طور پر، آپ ایک درخواست کھولتے ہیں یا اس کا سراغ لگاتے ہیں اور اس پر عمل درآمد کو اعلی سطحی کارروائیوں سے لے کر انفرادی کارروائیوں تک ٹریس کرتے ہیں۔ اس سے ہمیں اسکرین شاٹس یا فیچر کی فہرستوں کو دیکھنے کے بجائے اس مثال میں جو کچھ ہم بنا رہے ہیں اس کے بارے میں بہت بہتر بصیرت فراہم کرتا ہے۔

ہمارے عملی منصوبے

ہم ایک چھوٹی ادائیگی API بنائیں گے۔ اس کے تین چھوٹے اجزاء ہیں:

  • حکم: HTTP درخواستیں وصول کرتا ہے اور ادائیگی کے بہاؤ کو مربوط کرتا ہے۔

  • انوینٹری: درخواست کردہ پروڈکٹ ریزرویشن کی نقل کرتا ہے۔

  • ادائیگی: ایک بیرونی ادائیگی فراہم کنندہ کی تقلید کرتا ہے اور جان بوجھ کر تاخیر کو متعارف کراتا ہے۔

مجموعی بہاؤ کے لیے اوپر تصویر 1 دیکھیں جس کی ہم نقل تیار کریں گے۔

کہ Orders اگرچہ جزو درخواست میں مرکوز ہے، Inventory اور Payments ان کارروائیوں کی نمائندگی کرتا ہے جو عمل درآمد کے راستے کے نیچے واقع ہوتے ہیں۔ یہ آپ کو حقیقت پسندانہ سست درخواستیں بنانے کے لیے کافی ڈھانچہ فراہم کرتا ہے اور بعد میں یقینی بنائیں کہ مشاہدہ آپ کو دکھا سکتا ہے کہ وقت کہاں گزرا ہے۔

ادائیگی فراہم کرنے والے جان بوجھ کر چیزوں کو سست کرتے ہیں۔

ہمارا مقصد یہ دیکھنا ہے کہ کیا ہم اس بات کی نشاندہی کر سکتے ہیں کہ درخواستیں ہر کام کو دستی طور پر بنائے بغیر اپنا وقت کہاں گزار رہی ہیں۔

ہم ای کامرس پلیٹ فارم نہیں بنا رہے ہیں۔ ہم حقیقت پسندانہ مشاہداتی مسائل پیدا کرنے کے لیے کافی پیچیدگی پیدا کر رہے ہیں۔

جاری رکھنے کے لیے آپ کو تازہ ترین Node.js انسٹالیشن اور NestJS CLI کی ضرورت ہوگی۔ آپ کو OpenTelemetry یا کسی موجودہ APM پلیٹ فارم کو جاننے کی ضرورت نہیں ہے، اور نہ ہی آپ کو پروڈکشن ایپلی کیشن کی ضرورت ہے۔

NestJS ایپلیکیشن بنائیں

باقاعدہ NestJS پروجیکٹ کے ساتھ شروع کریں۔

$ npm i -g @nestjs/cli # if not installed yet
$ nest new nest-observe-demo
$ cd nest-observe-demo

کہ nest new حکم ہے "کیا آپ آٹو انسٹرومینٹڈ آبزرویبلٹی (@nestjs/observe) کو فعال کرنا چاہیں گے؟ جب اشارہ کیا جائے تو ہاں کہیں۔

شروع کریں:

$ npm run start:dev

اب Nest CLI کا استعمال کرتے ہوئے اپنا ماڈیول بنائیں۔

$ nest g module orders
$ nest g controller orders
$ nest g service orders

$ nest g module inventory
$ nest g service inventory

$ nest g module payments
$ nest g service payments

آپ کا پروجیکٹ تقریبا اس طرح نظر آنا چاہئے:

src/
├── app.module.ts
├── main.ts
│
├── orders/
│   ├── orders.controller.ts
│   ├── orders.service.ts
│   └── orders.module.ts
│
├── inventory/
│   ├── inventory.service.ts
│   └── inventory.module.ts
│
└── payments/
    ├── payments.service.ts
    └── payments.module.ts

ہماری ادائیگی کی خدمات بیرونی ادائیگی فراہم کرنے والوں کی نمائندگی کرتی ہیں۔ ٹیوٹوریل نیٹ ورک لیٹینسی کی نقل کرتا ہے۔

import { Injectable } from '@nestjs/common';

@Injectable()
export class PaymentsService {
  async charge(amount: number) {
    await new Promise((resolve) =>
      setTimeout(resolve, 750),
    );

    return {
      id: `payment_${Date.now()}`,
      amount,
      status: 'succeeded',
    };
  }
}

اہم حصہ ہے۔ setTimeout(). ہم جان بوجھ کر سست انحصار پیدا کر رہے ہیں۔

ایک حقیقی درخواست میں یہ اس طرح نظر آسکتا ہے:

  • HTTP درخواست

  • ڈیٹا بیس استفسار

  • فریق ثالث APIs

  • ایک اور مائیکرو سروس

ہمارے مقاصد کے لیے، تاخیر کی وجہ اہم نہیں ہے۔

اسٹاک شامل کریں۔

ہماری انوینٹری سروس بہت تیز ہوگی:

import { Injectable } from '@nestjs/common';

@Injectable()
export class InventoryService {
  async reserve(productId: string) {
    await new Promise((resolve) =>
      setTimeout(resolve, 40),
    );

    return {
      productId,
      reserved: true,
    };
  }
}

ایک بار پھر، تاخیر بیرونی اعمال کی نمائندگی کرتی ہے۔

آرڈرنگ سروس بنائیں

اب آئیے دونوں آپریشنز کو ملاتے ہیں۔

// src/orders.service.ts
import { Injectable } from '@nestjs/common';
import { InventoryService } from '../inventory/inventory.service';
import { PaymentsService } from '../payments/payments.service';

@Injectable()
export class OrdersService {
  constructor(
    private readonly inventoryService: InventoryService,
    private readonly paymentsService: PaymentsService,
  ) {}

  async createOrder(
    productId: string,
    amount: number,
  ) {
    const inventory =
      await this.inventoryService.reserve(productId);

    const payment =
      await this.paymentsService.charge(amount);

    return {
      id: `order_${Date.now()}`,
      productId,
      amount,
      inventory,
      payment,
    };
  }
}

اہم نکات پر توجہ دیں۔ یہاں کوئی مشاہداتی کوڈ نہیں ہے۔ کم از کم ابھی کے لیے یہ صرف ایپلیکیشن کوڈ ہے!

کنٹرولر بنائیں

تیار کردہ کنٹرولر فائل میں، درج ذیل درج کریں:

import { Body, Controller, Post } from '@nestjs/common';
import { OrdersService } from './orders.service';

@Controller('orders')
export class OrdersController {
  constructor(
    private readonly ordersService: OrdersService,
  ) {}

  @Post()
  create(
    @Body()
    body: {
      productId: string;
      amount: number;
    },
  ) {
    return this.ordersService.createOrder(
      body.productId,
      body.amount,
    );
  }
}

کنٹرولر جان بوجھ کر پتلا ہے۔ HTTP درخواستوں کو قبول کرتا ہے۔ productId اور amountاصل کام درج ذیل صارفین کو سونپا جاتا ہے: OrdersService.

کہ OrdersService NestJS انحصار انجیکشن (DI) کا استعمال کرتے ہوئے کنٹرولر کنسٹرکٹر کے ذریعے فراہم کیا گیا ہے۔ یعنی ہم تخلیق نہیں کرتے۔ new OrdersService() ہم خود اس کے بجائے، Nest ایک سروس بناتا ہے اور ایپلیکیشن شروع ہونے پر اسے کنٹرولر کو فراہم کرتا ہے۔ یہ کنٹرولر کو HTTP مسائل پر توجہ مرکوز کرنے کی اجازت دیتا ہے اور Nest کو ایپلیکیشن کے انحصار کو منظم کرنے کی اجازت دیتا ہے۔

ذیل میں ماڈیول کنفیگریشن ماڈیول کی حدود میں انجیکشن کو قابل بناتی ہے۔ OrdersModule فراہم کریں OrdersService برآمد شدہ ماڈیول درآمد کریں۔ InventoryService اور PaymentsService. وہ exports سروس کو ان ماڈیولز کے لیے دستیاب کرتا ہے جو اسے درآمد کرتے ہیں۔ یہ اس مثال کے لیے درکار NestJS DI کا صرف ایک چھوٹا سا حصہ ہے۔ متعلقہ NestJS وسائل صرف اس صورت میں موجود ہیں جب آپ مزید جاننا چاہتے ہیں کہ انحصار انجیکشن سسٹم کیسے کام کرتا ہے۔

یقینی بنائیں کہ آپ کا ماڈیول درآمد کرتا ہے اور مطلوبہ خدمات فراہم کرتا ہے۔ آپ یہاں Nest میں DI کے بارے میں مزید جان سکتے ہیں۔

مثال کے طور پر، درج ذیل کوڈ:

import { Module } from '@nestjs/common';
import { OrdersController } from './orders.controller';
import { OrdersService } from './orders.service';
import { InventoryModule } from '../inventory/inventory.module';
import { PaymentsModule } from '../payments/payments.module';

@Module({
  imports: [
    InventoryModule,
    PaymentsModule,
  ],
  controllers: [OrdersController],
  providers: [OrdersService],
})
export class OrdersModule {}

اس ماڈیول سے سروس ایکسپورٹ کریں۔ OrdersModule آپ کھا سکتے ہیں:

@Module({
  providers: [InventoryService],
  exports: [InventoryService],
})
export class InventoryModule {}

اور:

@Module({
  providers: [PaymentsService],
  exports: [PaymentsService],
})
export class PaymentsModule {}

آخری درآمد OrdersModule ~ میں AppModule. یہ CLI کے ذریعہ خود بخود ہونا چاہئے، لیکن دوبارہ چیک کریں کہ آیا آپ نے CLI استعمال نہیں کیا ہے۔

درخواست کی جانچ

مشاہدے کو شامل کرنے سے پہلے، آئیے پہلے یہ یقینی بنائیں کہ ایپلیکیشن خود کام کر رہی ہے۔ یہ درخواست چیک آؤٹ کا پورا راستہ چلاتی ہے۔ کنٹرولر کو درخواست موصول ہوتی ہے، OrdersService جب آپ انوینٹری، پھر ادائیگیوں کو کال کرتے ہیں، تو API مشترکہ نتیجہ لوٹاتا ہے۔

تقریباً 790ms کا جوابی وقت جان بوجھ کر ہے۔ جب مشاہدہ فعال ہوتا ہے، تو یہ تحقیقات کے لیے کارکردگی کے مخصوص مسائل فراہم کرتا ہے۔

درخواست کو دوبارہ شروع کریں۔ $ npm run start:dev.

پھر کال کریں۔

curl -X POST http://localhost:3000/orders 
  -H "Content-Type: application/json" 
  -d '{"productId":"book-123","amount":49}'

آپ کو اس سے ملتے جلتے نتائج مل سکتے ہیں:

{
  "id": "order_...",
  "productId": "book-123",
  "amount": 49,
  "inventory": {
    "productId": "book-123",
    "reserved": true
  },
  "payment": {
    "id": "payment_...",
    "amount": 49,
    "status": "succeeded"
  }
}

درخواست میں تقریباً 40ms + 750ms ≒ 790ms لگتے ہیں۔

ہمارے پاس پہلے ہی چھوٹے پیمانے پر ایک مسئلہ ہے۔

فرض کریں کہ ایک صارف پیداوار میں اس کی اطلاع دیتا ہے۔ "آرڈر تخلیق سست ہے۔”

  • میں مسئلہ کو دوبارہ پیش کرسکتا ہوں۔ POST /orders ≈ 800ms

  • پھر سوال یہ بنتا ہے، "وہ 800ms کہاں گئے؟” یقیناً ہم اس کا جواب جانتے ہیں کیونکہ ہم نے یہ برا کوڈ لکھا ہے۔

لیکن دوسری صورت میں تصور کریں. آپ کی خدمت کچھ اس طرح نظر آ سکتی ہے:

OrdersService
    |
    +-- PostgreSQL
    |
    +-- Redis
    |
    +-- Inventory service
    |
    +-- Tax service
    |
    +-- Payment provider
    |
    +-- Fraud service

اب کیا؟ یہ وہ جگہ ہے جہاں مشاہدہ اہم ہو جاتا ہے۔

بنیادی حل: لاگنگ

ابتدائی طور پر آپ شامل کر سکتے ہیں:

console.log('Starting inventory');
await this.inventoryService.reserve(productId);
console.log('Inventory complete');
console.log('Starting payment');
await this.paymentsService.charge(amount);
console.log('Payment complete');

اب لاگ اس طرح لگتا ہے:

Starting inventory
Inventory complete
Starting payment
Payment complete

ہم اندازہ لگا سکتے ہیں کہ انوینٹری نسبتاً تیز تھی اور ادائیگی سست تھی، لیکن دیکھیں کہ ہم کیا کر رہے ہیں۔ ہم دستی طور پر اطلاق کی منطق کے ارد گرد آلات شامل کر رہے ہیں۔ جیسے جیسے آپ کی درخواست بڑھتی جاتی ہے، یہ زیادہ سے زیادہ مہنگی ہوتی جاتی ہے۔

اور ہم نے ابھی تک درخواست کے لیے کوئی منظم نمائندگی نہیں بنائی ہے۔

ہمیں کیا نشانات دیتے ہیں۔

ٹریس پھانسی کا درخت فراہم کرتا ہے۔

POST /orders
│
└── OrdersController.create()
    │
    └── OrdersService.createOrder()
        │
        ├── InventoryService.reserve()
        │
        └── PaymentsService.charge()

اب منسلک وقت کا تصور کریں۔

POST /orders                       ~790ms
│
└── OrdersController.create        ~790ms
    │
    └── OrdersService.createOrder  ~790ms
        │
        ├── InventoryService        ~40ms
        │
        └── PaymentsService        ~750ms

مسئلہ واضح ہو جاتا ہے۔ اختتامی مقامات اب غیر معمولی طور پر سست نہیں ہیں۔ ادائیگی کی کارروائیوں میں آپ کا زیادہ تر وقت لگتا ہے۔

یہی فرق ہے۔ لاگ کے ساتھ اور پھانسی کو سمجھنا.

آئیے مشاہدہ کو کام پر لگائیں۔

پر $ nest new جب آپ کمانڈ چلاتے ہیں، تو ہو سکتا ہے کہ آپ نے پہلے سے ہی اپنے کوڈ کو بطور ڈیفالٹ تیار کرنے کا انتخاب کیا ہو۔ اگر آپ اسے قبول کرتے ہیں، تو آپ کو درج ذیل خرابی نظر آ سکتی ہے:

[Nest] 87392  - 09/13/2026, 9:09:11 PM   ERROR [ObserveAgentWorker] Error: Telemetry rejected (401). Check that appKey and appSecret are valid; the application is taken from the key. Credentials are read once at start-up, so this will not recover without a restart - further rejections are counted, not logged.

اب آئیے خود بھی یہی کام کرتے ہیں، آبزروی کو انسٹال کرنے اور NestJS ایپلیکیشن کو آلہ بنانے سے شروع کرتے ہیں۔

$ npm install @nestjs/observe

مشاہدہ پیکج Nest ایپلی کیشنز میں انسٹرومینٹیشن کو ضم کرنے کے لیے مددگاروں کو بے نقاب کرتا ہے۔ اب src/observe.ts src فولڈر میں، درج ذیل مواد کے ساتھ ایک فائل بنائیں:

import { createObserveModule } from '@nestjs/observe';

export const {
  ObserveModule,
  ObserveInstrument,
} = createObserveModule();

یہ ہمیں NestJS انضمام فراہم کرتا ہے جس کی ہمیں ضرورت ہے۔

مشاہدہ کی ترکیب

اپ ڈیٹ app.module.ts:

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { OrdersModule } from './orders/orders.module';
import { InventoryModule } from './inventory/inventory.module';
import { PaymentsModule } from './payments/payments.module';
import { ObserveModule } from './observe';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    // we're loading secrets from env file - which is an async operation (hence we use forRootAsync()
    ObserveModule.forRootAsync({
      inject: [ConfigService],
      // useFactory defers reading the env vars until Nest has loaded .env, instead of evaluating process.env when the @Module decorator first runs 
      useFactory: (config: ConfigService) => ({
        appKey: config.getOrThrow('OBSERVE_APP_KEY'),
        appSecret: config.getOrThrow('OBSERVE_APP_SECRET'),
        serviceId: config.getOrThrow('OBSERVE_SERVICE_ID'),
      }),
    }),
    OrdersModule,
    InventoryModule,
    PaymentsModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

اس ترتیب میں، تین چیزیں ہوتی ہیں:

ConfigModule.forRoot({ isGlobal: true }) ماحول کے متغیرات کو لوڈ کریں۔ ConfigService پوری درخواست میں دستیاب ہے۔

ObserveModule.forRootAsync() Nest کو فکسڈ آبجیکٹ کے بجائے فیکٹری فنکشن کا استعمال کرتے ہوئے مشاہدہ انضمام کو شروع کرنے کی ہدایت کرتا ہے۔ گھوںسلا انجکشن ConfigService مشاہدہ کی اسناد کو اس فیکٹری میں ذخیرہ کرنے اور کنفیگریشن لوڈ ہونے کے بعد ہی پڑھا جاتا ہے۔

آخر کار serviceId ٹیلی میٹری کے لیے ایک قابل اعتماد شناخت فراہم کرتا ہے تاکہ آبزروی پلیٹ فارم کو معلوم ہو کہ ڈیٹا کا تعلق کس ایپلی کیشن/سروس سے ہے۔

استعمال کریں getOrThrow() وہ بھی جان بوجھ کر۔ اگر ان میں سے کوئی ایک مطلوبہ قدر غائب ہے تو، ایپلیکیشن خود بخود ایک نامکمل مشاہداتی ترتیب کے ساتھ شروع ہونے کے بجائے سٹارٹ اپ میں واضح طور پر ناکام ہو جائے گی۔

جب آپ کوئی سروس بناتے ہیں تو آبزروی ڈیش بورڈ سے اسناد حاصل کی جاتی ہیں۔ آبزروی پلیٹ فارم پر جائیں اور اپنے پلیٹ فارم کو محفوظ بنائیں۔ اگر آپ Nest ایکو سسٹم میں نئے ہیں تو کوڈ کے ٹکڑوں میں دی گئی تفصیل پر توجہ دیں۔

اسے اپنے ماحول میں رکھیں۔

OBSERVE_APP_KEY=...
OBSERVE_APP_SECRET=...

اس کے ساتھ کسی دوسرے ایپلیکیشن کے راز کی طرح سلوک کریں۔

Nest ایپلیکیشن کا آلہ

ابھی اپ ڈیٹ کریں۔ main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ObserveInstrument } from './observe';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    instrument: ObserveInstrument,
  });
  await app.listen(process.env.PORT ?? 3000);
}
void bootstrap();

یہ وہ جگہ ہے جہاں یہ دلچسپ ہو جاتا ہے۔ ہم نے دستی طور پر پیک نہیں کیا۔ OrdersController.create() یا OrdersService.createOrder() مشاہداتی کوڈ استعمال کریں۔ اس کے بجائے، NestJS انٹیگریشن آپ کو فریم ورک کے ایگزیکیوشن ماڈل کی بنیاد پر اپنی ایپلیکیشن کو انسٹرومنٹ کرنے کی اجازت دیتا ہے۔

یہی چیز اس نقطہ نظر کو ہر جگہ لاگنگ کے بیانات شامل کرنے سے مختلف بناتی ہے۔

کچھ ٹریفک پیدا کریں۔

درخواست کو دوبارہ شروع کریں۔

$ npm run start:dev

یہ کسی قسم کے بوجھ کو نقل کرنے کے لیے چند درخواستیں تیار کرتا ہے۔

for i in {1..20}; do
  curl -s -X POST http://localhost:3000/orders 
    -H "Content-Type: application/json" 
    -d '{"productId":"book-123","amount":49}' 
    > /dev/null
done

اب اپنے آبزروی ڈیش بورڈ کا معائنہ کریں، یہ درج ذیل اسکرین شاٹ کی طرح نظر آنا چاہیے:

شکل 3: مشاہداتی ڈیش بورڈ میں / آرڈر کی درخواست کی پیمائش

آبزروی ڈیش بورڈ اس کے لیے ٹیلی میٹری دکھاتا ہے: /orders یہ درخواست کی سرگرمی اور تاخیر کا ایک اعلیٰ سطحی نظارہ فراہم کرتا ہے، جس سے آپ یہ تحقیق کر سکتے ہیں کہ آپ کی درخواستوں کے کن حصوں میں زیادہ وقت لگ رہا ہے۔

جیسا کہ پروڈکٹ تیار ہوتا ہے عین مطابق UI اور دستیاب آراء تبدیل ہو سکتے ہیں۔ اب ہم درج ذیل سوالات کا جواب دے سکتے ہیں:کون سا بلاک 800ms میں سے سب سے زیادہ وقت لیتا ہے؟حقیقی ایپلیکیشن بوجھ کے تحت یہ اور بھی دلچسپ ہو جاتا ہے۔

اہم حصہ ڈیش بورڈ نہیں ہے۔

آپ شاید یہاں رک کر کہنا چاہیں، "یہ بہت اچھا ہے، NestJS میں اب ٹریکنگ کی فعالیت ہے۔” یہ جو ہم دیکھ رہے ہیں اسے کم کر رہا ہے۔ دلچسپ بات یہ ہے کہ ذخیرہ الفاظ۔

ہم صرف HTTP یا Node.js یا db کو نہیں دیکھ رہے ہیں، ہم کنٹرولرز، فراہم کنندگان، خدمات وغیرہ جیسے تصورات کو دیکھ رہے ہیں جو ممکنہ طور پر براہ راست NestJS ایپلیکیشن میں موجود ہیں۔

یہ فریم ورک سے آگاہ آلات کا ممکنہ فائدہ ہے۔ فریم ورک پہلے ہی ان اجزاء کو سمجھتا ہے۔ ٹیلی میٹری پیدا کرتے وقت آبزروی اس سمجھ کو استعمال کر سکتا ہے۔

آئیے اپنی درخواست کے لیے ایک حقیقی مسئلہ پیدا کرنے کے لیے ٹائم آؤٹ کو 750 سے 2500 میں تبدیل کریں۔

ایک بار پھر ٹریفک پیدا کریں۔ اب اختتامی نقطہ تقریباً 40ms + 2500ms ≒ 2540ms لیتا ہے۔ مان لیں کہ آپ ایک پروڈکشن واقعہ کو ڈیبگ کر رہے ہیں۔

سورس کوڈ کو مت دیکھیں۔ ان سوالات کے ساتھ ٹریکنگ شروع کریں: /orders کیا اس میں 2.5 سیکنڈ لگتے ہیں؟”

ٹریکنگ آپ کو یہاں سے آگے بڑھنے کی اجازت دے گی: POST /orders کو OrdersService.createOrder کو PaymentsService.charge سست آپریشن کی شناخت کریں۔ یہ کام کا بہاؤ ہے جو اچھی مشاہدے کی اجازت دیتا ہے۔

پہلے نشان سے آگے کیسے جانا ہے۔

خودکار اور دستی پیمائش

خودکار آلہ طاقتور ہے، لیکن یہ سب کچھ نہیں سمجھتا۔ Nest سب کچھ جانتا ہے (HTTP، کنٹرولر، وغیرہ)۔ آپ خود بخود محسوس نہیں کریں گے کہ یہ خصوصیت آپ کے کاروبار کے لیے خاص طور پر اہم ہے۔

async calculateCheckoutDiscount(cart: Cart) {
  // complicated business logic
}

اس آپریشن میں لگ بھگ 400ms لگ سکتے ہیں اور یہ ادائیگی کی پائپ لائن کے سب سے اہم حصوں میں سے ایک ہے۔ فریم ورک ضروری طور پر اس کا اندازہ نہیں لگا سکتا۔

یہ وہ جگہ ہے جہاں دستی میٹرولوجی کام آتی ہے۔

عام ماڈلز میں شامل ہیں:

Automatic instrumentation
            +
Manual instrumentation
            =
Useful application telemetry

خودکار میٹرولوجی ہمیں فریم ورک فراہم کرتی ہے۔ دستی انسٹرومینیشن ایپلیکیشن کے لیے مخصوص معنی کا اضافہ کرتی ہے۔

یہ ایک آسان جال ہے۔ ایک بار جب آپ کو کوئی ٹریس مل جاتا ہے، تو یہ ہر خصوصیت کو آلہ بنانے کے لیے پرکشش ہوتا ہے۔

functionA()
functionB()
functionC()
functionD()
functionE()
functionF()

لیکن آپ کو اس طرح نہیں کرنا چاہئے۔ ہر چیز کی پیمائش نہ کریں۔ مقصد سب سے بڑی پگڈنڈی بنانا نہیں ہے۔ مفید ٹیلی میٹری۔.

دستی آلات کے اچھے امیدواروں میں شامل ہیں:

  • ایک مہنگا کاروبار چلانا

  • بیرونی کرنسی

  • تنقیدی ورک فلو

  • ایک مہنگا حساب

  • تاخیر سے متعلق اہم آپریشن

  • اہم کاروباری تقریب

مثال کے طور پر:

checkout.calculatePrice
fraud.evaluate
payment.authorize
invoice.generate

نام کے معنی ہیں۔

میٹرکس: جب ٹریکنگ کافی نہیں ہے۔

ہم کہتے ہیں کہ آپ جاننا چاہتے ہیں کہ کتنے آرڈرز تیار ہوتے ہیں۔ ٹریکنگ اس کے لیے بہترین ٹول نہیں ہے۔

ہم درج ذیل میٹرکس چاہتے ہیں: orders.created یا payments.failed یا checkout.duration. میٹرکس ہمیں مکمل تصویر فراہم کرتا ہے۔

مثال کے طور پر:

orders.created_total
    12,430
payment.failures_total
    183
checkout_latency_p95
    840ms

اب ہم سوالات پوچھ سکتے ہیں اور جواب دے سکتے ہیں جیسے، "کیا حال ہی میں صبح 2 بجے ریلیز ہونے کے بعد سے سسٹم خراب ہو رہا ہے؟”

نشانات کا جواب "اس مخصوص کام کا کیا ہوا؟” اور میٹرکس جواب دیتے ہیں "سسٹم بھر میں کیا ہو رہا ہے؟” دونوں ہی کارآمد ہیں، خاص طور پر جب آپ کی ایپلیکیشن نے کچھ توجہ حاصل کی ہو۔

غلطیاں بھی ٹیلی میٹرک ہیں۔

درج ذیل کوڈ پر غور کریں:

try {
  await this.paymentsService.charge(amount);
} catch (error) {
  return {
    status: 'pending',
  };
}

استثنیٰ کو درخواست کے نقطہ نظر سے ہینڈل کیا گیا ہے۔ آپریشنل نقطہ نظر سے، ہمیں اب بھی گہری تشویش ہو سکتی ہے کہ ایسا ہوا۔

یہ ایک اہم فرق کی طرف جاتا ہے۔ درخواست کی درستگی اور آپریشنل مرئیت ہمیشہ ایک جیسی نہیں ہوتی۔

غلطیوں کو ایپلیکیشن کے ذریعے سنبھالا جا سکتا ہے اور ساتھ ہی یہ مشن انتہائی اہم ہے۔ یہی وجہ ہے کہ مشاہدے کو ہینڈل شدہ غلطیوں اور غیر ہینڈل کریشز کا حساب دینا چاہیے۔

HTTP سے آگے: ایپلی کیشنز میں کارروائیوں کا سراغ لگانا

اب تک ہم نے صرف HTTP درخواستوں کو دیکھا ہے۔ اصل NestJS ایپلیکیشن وہیں نہیں رکتی۔ اس میں اکثر BullMQ ٹاسک، شیڈولڈ ٹاسک، RPC ہینڈلرز، GraphQL حل کرنے والے، اور پس منظر کے کاموں کی دوسری شکلیں شامل ہوتی ہیں۔ آبزروی پروجیکٹ میں فی الحال ان میں سے کچھ Nest کے مخصوص ایگزیکیوشن راستوں کے لیے خودکار آلات شامل ہیں۔

آرڈر پروسیسنگ کے بہاؤ پر غور کریں جہاں ایک ابتدائی HTTP درخواست آرڈر بناتی ہے اور پھر ادائیگی کی قطار لگاتی ہے۔

POST /orders -> Create order -> Queue payment -> BullMQ -> Payment worker

اب تصور کریں کہ صارف کہتا ہے، "آپ کا آرڈر بن گیا، لیکن ادائیگی میں 10 منٹ لگے۔” HTTP درخواست خود چند سو ملی سیکنڈ میں مکمل ہو سکتی ہے۔ تاخیر قطاروں، کارکنوں، بہاو خدمات، یا ادائیگی فراہم کرنے والوں کے اندر ہو سکتی ہے۔

یہ صرف ایک سست HTTP اختتامی نقطہ تلاش کرنے سے بہت مختلف ڈیبگنگ مسئلہ ہے۔ ٹریسنگ خاص طور پر اس وقت مفید ہوتی ہے جب ایک منطقی عمل عمل کی حد کو عبور کرتا ہے، کیونکہ کہانی کے اہم حصے اصل درخواست کے مکمل ہونے کے بعد ہو سکتے ہیں۔

یہ وہ جگہ ہے جہاں سیاق و سباق اہم ہو جاتا ہے۔ جیسے جیسے کوئی کام سسٹم کے ذریعے منتقل ہوتا ہے، یہ معلومات کے ساتھ گزر سکتا ہے جیسے کہ ٹریکنگ ID، اسکوپ ID، درخواست ID، سروس، ماحولیات اور علاقہ۔

HTTP request
      |
      +---- Service A
      |
      +---- Queue
              |
              +---- Worker
                      |
                      +---- Service B

ہر سروس کے لاگز کو دستی طور پر تلاش کرنے اور اس بات کا تعین کرنے کے بجائے کہ کون سے آئٹمز ایک ہی آپریشن سے تعلق رکھتے ہیں، تقسیم شدہ ٹریسنگ آپ کو ان آپریشنز کو آپس میں جوڑنے کی اجازت دیتی ہے۔ یہ OpenTelemetry میں تقسیم شدہ ٹریکنگ اور سیاق و سباق کی تبلیغ کے ماڈل کے پیچھے ایک اہم خیال ہے۔

مشاہدے کی ایک اور جہت ہے جو اس وقت اہم ہو جاتی ہے جب ایپلی کیشن میں ہی مسائل ہوں۔

تصور کریں کہ ٹریکنگ آپ کو بتاتی ہے:

POST /orders
≈ 2 seconds

تاہم، کوئی سست ڈیٹا بیس سوالات، سست بیرونی APIs، قطار میں تاخیر، اور واضح انحصار کے مسائل نہیں ہیں۔ کیا ہوگا اگر Node.js عمل خود متاثر ہو رہا ہے؟

اب ہمیں ایک مختلف قسم کی ٹیلی میٹری کی ضرورت ہے۔ آپ پوچھ سکتے ہیں کہ آیا کوئی عمل سی پی یو سے منسلک ہے، کیا میموری کا استعمال بڑھ رہا ہے، کیا کوڑا اٹھانا تاخیر کو متاثر کر رہا ہے، آیا ایونٹ لوپ دباؤ میں ہے، یا آیا ایک فنکشن زیادہ مقدار میں CPU استعمال کر رہا ہے۔

یہ وہ جگہ ہے جہاں رن ٹائم میٹرکس اور پروفائلنگ کام آتی ہے۔ ایپلیکیشن انسٹرومینٹیشن کے علاوہ، آبزروی کے موجودہ فیچر سیٹ میں رن ٹائم میٹرکس اور سی پی یو پروفائلنگ شامل ہے۔ لہذا، ایپلیکیشن مشاہدے کو خود HTTP درخواست پر رکنے کی ضرورت نہیں ہے۔ بعض اوقات مسئلہ رن ٹائم کا ہوتا ہے جو ایپلیکیشن چلاتا ہے۔

ذہن میں رکھنے کے لیے اہم حدود بھی ہیں۔ ٹریسنگ خود بخود بنیادی وجہ کو ظاہر نہیں کرتی ہے۔

فرض کریں کہ ہم دیکھتے ہیں:

POST /orders       3 seconds
PaymentsService    2.9 seconds

اس نے مسئلہ کو مقامی بنایا، لیکن ضروری طور پر اس کی وضاحت نہیں کی۔ PaymentsService سست ادائیگی فراہم کنندہ، ڈیٹا بیس کے سوالات میں بہت زیادہ وقت لگنے، نیٹ ورک میں تاخیر میں اضافہ، کنکشن پول کی تھکن، یا فراہم کنندہ کی دوبارہ کوشش کی کارروائیوں کی وجہ سے سست روی واقع ہو سکتی ہے۔

مشاہدہ تلاش کی جگہ کو تنگ کرتا ہے۔ یہ انجینئرنگ کے فیصلے کا متبادل نہیں ہے۔ ایک اچھا مشاہداتی نظام تحقیقات کو تیز تر بناتا ہے۔ اس کا مطلب یہ نہیں کہ تحقیقات غیر ضروری ہو جاتی ہیں۔

جہاں مشاہدہ فٹ بیٹھتا ہے: NestJS، OpenTelemetry، اور Wider Ecosystem

اس مقام پر، مشاہدے کو بڑے مشاہداتی ماحول میں لاگو کرنا اچھا خیال ہو سکتا ہے۔

مشاہدہ اور اوپن ٹیلی میٹری صرف دو قابل تبادلہ مصنوعات نہیں ہیں۔ OpenTelemetry ایک وینڈر غیر جانبدار مشاہداتی فریم ورک اور ٹول کٹ ہے جو آپ کی ایپلیکیشنز اور انفراسٹرکچر میں ٹیلی میٹری کو پیدا کرنے، جمع کرنے اور برآمد کرنے کا ایک معیاری طریقہ فراہم کرتا ہے۔

آسان فن تعمیر مندرجہ ذیل ہے:

NestJS
   |
OpenTelemetry
   |
Collector
   |
   +---- Grafana
   +---- Jaeger
   +---- Datadog
   +---- New Relic
   +---- other backend

مشاہدہ زیادہ رائے والا ہے۔

NestJS
   |
Observe
   |
Observe platform

لہذا دلچسپ فرق یہ نہیں ہے کہ "ایک کے پاس ٹریکنگ ہے اور دوسرے کے پاس نہیں”۔ مزید مفید سوالات میں شامل ہیں:

NestJS ایگزیکیوشن ماڈل کا کتنا آلہ خود بخود سمجھنا چاہیے؟

OpenTelemetry کی اہم طاقت اس کی پورٹیبلٹی ہے۔ تصور کریں کہ ایک کمپنی 8 NestJS سروسز، 2 Go سروسز، 4 Python سروسز، اور 3 .NET سروسز چلا رہی ہے۔ آپ شاید چار مکمل طور پر مختلف مشاہداتی آرکیٹیکچرز نہیں چاہتے ہیں۔ عام ٹیلی میٹری، سیاق و سباق، اصطلاحات، پسدید، اور آپریشنل طریقوں کی ضرورت ہے۔

یہ وہ مسئلہ ہے جسے حل کرنے کے لیے OpenTelemetry کو ڈیزائن کیا گیا تھا۔

مشاہدہ ایک مختلف تجارت کرتا ہے۔ ایک درجن NestJS خدمات اور ڈویلپرز کے ساتھ ایک تنظیم کا تصور کریں جو قدرتی طور پر کنٹرولرز، فراہم کنندگان، ماڈیولز، گارڈز، انٹرسیپٹرز، حل کرنے والوں، قطاروں اور دیگر NestJS تصورات کے حوالے سے سوچتے ہیں۔ اگر مشاہداتی ٹولز خود بخود ان تصورات کو سمجھ سکتے ہیں، تو ڈویلپر کا تجربہ آسان ہو سکتا ہے کیونکہ ٹیلی میٹری کا اظہار ان شرائط میں کیا جاتا ہے جسے انجینئر پہلے ہی اپنی ایپلی کیشنز کے بارے میں استدلال کرنے کے لیے استعمال کرتے ہیں۔

ضروری نہیں کہ ان طریقوں کا مقابلہ کیا جائے۔

کچھ مفید فن تعمیرات میں شامل ہیں:

شکل 4: فن تعمیر NestJS، OpenTelemetry، اور مشاہداتی پس منظر دکھا رہا ہے۔

مندرجہ بالا آرکیٹیکچر ایک تہہ دار نقطہ نظر کو ظاہر کرتا ہے جہاں NestJS فریم ورک کی سطح کا سیاق و سباق فراہم کرتا ہے، OpenTelemetry معیاری ٹیلی میٹری اور انٹرآپریبلٹی فراہم کرتا ہے، اور ایک مشاہداتی بیک اینڈ اسٹوریج، ویژولائزیشن، الرٹنگ، اور تجزیات کو ہینڈل کرتا ہے۔

فریم ورک عمل درآمد کے سیاق و سباق اور فریم ورک کی سطح کے آلات فراہم کر سکتے ہیں۔ ٹیلی میٹری کے معیارات عام سیمنٹکس، سیاق و سباق کی تبلیغ، اور انٹرآپریبلٹی فراہم کر سکتے ہیں۔ پسدید اسٹوریج، سوالات، تصورات، انتباہات، اور تجزیات فراہم کر سکتا ہے۔

یہ علیحدگی معنی رکھتی ہے۔

NestJS مشاہدے کو ایپلیکیشن فریم ورک اور رن ٹائم کے قریب منتقل کرنے میں بھی اکیلا نہیں ہے۔

مثال کے طور پر، .NET ماحولیاتی نظام میں تصورات کے ارد گرد بنائے گئے فریم ورک اور رن ٹائم تشخیص ہیں جیسے: Activityیہ میٹرکس اور لاگنگ فراہم کرتا ہے، اور OpenTelemetry ٹیلی میٹری کو باہم مربوط اور برآمد کرنے کا ایک معیاری طریقہ فراہم کرتا ہے۔

جاوا میں اسپرنگ بوٹ جیسے فریم ورک اور مائیکرو میٹر جیسی لائبریریوں کے لیے بالغ مشاہداتی ٹولز ہیں۔

Python میں Django اور FastAPI جیسے فریم ورکس کے لیے OpenTelemetry انضمام ہے، جبکہ Go ایپلی کیشنز عام طور پر HTTP، gRPC، اور دیگر لائبریریوں میں OpenTelemetry آلات استعمال کرتی ہیں۔

نفاذ مختلف ہے، لیکن وسیع سمت ایک جیسی ہے۔ ایپلیکیشن کے ایگزیکیوشن ماڈل سے مشاہدہ جتنا قریب ہوگا، اتنا ہی مفید سیاق و سباق یہ خود بخود پکڑ سکتا ہے۔

یہ مشاہدہ کرنے کے لیے ایک دلچسپ خیال ہے۔ NestJS نے مشاہداتی ایجاد نہیں کیا، اور فریم ورک کے لیے مخصوص آلات وسیع تر ماحولیاتی نظام کا متبادل نہیں ہیں۔ بلکہ، NestJS فریم ورک کی سطح پر شرط لگا رہا ہے کہ NestJS ایگزیکیوشن ماڈل کے اندر کام کرنے والے ڈویلپرز کی طرف سے مشاہدے کو کیسے محسوس کیا جا سکتا ہے۔

یہاں قدرتی تجارت ہے۔ مشاہداتی نظام NestJS کو جتنا گہرا سمجھتا ہے، یہ NestJS ڈویلپرز کے لیے اتنا ہی زیادہ مفید ہو گا، لیکن یہ تخصص اسے کم پورٹیبل بھی بنا سکتا ہے۔

اگر آپ کی تنظیم NestJS میں اہم سرمایہ کاری کر رہی ہے، تو فریم ورک کے لیے مخصوص سیاق و سباق بہت اہم ہو سکتا ہے۔ اگر آپ متعدد زبانوں میں درجنوں خدمات چلاتے ہیں، تو ایک عام OpenTelemetry پر مبنی فن تعمیر زیادہ اہم ہو سکتا ہے۔ کوئی بھی نقطہ نظر خود بخود تمام ماحول کے لیے موزوں نہیں ہے۔ فن تعمیر اس بات کا تعین کرتا ہے کہ کیا اہم ہے۔

حقیقی ایپلی کیشنز میں مشاہدہ کا اندازہ کیسے لگایا جائے۔

فیصلے کا ایک اور حصہ جسے آسانی سے نظر انداز کیا جا سکتا ہے وہ لاگت ہے۔

مشاہدے کے حل کا موازنہ کرتے وقت، لوگ اکثر درج ذیل فیصلے کرتے ہیں:

Tool A = $X
Tool B = $Y
OpenTelemetry = free

یہ نامکمل ہے۔

مشاہداتی حل کی اصل قیمت میں سافٹ ویئر، انفراسٹرکچر، اسٹوریج، انجینئرنگ کا وقت، دیکھ بھال، ترتیب، اور واقعہ کے ردعمل کے آپریشنل اخراجات شامل ہو سکتے ہیں۔

OpenTelemetry بذات خود اوپن سورس ہے، لیکن اگر آپ اس کے ارد گرد ایک مشاہداتی پلیٹ فارم بناتے ہیں، تو پھر بھی کسی کو کلکٹر، اسٹوریج، ڈیش بورڈز، الرٹس، برقرار رکھنے کی پالیسیاں، سیکیورٹی اور اپ گریڈ کو چلانے کی ضرورت ہوگی۔

میزبان پلیٹ فارم کچھ بنیادی ڈھانچے کے بوجھ کو کم کرتے ہیں، لیکن یہ سہولت قیمت پر آتی ہے۔ اس کے برعکس، اوپن سورس اسٹیک آپ کو زیادہ کنٹرول فراہم کرتے ہیں، لیکن ان کو چلانے کے لیے پیسے بھی خرچ ہوتے ہیں۔

لہذا، آپ کو پیداوار کا کوئی بھی فیصلہ کرنے سے پہلے موجودہ سرکاری قیمتوں کے صفحہ کا موازنہ کرکے ہمیشہ قیمتوں کو چیک کرنا چاہیے۔ اس تحریر کے مطابق، آبزروی پروجیکٹ ہر ماہ 300,000 واقعات کے مفت درجے کی تشہیر کر رہا ہے، جو تجربات کو نسبتاً قابل رسائی بناتا ہے۔ تاہم، ایونٹ پر مبنی قیمتوں کا تعین ایک اور اہم تصور متعارف کرایا ہے: ٹیلی میٹری والیوم۔

ایک درخواست کی درخواست HTTP آپریشنز، متعدد اسکوپس، لاگز، غلطیاں اور دیگر ٹیلی میٹری پیدا کر سکتی ہے۔ زیادہ ٹریفک والیوم تیزی سے بڑھ سکتے ہیں۔ لہذا، مشاہدے کے لیے اپنی صلاحیت کی منصوبہ بندی کی ضرورت ہوتی ہے۔

زیادہ ٹیلی میٹری کا مطلب خود بخود بہتر نہیں ہے۔

ہر ایونٹ کے ساتھ درج ذیل کو منسلک کرنے کا تصور کریں:

userId
requestId
transactionId
tenantId
email

اگرچہ یہ زیادہ سیاق و سباق پیدا کرتا ہے، لیکن یہ ممکنہ طور پر اعلیٰ قلبی، اسٹوریج کی بڑھتی ہوئی ضروریات، رازداری کے خدشات، بڑے بل، اور زیادہ پیچیدہ سوالات بھی پیدا کرتا ہے۔

کچھ معلومات کو کسی مشاہداتی پلیٹ فارم پر بے دریغ نہیں بھیجا جانا چاہیے۔ توثیقی ہیڈرز، کوکیز، پاس ورڈز، API کیز، ٹوکنز، ادائیگی کی معلومات، اور ذاتی معلومات پر خاص توجہ دیں۔

مثال کے طور پر، یہ ہے جو آپ کو آنکھیں بند کرکے نہیں کرنا چاہئے:

span.setAttribute(
  'headers',
  JSON.stringify(request.headers),
);

آخر کار، آپ اپنے ٹیلی میٹری بیک اینڈ پر ایک تصدیقی ٹوکن یا کوکی بھیج سکتے ہیں۔

ٹیلی میٹری ڈیٹا ہے۔ اسے پروڈکشن ڈیٹا کی طرح سمجھیں۔

ٹریفک کے حجم میں اضافے کے ساتھ نمونے لینا بھی اہم ہو سکتا ہے۔ چھوٹی ایپلی کیشنز کے لیے ہر چیز کو لاگ کرنا درست سمجھ میں آتا ہے، لیکن فی سیکنڈ ہزاروں درخواستوں کو سنبھالنے والے سسٹمز کے لیے آپ کو ٹیلی میٹری کی مقدار کو کم کرنے کی ضرورت پڑ سکتی ہے۔

حکمت عملی مندرجہ ذیل ہے:

100% of errors
100% of slow requests
10% of successful requests

درست حکمت عملی مکمل طور پر آپ کی درخواست اور آپریشنل ضروریات پر منحصر ہے۔ اہم نکتہ یہ ہے کہ مشاہدے کے لیے خود انجینئرنگ کی ضرورت ہوتی ہے۔

تو آپ کو کب سنجیدگی سے NestJS Observe کا جائزہ لینا چاہئے؟

NestJS کی بڑی درخواستیں واضح امیدوار ہیں۔ یہ خاص طور پر سچ ہے اگر آپ کے پاس مشاہداتی ڈھانچہ موجود نہیں ہے اور آپ کی ٹیم خود ایک مکمل مشاہداتی پلیٹ فارم بنانے اور چلانے کے بغیر مفید پیداواری مرئیت چاہتی ہے۔

یہ زیادہ دلچسپ ہو جاتا ہے جب آپ کی ایپلیکیشن روایتی HTTP APIs سے آگے بڑھ جاتی ہے اور BullMQ، GraphQL، مائیکرو سروسز، شیڈولڈ ٹاسک، یا دیگر ایگزیکیوشن پاتھز کا بہت زیادہ استعمال کرتی ہے جنہیں فریم ورک سے آگاہ انسٹرومینٹیشن سمجھ سکتا ہے۔

یہ ڈویلپرز کے لیے مندرجہ ذیل NestJS تصورات کے ساتھ اپنی ایپلی کیشنز کے بارے میں فطری طور پر استدلال کرنا بھی مفید ہو سکتا ہے۔

OrdersController
OrdersService
PaymentService

اس بات کو یقینی بنانا کہ ٹیلی میٹری انہی تصورات کی عکاسی کرتی ہے کسی واقعے کے دوران ایپلی کیشنز اور مشاہداتی نظاموں کے درمیان منتقل ہونے کے علمی اوور ہیڈ کو کم کر دیتی ہے۔

اس کا مطلب یہ نہیں ہے کہ تمام NestJS ایپلی کیشنز کو اسے اپنانا چاہیے۔

اگر آپ کے پاس پہلے سے ہی کلکٹرز، ڈیش بورڈز، انتباہات، SLOs، ٹریس، میٹرکس، لاگز، اور کراس سروس ارتباط کے ساتھ ایک بالغ OpenTelemetry پر مبنی مشاہداتی اسٹیک ہے، تو دوسرا پلیٹ فارم متعارف کرانے کے نتیجے میں غیر ضروری نقل پیدا ہو سکتی ہے۔

جب آپ کے پاس بہت سے کثیر لسانی فن تعمیر ہوتے ہیں تو وہی تحفظات لاگو ہوتے ہیں۔ اگر آپ کی کمپنی .NET, Go, Java, Python اور Rust کے ساتھ NestJS چلاتی ہے تو، ایک معیاری ٹیلی میٹری فن تعمیر فریم ورک کے لیے مخصوص سہولت سے زیادہ اہم ہو سکتا ہے۔

آپ کو اپنے پسدید اور تعیناتی کی ضروریات پر بھی غور کرنا چاہیے۔ اگر آپ کی تنظیم نے ایک موجودہ مشاہداتی پلیٹ فارم پر معیاری بنایا ہے، تو دستیاب انضمام اور برآمدی ماڈلز اہم ہیں۔ اگر تعمیل یا تعمیراتی وجوہات کی بنا پر سیلف ہوسٹنگ کی ضرورت ہے تو یاد رکھیں کہ اوپن سورس انسٹرومینٹیشن لائبریریوں کا خود بخود یہ مطلب نہیں ہے کہ میزبان مشاہداتی پلیٹ فارم کی خود میزبانی کی جا سکتی ہے۔

آخر میں، تمام ایپلی کیشنز کو نفیس مشاہداتی صلاحیتوں کی ضرورت نہیں ہے۔ ایک ڈویلپر اور کم سے کم آپریشنل رسک کے ساتھ ایک چھوٹا اندرونی API مکمل مشاہداتی اسٹیک کا جواز پیش نہیں کر سکتا۔

مشاہدہ جیسے ٹولز کا جائزہ لینے کا بہترین طریقہ فیچر چیک لسٹ کا موازنہ کرنا نہیں ہے۔ حقیقی دنیا کے مسائل پر تجربات چلائیں۔

ہم ایک نمائندہ درخواست منتخب کرتے ہیں اور کچھ کنٹرول شدہ غلطیاں متعارف کراتے ہیں۔

1. Slow database query
2. Slow external API
3. Increased error rate
4. CPU-heavy operation
5. Slow background job

پھر پیمائش کریں کہ واقعی کیا اہمیت ہے۔ انجینئرز کو وجہ کی نشاندہی کرنے میں کتنا وقت لگے گا؟

پہلے موجودہ اسٹیک کو استعمال کرنے کی کوشش کریں۔ پھر نیا اسٹیک استعمال کرنے کی کوشش کریں۔

یہ ڈیش بورڈز یا میٹرکس کا حساب لگانے سے کہیں زیادہ معنی خیز تشخیص ہے۔ مشاہدے کی اصل قدر تشخیص کے وقت کے قریب ہے۔

اگر آج کسی واقعے کی تشخیص میں 2 گھنٹے اور بہتر ٹیلی میٹری کے ساتھ 20 منٹ لگتے ہیں، تو یہ فرق آپ کی ٹیم کے لیے اصل آپریشنل قدر ہے۔

حتمی خیالات

مشاہدہ کا سب سے دلچسپ حصہ صرف یہ نہیں ہے کہ NestJS کے پاس نشانات پیدا کرنے کا ایک مختلف طریقہ ہے۔ ہم سالوں سے ایسا کرنے کے طریقے پیش کر رہے ہیں۔

ایک زیادہ دلچسپ خیال یہ ہے کہ فریم ورک خود مشاہداتی ماڈل کا حصہ ہوسکتا ہے۔

ان ماڈیولز، کنٹرولرز، پائپس، قطار کے صارفین وغیرہ کے بارے میں سوچیں جن کے بارے میں NestJS پہلے ہی جانتا ہے۔ یہ کوڈ کا بے ترتیب ٹکڑا نہیں ہے۔ یہ ایک معنی خیز اطلاق کی حد ہے۔

اگر ٹیلی میٹری خود بخود ان حدود کو سمجھ سکتی ہے تو مشاہداتی صلاحیت ڈویلپر کے ذہنی ماڈل کے قریب تر ہوجاتی ہے۔ انجینئرز سے درخواست کی مکمل طور پر الگ نمائندگی سیکھنے کے لیے کہنے کے بجائے، مشاہداتی نظام ان تصورات پر استوار کر سکتا ہے جو انجینئرز پہلے ہی سمجھتے ہیں۔

یہ ایک ممکنہ طور پر بڑا مسئلہ ہے۔

ایک ہی وقت میں، فریم ورک کی آگاہی کا مطلب یہ نہیں ہونا چاہیے کہ تمام مشاہداتی مسائل فریم ورک کے اندرونی تعلق رکھتے ہیں۔ NestJS کا فریم ورک + APM + لاگ ایگریگیشن + میٹرکس بیک اینڈ + ڈسٹری بیوٹڈ ٹریکنگ وغیرہ ہونا ضروری نہیں ہے۔

یہ مختلف خدشات ہیں۔

فریم ورک خاص طور پر عملدرآمد کے سیاق و سباق، لائف سائیکل کی معلومات، اجزاء کی حدود، اور فریم ورک کی سطح کے آلات فراہم کرنے کے لیے موزوں ہیں۔

ٹیلی میٹری کے معیارات عام سیمنٹکس، سیاق و سباق کی تبلیغ، انٹرآپریبلٹی، اور وینڈر کی غیرجانبداری فراہم کر سکتے ہیں۔ آبزرویبلٹی بیک اینڈ اسٹوریج، استفسارات، تصورات، انتباہات اور تجزیات فراہم کر سکتے ہیں۔

یہ علیحدگی مفید ہے کیونکہ یہ ہر پرت کو اس بات پر توجہ مرکوز کرنے کی اجازت دیتی ہے کہ وہ کیا بہتر کرتی ہے۔

لہذا، اگر آپ مشاہدہ کرنے کے لیے نئے ہیں، تو میں جس سادہ ترین ذہنی ماڈل کو برقرار رکھنا چاہوں گا وہ یہ ہے:

Logs
What happened?

Metrics
How often is it happening?

Traces
What happened during this operation?

Profiles
Where is the runtime spending resources?

Framework-aware instrumentation
What does the framework already know about how this operation happened?

یہ کنکشن ہے۔

فریم ورک روایتی طور پر ہماری مدد کے لیے موجود ہیں۔ تحریر درخواست یہ روٹنگ، انحصار انجیکشن، توثیق، مڈل ویئر، تصدیق، قطار، شیڈولنگ، اور بہت سے دوسرے اجزاء فراہم کرتا ہے۔

لیکن فریم ورک یہ بھی جانتا ہے کہ اس کے پرزے کیسے چلتے ہیں۔

اس کا مطلب یہ ہے کہ وہی علم ممکنہ طور پر ہماری تیار کردہ ایپلیکیشنز کی تشخیص، پروفائل، ٹریس، پیمائش اور ڈیبگ کرنے میں ہماری مدد کر سکتا ہے۔

ایک فریم ورک صرف یہ نہیں جانتا کہ آپ کی درخواست کی ساخت کیسے ہے۔ یہ کچھ جانتا ہے درخواست کیسے کام کرتی ہے۔.

اور یہ قیمتی معلومات ہے۔

Scroll to Top