আপনি যখন শান্তভাবে একটি ড্যাশবোর্ডের দিকে তাকাচ্ছেন তখন প্রথমবার আপনার সত্যিই পর্যবেক্ষণযোগ্যতার প্রয়োজন হয় না। এটি যখন একজন ব্যবহারকারী "চেকআউট ধীর" লেখেন, ত্রুটির গ্রাফটি স্বাভাবিক দেখায় এবং লগগুলিতে আপনি কেবল সংযোগ বিচ্ছিন্ন বার্তাগুলির একটি সারি পান৷
OpenTelemetry সেই মুহূর্তটি এড়াতে তৈরি করা হয়েছিল: আরও গ্রাফিক্সের জন্য নয়, টুকরোগুলিকে সংযুক্ত করার জন্য। একটি অনুরোধ API এ প্রবেশ করে, একটি ডাটাবেস কল করে, একটি বহিরাগত প্রদানকারীর মাধ্যমে যায়, একটি সারিবদ্ধ কাজ পোস্ট করে এবং পরে তিনটি পরিষেবা ব্যর্থ হতে পারে৷ বিতরণ করা ট্রেসিং ছাড়াই, আপনি সেই গল্পটি হাত দিয়ে পুনর্গঠন করেন। OpenTelemetry দিয়ে অন্তত আপনার কাছে একটি মানচিত্র আছে।
বিষয়টা trace নয়, এটা গল্প
A trace হল span এর একটি ক্রম। ঠাণ্ডা শোনাচ্ছে এমনভাবে রাখুন। অনুশীলনে, প্রতিটি span গল্পের একটি অংশ: POST /checkout, SELECT inventory, call payment provider, publish order.created।
আপনি যখন প্রকৃত প্রশ্নের উত্তর দিতে শুরু করেন তখন মানটি আসে:
- কোন বাহ্যিক পরিষেবার গতি কমছে?
- ত্রুটিগুলি কি একটি নির্দিষ্ট সংস্করণ থেকে আসে?
- সমস্যা কি সবাইকে প্রভাবিত করে নাকি শুধুমাত্র একজন ভাড়াটে?
- একটি পুনঃপ্রচেষ্টা কি একটি টাইমআউট লুকিয়ে রাখে?
- অ্যাসিঙ্ক্রোনাস কাজ শুরু হয় কিন্তু তারপর অন্য কোথাও মারা যায়?
হুট করে ছুড়ে দেওয়া console.log দ্বারা এই প্রশ্নগুলি সমাধান করা যায় না। প্রকৃতপক্ষে, প্রায়শই জরুরী সময়ে যোগ করা লগ আজ আপনাকে সাহায্য করে এবং আগামীকাল গোলমাল হয়ে যায়।
আমি কীভাবে এটি একটি অ্যাপে রাখব Node.js
স্বাস্থ্যকর সেটআপটি সহজ: অ্যাপটি টেলিমেট্রি তৈরি করে, Collector এটিকে কোথায় পাঠাতে হবে তা নির্ধারণ করে।
Node.js app -> OpenTelemetry Collector -> backend di observability
কেন সরাসরি বিক্রেতার কাছে রপ্তানি হচ্ছে না? কারণ প্রথমে এটি দ্রুত মনে হয়, তারপর আপনি বুঝতে পারেন যে প্রতিটি পরিষেবার আলাদা কনফিগারেশন, বিভিন্ন পুনঃপ্রচার, বিভিন্ন ফিল্টার এবং সংবেদনশীল ডেটা অপসারণ বা গন্তব্য পরিবর্তন করার জন্য কোনও কেন্দ্রীয় বিন্দু নেই।
Collector সমস্ত সঠিক উপায়ে বিরক্তিকর। এটি OTLP গ্রহণ করে, ব্যাচিং করে, ফিল্টার করতে পারে, স্যাম্পলিং করতে পারে, সাধারণ বৈশিষ্ট্য যোগ করতে পারে এবং একাধিক সিস্টেমে রপ্তানি করতে পারে।
স্ব-ইন্সট্রুমেন্টেশন: ভাল, কিন্তু যথেষ্ট নয়
Node.js-এ আমি স্বয়ংক্রিয়-ইন্সট্রুমেন্টেশন দিয়ে শুরু করব। এটি আপনাকে HTTP, সমর্থিত ফ্রেমওয়ার্ক, ডাটাবেস এবং সাধারণ লাইব্রেরিতে অবিলম্বে দৃশ্যমানতা দেয়।
npm install @opentelemetry/sdk-node \ @opentelemetry/auto-instrumentations-node \ @opentelemetry/exporter-trace-otlp-http
তারপরে আপনি বাকি অ্যাপের আগে SDK আরম্ভ করুন:
import { NodeSDK } from '@opentelemetry/sdk-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; const sdk = new NodeSDK({ traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, }), instrumentations: [getNodeAutoInstrumentations()], }); sdk.start();
যাইহোক, এটি আপনার পণ্য নয়, কাঠামোটি দেখে। এটি জানে যে আপনি একটি ক্যোয়ারী করেছেন, কিন্তু এটি জানেন না যে ক্যোয়ারী "ক্রীট অর্ডার" বা "সাবস্ক্রিপশন পুনর্নবীকরণ" এ ছিল। এর জন্য আপনার সেই পয়েন্টে span ম্যানুয়াল দরকার যেখানে আধিপত্য গণনা করা হয়।
const span = tracer.startSpan('checkout.create_order'); try { span.setAttribute('cart.items_count', input.items.length); const order = await createOrder(input); span.setAttribute('order.id', order.id); return order; } catch (error) { span.recordException(error as Error); throw error; } finally { span.end(); }
আমি কোথাও span ম্যানুয়াল রাখব না। আমি সেগুলিকে যেখানে রাখতাম, ভোর তিনটায়, আমি বুঝতে চাই যে অর্ধেক কোড বেস না পড়ে কী ঘটেছে।
তিনটি নিয়ম যা অনেক বিশৃঙ্খলা এড়ায়
প্রথম নিয়ম: প্রতিটি পরিষেবার অবশ্যই service.name, পরিবেশ এবং সংস্করণ থাকতে হবে। এটা তুচ্ছ মনে হয়, কিন্তু এই বৈশিষ্ট্যগুলি ছাড়া একটি trace অনেক কম দরকারী। যখন একটি স্থাপনা কিছু ভাঙে, আপনি দুই সেকেন্ডের মধ্যে সংস্করণ অনুসারে ফিল্টার করতে চান।
দ্বিতীয় নিয়ম: বৈশিষ্ট্যগুলিতে সংবেদনশীল ডেটা রাখবেন না। ইমেল, টোকেন, পূর্ণসংখ্যা পেলোড এবং ঠিকানাগুলি দুর্ঘটনাক্রমে একটি পর্যবেক্ষণযোগ্য ব্যাকএন্ডে শেষ হওয়া উচিত নয়। আপনি যদি একজন ব্যবহারকারীকে সনাক্ত করতে চান, তাহলে অভ্যন্তরীণ আইডি, হ্যাশিং বা কম সংবেদনশীল ক্ষেত্র বিবেচনা করুন।
তৃতীয় নিয়ম: কার্ডিনালিটির দিকে মনোযোগ দিন। user.id trace এর বৈশিষ্ট্য হিসাবে বোঝা যায়। একটি মেট্রিক লেবেল হিসাবে এটি আপনার খরচ এবং কর্মক্ষমতা ধ্বংস করতে পারে।
মেট্রিক্স: কম, কিন্তু ভাল
আমি খুব ব্যবহারিক মেট্রিক দিয়ে শুরু করব:
- হার, ত্রুটি এবং অনুরোধের সময়কাল;
- বাহ্যিক নির্ভরতার বিলম্ব;
- টাইমআউট এবং পুনরায় চেষ্টার সংখ্যা;
- লেজের গভীরতা;
- কাজের সময়কাল;
- প্রতি সংস্করণে ত্রুটির শতাংশ।
প্রয়োজনে বাকি যোগ করা হয়। গ্রাফে পূর্ণ ড্যাশবোর্ড যেগুলো কেউ দেখে না সেগুলো আসবাবপত্র, পর্যবেক্ষণযোগ্যতা নয়।
লগ: এখনও দরকারী, কিন্তু লিঙ্ক করা আছে
লগ অদৃশ্য না. যখন তারা trace_id এবং span_id বহন করে তখন তারা অনেক বেশি উপযোগী হয়ে ওঠে। সুতরাং আপনি একটি ত্রুটি লগ থেকে শুরু করতে পারেন এবং trace খুলতে পারেন, অথবা একটি ধীর trace থেকে শুরু করতে পারেন এবং শুধুমাত্র সেই পথে উত্পাদিত লগগুলি পড়তে পারেন৷
পারস্পরিক সম্পর্ক ছাড়া, আপনি সূঁচ খুঁজছেন. পারস্পরিক সম্পর্কের সাথে, অন্তত আপনি জানেন কোন ড্রয়ারে দেখতে হবে।
"আমরা আচ্ছাদিত" বলার আগে আমি যে চেকলিস্টটি ব্যবহার করব
- trace আসলে একাধিক পরিষেবা অতিক্রম করে।
- লগ
trace_idএবংspan_idঅন্তর্ভুক্ত। - Collector ব্যাচিং এবং মেমরি সীমার সাথে কনফিগার করা হয়েছে।
- ত্রুটিগুলি span এ রেকর্ড করা হয়েছে।
- একটি নমুনা নীতি আছে.
- মেট্রিক্স কার্ডিনালিটি নিয়ন্ত্রণ করেছে।
- সংবেদনশীল তথ্য ফিল্টার করা হয়.
- সতর্কতাগুলি ব্যবহারকারীর উপসর্গ থেকে শুরু হয়, এলোমেলো গ্রাফ নয়।
উপসংহার
OpenTelemetry নিজে থেকে উৎপাদন সমস্যার সমাধান করে না। কিন্তু আপনি তাদের সাথে মোকাবিলা করার উপায় পরিবর্তিত হয়। অন্ধভাবে লগ যোগ করার পরিবর্তে, আপনি একটি অনুরোধের প্রকৃত পথ অনুসরণ করা শুরু করেন।
আমার জন্য এটি কাজ করছে এমন চিহ্নটি সহজ: যখন কিছু ঘটে, দলটি "আমরা কোথায় খুঁজছি?" জিজ্ঞাসা করা বন্ধ করে দেয়। এবং জিজ্ঞাসা করা শুরু করে "কেন সেই অংশটি ধীর?" সেখানেই পর্যবেক্ষণযোগ্যতা একটি হাতিয়ার হয়ে ওঠে, ড্যাশবোর্ডের সংগ্রহ নয়।