OpenTelemetry در جنگ مشاهدهپذیری پیروز شده است — اکنون چه باید کرد؟

مشکل قفل شدن به فروشنده حل شده است
در بیشتر دهه ۲۰۱۰، انتخاب یک فروشنده مشاهدهپذیری به معنای ازدواج با کتابخانه ابزارگذاری آنها بود. عاملهای Datadog، SDKهای New Relic، خطوط اختصاصی Honeycomb — هر کدام کد برنامه شما را به یک پشتیبان خاص قفل میکردند. تغییر فروشنده به معنای ابزارگذاری مجدد هر سرویس بود. آن دوران تمام شده است.
OpenTelemetry اکنون استاندارد بالفعل برای رهگیری توزیعشده، متریکها و لاگها است. AWS، GCP، Azure، Datadog، Honeycomb، Grafana، New Relic، Dynatrace و هر پلتفرم مشاهدهپذیری بزرگی بومی از آن پشتیبانی میکنند. یک بار ابزارگذاری میکنید. به هر جایی مسیریابی میکنید.
OpenTelemetry در واقع چیست
OpenTelemetry یک پروژه CNCF است — در سال ۲۰۲۱ فارغالتحصیل شد — که از ادغام دو استاندارد رقیب متولد شد: OpenCensus (Google) و OpenTracing (CNCF). این ادغام اهمیت دارد زیرا تکهتکهگی را پایان داد. پیش از OpenTelemetry، باید یک طرف را انتخاب میکردید؛ اکنون تنها یک استاندارد وجود دارد.
این پروژه سه سیگنال مشاهدهپذیری را تعریف میکند:
- Traces: جریانهای درخواست توزیعشده در مرزهای سرویس، که به صورت درختی از Spanها با زمانبندی و ویژگیها نمایش داده میشوند.
- Metrics: اندازهگیریهای عددی تجمیعشده — شمارندهها، سنجهها، هیستوگرامها — برای داشبوردها و هشداردهی.
- Logs: رکوردهای رویداد ساختاریافته که میتوانند از طریق زمینه مشترک (Trace IDها، Span IDها) با Traces و Metrics همبسته شوند.
معماری دو مؤلفه اصلی دارد: SDK (تعبیهشده در برنامه شما) و Collector (یک باینری مستقل که تلهمتری را دریافت، پردازش و صادر میکند). درک جدایی بین این دو، بینش کلیدی است که بیشتر تیمها از دست میدهند.
مشخصات در مقابل SDK: چرا جدایی اهمیت دارد
OpenTelemetry یک مشخصات API جدا از پیادهسازی SDK تعریف میکند. این عمدی است. نویسندگان کتابخانه میتوانند کد خود را در برابر API ابزارگذاری کنند بدون اینکه وابستگی سختی به SDK خاصی داشته باشند. وقتی برنامه شما بدون SDK پیکربندیشده اجرا میشود، آن فراخوانیهای API به no-op تبدیل میشوند. سربار صفر.
وقتی SDK را پیکربندی میکنید، به API متصل میشود و شروع به صادرات میکند. SDK مسئول دستهبندی، منطق تلاش مجدد، نمونهبرداری و انتشار زمینه است. مشخصات قرارداد را تعریف میکند؛ SDK پیادهسازی را ارائه میدهد. این معماری دلیلی است که OpenTelemetry میتواند ادعای ابزارگذاری با سربار صفر برای استقرارهای غیرابزارگذاریشده داشته باشد — ادعایی که برای نویسندگان کتابخانه که به پایگاه کاربر گستردهای ارسال میکنند، اهمیت دارد.
پیامد عملی: کتابخانههای خود را در برابر OTel API ابزارگذاری کنید. برنامههای خود را در برابر SDK ابزارگذاری کنید. هرگز اجازه ندهید یک کتابخانه وابستگی سخت به SDK بگیرد.
ابزارگذاری خودکار در مقابل Spanهای دستی
OpenTelemetry ابزارگذاری خودکار مخصوص زبان را فراهم میکند که فریمورکها و کتابخانههای محبوب را بدون تغییر کد وصله میکند:
- Java: یک عامل جاوا (
-javaagent:opentelemetry-javaagent.jar) که Spring، Tomcat، gRPC، JDBC و دهها کتابخانه دیگر را از طریق دستکاری بایتکد در زمان راهاندازی ابزارگذاری میکند. - Python:
opentelemetry-instrument python app.py— Django، Flask، FastAPI، SQLAlchemy، کلاینتهای Redis و موارد دیگر را به صورت خودکار ابزارگذاری میکند. - Node.js: بسته
@opentelemetry/auto-instrumentations-nodeرا نیاز دارید و از طریق وصلهکردن ماژول به Express، HTTP، gRPC، MySQL، Postgres و دیگران متصل میشود.
ابزارگذاری خودکار بلافاصله دید در سطح زیرساخت را به شما میدهد. مدتزمان درخواست HTTP، تأخیر پرسوجوی پایگاه داده، فراخوانیهای API خارجی — تمام لولهکشیهای مکانیکی — را بدون دست زدن به کد برنامه مشاهده خواهید کرد.
اما ابزارگذاری خودکار نمیداند کد شما چه معنایی دارد. نمیتواند به شما بگوید که سرویس تسویه حساب به دلیل یک قانون اعتبارسنجی کد تخفیف خاص کند است. برای دید منطق کسبوکار به Spanهای دستی نیاز دارید:
- هر عملیاتی که ممکن است خراب شود یا حساس به تأخیر باشد را در یک Span سفارشی بپیچید.
- ویژگیهای معنایی اضافه کنید: ID کاربر، ID سفارش، نوع آزمایش، مقادیر پرچم ویژگی.
- استثناها را به صراحت با
span.recordException(err)وspan.setStatus({code: ERROR})ثبت کنید.
رویکرد درست: از ابزارگذاری خودکار به عنوان پایه استفاده کنید، Spanهای دستی را در هر نقطه تصمیمگیری که برای کسبوکار شما مهم است اضافه کنید. با خودکار شروع کنید، به تدریج با یادگیری سوالاتی که نمیتوانید پاسخ دهید، دستی اضافه کنید.
Collector محور معماری است
بیشتر تیمها با ارسال مستقیم تلهمتری از SDK برنامه خود به یک پشتیبان شروع میکنند. این کار میکند اما با ارزشترین ویژگی معماری OTel یعنی خط لوله Collector را از دست میدهد.
OTel Collector یک پراکسی مستقل از فروشنده است که بین برنامههای شما و پشتیبانهایتان قرار میگیرد. آن را با receiverها (OTLP، Jaeger، Prometheus، Zipkin)، processorها (نمونهبرداری، دستکاری ویژگی، پاکسازی PII) و exporterها (Datadog، Honeycomb، Tempo، CloudWatch — هر ترکیبی) پیکربندی کنید.
چرا این در عمل اهمیت دارد:
- Fan-out: همزمان Traces را برای اکتشاف به Honeycomb و برای نگهداری بلندمدت به Grafana Tempo ارسال کنید. بدون نیاز به تغییرات برنامه.
- پاکسازی PII: ویژگیهای حساس (آدرسهای ایمیل، آدرسهای IP، توکنهای جلسه) را قبل از خروج از مرز شبکهتان — قبل از رسیدن هر دادهای به یک فروشنده — حذف یا هش کنید.
- تصمیمات نمونهبرداری: نمونهبرداری مبتنی بر دم را در سطح Collector اعمال کنید، خطاها و تراکنشهای کند را نگه دارید، تراکنشهای سالم سریع را دور بریزید.
- مهاجرت پشتیبان: با تغییر یک فایل پیکربندی Collector از Datadog به Grafana سوئیچ کنید. ابزارگذاری برنامه شما untouched باقی میماند.
Collector را به عنوان sidecar در Kubernetes یا به عنوان DaemonSet مستقر کنید. برای محیطهای با ترافیک بالا، یک معماری طبقهای مستقر کنید: Collectorهای sidecar در هر pod که به Collectorهای دروازهای که نمونهبرداری دم را در کل جمعیت درخواست انجام میدهند، ارسال میکنند.
راهبردهای نمونهبرداری: مبتنی بر سر در مقابل مبتنی بر دم
ردیابی هر درخواست با وفاداری کامل گران است. در ۱۰۰۰۰ درخواست در ثانیه، ذخیره هر Trace هزینه واقعی دارد. نمونهبرداری در مقیاس اختیاری نیست — اما راهبرد نمونهبرداری تعیین میکند که واقعاً چه چیزی را میتوانید اشکالزدایی کنید.
نمونهبرداری مبتنی بر سر تصمیم نگهداشتن/انداختن را در شروع یک درخواست، قبل از ایجاد هر Span پاییندستی میگیرد. پیادهسازی آن ساده است و سربار حداقلی دارد. مشکل: نمیتوانید بر اساس نتایجی که هنوز نمیدانید نمونهبرداری کنید. ممکن است همان درخواستی را که خراب شد دور بیندازید. در نمونهبرداری سر ۱٪، به طور منظم هیچ Traceای برای جالبترین باگهای خود نخواهید داشت.
نمونهبرداری مبتنی بر دم تمام Spanهای یک Trace را بافر میکند و فقط پس از کامل شدن کل Trace تصمیم میگیرد. این به شما امکان میدهد:
- ۱۰۰٪ از Traces حاوی هر Span خطا را نگه دارید.
- ۱۰۰٪ از Traces فراتر از یک آستانه تأخیر (مثلاً P99 > ۲ ثانیه) را نگه دارید.
- درصد قابل پیکربندی از Traces سریع سالم (مثلاً ۱٪ پایه) را نگه دارید.
پردازنده tailsampling OTel Collector این را پیادهسازی میکند. سیاستها را در YAML پیکربندی کنید: سیاستهای وضعیت خطا را با سیاستهای تأخیر و یک پایه احتمالی ترکیب کنید. نتیجه یک مجموعه Trace است که به طور نامتناسبی از موارد جالبی که واقعاً میخواهید اشکالزدایی کنید تشکیل شده است.
هزینه عملیاتی: نمونهبرداری مبتنی بر دم نیاز به بافر کردن Spanهای در حال پرواز در حافظه Collector دارد. برای تصمیمگیری معنادار، به تمام Spanهای یک Trace نیاز دارید که به همان نمونه Collector برسند — معمولاً از طریق متعادلسازی بار مبتنی بر Trace ID در مقابل یک استخر Collector. این زیرساخت بیشتری برای راهاندازی است، اما بهبود قابلیت اشکالزدایی حاشیهای نیست. این تفاوت بین دیدن هر خطا و ندیدن هیچکدام است.
وضعیت فعلی سه سیگنال
سیگنالهای OpenTelemetry با نرخهای مختلف بالغ شدند:
- Traces: از سال ۲۰۲۱ GA و پایدار. بالغترین سیگنال. قراردادهای معنایی برای HTTP، gRPC، پایگاه داده، سیستمهای پیامرسانی به خوبی تثبیتشده و پایدار هستند. ابتدا از این استفاده کنید.
- Metrics: از سال ۲۰۲۲ GA و پایدار. پروتکل متریک OTLP آماده تولید است. قراردادهای معنایی متریکهای سرور HTTP و کلاینت، متریکهای زمان اجرا (JVM، Python runtime) و متریکهای سیستم را پوشش میدهند.
- Logs: از سال ۲۰۲۳ پایدار. مدل داده لاگ و پروتکل لاگ OTLP به لاگهای ساختاریافته اجازه میدهند زمینه Trace (Trace ID، Span ID) را حمل کنند و همبستگی بین لاگها و Traces را در پشتیبانهایی که از آن پشتیبانی میکنند ممکن میسازند. همبستگی Grafana Loki + Tempo امروزه بالغترین پیادهسازی است.
قراردادهای معنایی چیزی هستند که همبستگی بین سیگنالها را واقعاً کار میکند. وقتی Span HTTP و متریک HTTP شما از نام ویژگیهای یکسانی استفاده میکنند (http.request.method، http.response.status_code، server.address)، پشتیبانها میتوانند آنها را به هم بپیوندند. به قراردادهای معنایی منتشر شده پایبند باشید — نام ویژگیهای خود را برای عملیات استاندارد اختراع نکنید.
چشمانداز فروشندگان در سال ۲۰۲۶
با خنثی شدن ابزارگذاری از نظر فروشنده، انتخاب پشتیبان به مدل پرسوجو، هزینه و ترجیح عملیاتی مربوط میشود:
- Honeycomb: عقیدهمندترین و احتمالاً بهترین محصول برای اکتشاف Trace. BubbleUp برای کشف همبستگی خودکار، پشتیبانی از ستونهای با کاردینالیتی بالا و یک مدل پرسوجو ساخته شده در اطراف رویدادهای با عرض دلخواه. بهترین برای تیمهایی که میخواهند تحلیل Trace پیچیده انجام دهند و مایلند برای یک محصول مدیریتشده هزینه کنند.
- استک Grafana (LGTM): Loki (لاگها) + Grafana (داشبوردها) + Tempo (Traces) + Mimir (متریکها). کاملاً متن باز، قابل میزبانی خود، یا به صورت مدیریتشده از طریق Grafana Cloud موجود است. استک LGTM انتخاب درستی برای تیمهایی است که میخواهند زیرساخت خود را در اختیار داشته باشند و کاملاً از قفل شدن به فروشنده اجتناب کنند. همبستگیهای Trace-to-Logs و Trace-to-Metrics تمپو زمانی که همه چیز از قراردادهای معنایی OTel استفاده میکند به خوبی کار میکند.
- Datadog: پشتیبانی عالی از ورود OTel از طریق عامل Datadog (که OTLP صحبت میکند). بهترین برای تیمهایی که قبلاً روی Datadog برای APM و نظارت بر زیرساخت هستند و میخواهند ابزارگذاری OTel را استاندارد کنند در حالی که رابط کاربری و هشداردهی Datadog را حفظ کنند. هزینه با حجم داده به شدت افزایش مییابد.
- AWS CloudWatch: توزیع AWS برای OpenTelemetry (ADOT) Collectorهای OTel مدیریتشده توسط AWS و یکپارچهسازی عمیق با CloudWatch، X-Ray و Amazon Managed Grafana را فراهم میکند. انتخاب عملی برای تیمهای AWS-first که میخواهند سطح عملیاتی را به حداقل برسانند. تجسم Trace X-Ray کاربردی است اما به اندازه Honeycomb یا Tempo گویا نیست.
چه چیزی همچنان سخت است
OpenTelemetry همه چیز را حل نکرده است. در مورد آنچه همچنان ناهموار است صادق باشید:
- سیگنال پروفایلینگ: مشخصات پروفایلینگ (پروفایلینگ مداوم CPU و حافظه همبسته با Traces) در حال توسعه است اما تا اواسط ۲۰۲۶ هنوز پایدار نشده است. انتظار میرود در سال ۲۰۲۶ یا ۲۰۲۷ به GA برسد. تا آن زمان، پروفایلینگ ویژه فروشنده باقی میماند.
- همبستگی متریک کسبوکار: اتصال یک پرسوجوی پایگاه داده کند به تأثیر درآمد نیاز به پیوستن دادههای مشاهدهپذیری با دادههای رویداد کسبوکار دارد. OpenTelemetry تعریف نمیکند چگونه این کار را انجام دهد. باید ویژگیهای کسبوکار را به Spanهای خود اضافه کنید (مقدار سفارش، رتبه کاربر، مسیر تولید درآمد) و تحلیل را خودتان در پشتیبان خود بسازید.
- پیچیدگی پیکربندی Collector: یک پیکربندی Collector OTel تولیدی با نمونهبرداری دم، چندین exporter، پاکسازی PII و تبدیل ویژگی میتواند به صدها خط YAML تبدیل شود. Collector یک مدل خط لوله گسترده دارد، اما منحنی یادگیری برای پیکربندیهای پیچیده واقعی است. از OTel Collector Builder استفاده کنید و پیکربندیها را به صورت محلی با exporter
fileقبل از استقرار تست کنید.
شروع کار: ابزارگذاری یک سرویس در ۵ مرحله
برای یک سرویس Node.js (همان الگو برای Python با بستههای معادل اعمال میشود):
- مرحله ۱ — نصب بستهها:
npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-otlp-http - مرحله ۲ — ایجاد یک فایل ابزارگذاری (
tracing.js): NodeSDK را با نام سرویس خود، پلاگین ابزارگذاری خودکار و یک exporter OTLP HTTP که به endpoint Collector شما یا مستقیماً به URL ورود OTLP یک فروشنده اشاره میکند، مقداردهی اولیه کنید. - مرحله ۳ — SDK را قبل از برنامه خود شروع کنید: در نقطه ورودی خود، قبل از نیاز به هر ماژول دیگری
sdk.start()را فراخوانی کنید. برای Node.js، از--require ./tracing.jsدر دستور راهاندازی خود استفاده کنید. - مرحله ۴ — Spanهای دستی برای منطق کسبوکار اضافه کنید: تسویه حساب، پردازش پرداخت، پرسوجوهای توصیه — هر چیزی با اهمیت کسبوکار — را در Spanهای سفارشی بپیچید. ویژگیهایی برای ID سفارش، بخش کاربر 및 پرچمهای آزمایش اضافه کنید.
- مرحله ۵ — یک sidecar Collector مستقر کنید: OTel Collector را در کنار سرویس خود اجرا کنید، پیکربندیشده برای دریافت OTLP روی
localhost:4318و صادرات به پشتیبان انتخابی شما. این کار پیکربندی پشتیبان را از استقرار برنامه جدا میکند.
چارچوب تصمیمگیری عملی
در اینجا نحوه اتخاذ تصمیمات کلیدی بدون فکر بیش از حد آمده است:
- اولویت سیگنال: ابتدا Traces، سپس Metrics و سپس Logs را پیادهسازی کنید. Traces بیشترین اهرم اشکالزدایی را به ازای واحد تلاش ابزارگذاری به شما میدهد. Logs با ارزش هستند اما احتمالاً از قبل آنها را دارید — روی اتصال آنها به Traces از طریق تزریق زمینه Trace تمرکز کنید.
- انتخاب پشتیبان: اگر خود میزبانی میکنید، از استک LGTM Grafana استفاده کنید. اگر مدیریتشده با UX عالی برای تحلیل Trace میخواهید، از Honeycomb استفاده کنید. اگر قبلاً روی Datadog برای نظارت زیرساخت هستید، ابزارگذاری OTel را استاندارد کنید و Datadog را به عنوان پشتیبان نگه دارید. برای انتخاب پشتیبان زود هنگام بهینهسازی نکنید — نکته OTel این است که میتوانید نظر خود را تغییر دهید.
- Collector از روز اول: حتی اگر امروز فقط یک پشتیبان دارید، Collector را مستقر کنید. هزینه حداقلی است; انعطافپذیری زمانی که یک پشتیبان دوم اضافه میکنید یا نیاز به تغییر فروشنده دارید قابل توجه است.
- سیاست نمونهبرداری: اگر نیاز به کنترل فوری هزینهها دارید، با نمونهبرداری مبتنی بر سر در ۱۰–۲۰٪ شروع کنید. برنامهریزی کنید که پس از داشتن یک استخر Collector به نمونهبرداری مبتنی بر دم مهاجرت کنید — بهبود در دید خطا ارزش پیچیدگی عملیاتی را دارد.
- قراردادهای معنایی: آنها را اعمال کنید. یک مرحله lint یا چک CI اضافه کنید که نام ویژگیهای Span سفارشی شما را در برابر ثبت قراردادهای معنایی OTel اعتبارسنجی کند. ثبات اکنون به معنای همبستگی بین سیگنالها بعداً است، و به این معنی است که هر پشتیبان جدیدی که اتخاذ کنید دادههای شما را بدون تبدیل درک خواهد کرد.
جنگهای فروشندگان مشاهدهپذیری تمام شده است. مشکل ابزارگذاری حل شده است. آنچه باقی میماند انضباط عملیاتی استقرار درست آن، پیکربندی خط لوله برای هزینه و وفاداری و ایجاد عادتهای سازمانی در اطراف اشکالزدایی مبتنی بر Trace است. آن عادتها — رفتن اول به Trace وقتی چیزی کند است، حاشیهنویسی استقرارها به عنوان ویژگیهای Trace، نوشتن runbookهایی که به ویژگیهای Span خاص اشاره میکنند — چیزی هستند که تیمهایی را که از مشاهدهپذیری ارزش میگیرند از تیمهایی که فقط داشبورد دارند جدا میکنند.