اولین باری که واقعاً به قابلیت مشاهده نیاز دارید زمانی نیست که با آرامش به داشبورد نگاه می کنید. زمانی است که کاربر می نویسد "تسویه حساب کند است"، نمودار خطا عادی به نظر می رسد و در گزارش ها فقط یک ردیف از پیام های قطع شده را پیدا می کنید.
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 بسیار کمتر مفید است. وقتی یک Deploy چیزی را خراب می کند، می خواهید بر اساس نسخه در دو ثانیه فیلتر کنید.
قانون دوم: داده های حساس را در ویژگی ها قرار ندهید. ایمیلها، نشانهها، محمولههای اعداد صحیح و آدرسها نباید بهطور تصادفی به یک پشتیبان قابل مشاهده ختم شوند. اگر نیاز به شناسایی کاربر دارید، شناسه های داخلی، هش یا فیلدهای کمتر حساس را در نظر بگیرید.
قانون سوم: به کاردینالیته توجه کنید. user.id به عنوان یک ویژگی trace می تواند معنا پیدا کند. به عنوان یک برچسب متریک می تواند هزینه ها و عملکرد شما را از بین ببرد.
معیارها: کم، اما خوب
من با معیارهای بسیار کاربردی شروع می کنم:
- نرخ ها، خطاها و مدت زمان درخواست ها؛
- تأخیر وابستگی های خارجی؛
- تعداد دفعات و تلاش های مجدد؛
- عمق دم؛
- مدت زمان کار؛
- درصد خطا در هر نسخه.
بقیه در صورت نیاز اضافه می شود. داشبوردهای پر از نمودارهایی که هیچ کس به آنها نگاه نمی کند مبلمان هستند، نه قابل مشاهده.
گزارش ها: هنوز مفید است، اما پیوند داده شده است
سیاههها ناپدید نمی شوند. زمانی که trace_id و span_id را حمل میکنند بسیار مفیدتر میشوند. بنابراین می توانید از یک گزارش خطا شروع کنید و trace را باز کنید، یا از یک trace کند شروع کنید و فقط گزارش های تولید شده در آن مسیر را بخوانید.
بدون همبستگی، شما به دنبال سوزن هستید. با همبستگی، حداقل می دانید که در کدام کشو باید نگاه کنید.
چک لیستی که قبل از گفتن "ما تحت پوشش هستیم" استفاده می کنم
- trace در واقع از چندین سرویس عبور می کند.
- گزارشها شامل
trace_idوspan_idهستند. - Collector با محدودیت های دسته بندی و حافظه پیکربندی شده است.
- خطاها در span ثبت می شوند.
- سیاست نمونه گیری وجود دارد.
- متریک ها کاردینالیته کنترل شده دارند.
- داده های حساس فیلتر شده است.
- هشدارها از علائم کاربر شروع می شوند، نه نمودارهای تصادفی.
نتیجه گیری
OpenTelemetry به تنهایی مشکلات تولید را حل نمی کند. اما نحوه برخورد با آنها تغییر می کند. به جای اضافه کردن کورکورانه گزارشها، شروع به دنبال کردن مسیر واقعی یک درخواست میکنید.
برای من نشانه این که کار میکند ساده است: وقتی چیزی اتفاق میافتد، تیم از پرسیدن "کجا به دنبال آن هستیم؟" و شروع به پرسیدن "چرا آن قطعه کند است؟" اینجاست که قابلیت مشاهده به یک ابزار تبدیل می شود، نه مجموعه ای از داشبورد.