حامد نعیمایی
حامد نعیمایی
خواندن ۸ دقیقه·۳ سال پیش

مانیتورینگ سرویس با Prometheus و Grafana - بخش 2

نحوه ارسال اطلاعات متریک ها به Prometheus

در بخش اول کلیات Prometheus را بررسی کردیم و در این بخش نحوه ارسال متریک ها بررسی خواهد شد و سپس تا حدودی با زبان PromQL آشنا میشیم.

نمونه داشبورد وضعیت سرویس ها
نمونه داشبورد وضعیت سرویس ها


ما یک سرویس با ASP.NET Core نوشتیم (شما میتونید از زبانها یا فریمورک های دیگه استفاده کنید) و از پکیج App-Metrics برای تولید متریک ها استفاده کردیم. این پکیج در زمینه جمع آوری متریک ها و ارتباط با Prometheus و InfluxDB ابزار خوبی هستش، علاوه بر این یک سری متریک در مورد مصرف منابع سرویس هم ثبت میکنه. با توجه به اینکه ساده ترین بخش کار تولید متریک ها در سرویس هستش شما میتونید از هر زبان یا تکنولوژی دیگه ای هم برای تولید متریک ها استفاده کنید و من اصلا اینجا به این مبحث نمی پردازم ولی اگر با ASP.NET Core کار کردید کد های مربوط به ارسال متریک ها به Prometheus رو ببینید. نکته دیگه هم اینکه تا جایی که میتونید ثبت متریک ها رو بصورت Fire and forget بنویسید.ما در ادامه ی مقاله بیشتر به مباحث اصلی Prometheus و Grafana می پردازم.

یک نکته ی مهم که باید بهش اشاره کنم اینه که در طراحی سیستم سعی کنید تعداد حالات Label های متریک خیلی زیاد نشه و حالت های اصلی رو نگهداری کنید. مثلا برای نگهداری HTTP Response ها حالت های مهم رو نگهداری کنید.
حالا علتش چیه؟
فرض کنید برای یک متریک 4 تا Label (Response Code, Endpoint, External Service, Client) قراره ذخیره بشه و هر کدوم از این 4 تا 3 حالت دارن.
مثلا برای Response Code ها مقادیر 500، 400 و 200 رو نگهداری میکنیم.
برای Endpoint مقادیر صفحه سرچ، صفحه لیست محصولات و صفحه ثبت سفارش رو داریم.
برای External Service ها فرضا فروشنده 1 ، فروشنده 2 و فروشنده 3 را خواهیم داشت.
برای کلاینت هم، اپلیکیشن موبایل، وب سایت و API را خواهیم داشت.
در نتیجه تعداد ماکزیمم حالتی (ترکیب Label ها) که دیتا برای این متریک ذخیره میشه 81 حالت که خوبه، ولی فرض کنید یک Label جدید اضافه میکنیم با 6 حالت ، که در نتیجه افزودن همین یک Label تعداد ماکزیمم حالات ما میشه 480 حالت که رشد زیادی خواهد داشت. در نتیجه باید روی این مسئله دقت کافی داشته باشیم.

همونطور که در پاراگرافهای قبل اشاره کردیم برای ثبت متریک ها در Prometheus از یکی از روش های Push و Pull میتونیم استفاده کنیم و اینکه هر کدوم چه مکانیزمی دارن رو اونجا توضیح دادم. روش Pull بار کمتری به سرویس ما وارد میکنه و البته ممکنه چالش هایی در خوندن و نوشتن در فایل متریک به وجود بیاد و همچنین نکته های دیگه هم داره که بحث رو طولانی میکنه و شاید در بخش های بعد بهش بپردازیم.

اگه به تصویر معماری Prometheus در بخش اول مراجعه کنید در سمت چپ تصویر میتونید نحوه ورود متریک ها به Prometheus رو ببینید. کد های نحوه ارسال متریک ها که خیلی هم ساده هستن رو اینجا میتونید ببینید

در ادامه در قالب یه مثال کار رو ادامه خواهیم داد. قبلش حتما پروژه رو از گیتهاب Clone کنید و از پوشه Prometheus دستور زیر رو اجرا کنید تا Image ها دریافت و سرویس ها بالا بیاد:

docker-compose -f &quotPrometheus\docker-compose.yml&quot up -d --build

با توجه به اینکه نیازه Image ها دانلود بشن بهتره اینکارو انجام بدید تا وقتی که میرسیم به بخش کوئری ها همه چی آماده باشه، بعد از اجرای کامل که یکم طول میکشه چندتا سرویس براتون میاد بالا:

  • سرویس های بک اند (1 و 2) که قراره متریک های شبه واقعی تولید کنه تا ما براشون نمودار و داشبورد بسازیم. دو نمونه از سرویس روی داکر Run خواهد شد.
  • سرویس Prometheus که دیگه تقریبا باهاش آشنا شدیم
  • سرویس Grafana که برای تولید داشبورد و نمودار ازش استفاده می کنیم. username: admin password: foobar
  • سرویس Alert Manager که برای ارسال هشدارها ازش استفاده میکنیم و یک هشدار ایمیل براش کانفیگ میکنیم و نحوه کانفیگ هشدار پیامکی رو هم توضیح خواهم داد.
  • سرویس Google cAdvisor یک سری متریک برای مانیتورینگ کانتینر ها تولید میکنه که داشبورد و نمودارهای آماده براش زیاد وجود داره و میشه اونها رو در گرافانا Import کرد.

کار با Prometheus و زبان PromQL

بعد از بالا اومدن سرویس ها از این آدرس وارد رابط کاربری سرویس Prometheus بشید تا با بخش های مختلف و اصلی ش آشنا بشیم:

صفحه اصلی Prometheus ، صفحه اجرای کوئری ها

صفحه اصلی اجرای کوئری در Prometheus
صفحه اصلی اجرای کوئری در Prometheus

در این صفحه میتونیم کوئری های مورد نظرمونو بنویسیم و نتیجه اون رو بصورت گراف( Graph Tab) یا ساده (Table Tab) مشاهده کنیم، زمانیکه شما اسم یک متریک رو وارد میکنید تمامی مقادیر اون در لحظه جاری (یا زمانی که مدنظرتون هست) برای شما نمایش داده میشه.

صفحه Target، مشاهده وضعیت Target ها

صفحه Target ها در Prometheus
صفحه Target ها در Prometheus

در این صفحه Up و Down بودن وضعیت سرویس هایی که Prometheus ازشون دیتا میگیره قابل مشاهده هستش و اگر سرویسی Down باشه علتش اینجا مشخص میشه. نحوه کانفیگ ساده ی یک Target هم طبق این فرمت در فایل Prometheus.yml هستش:

https://gist.github.com/naeemaei/8c28c171acc3bbdaae8561fe3b827436


صفحات مربوط به سیستم ارسال هشدار :

  1. بخش Alert ها : اینجا لیست هشدار های کانفیگ شده به همراه وضعیت آن ها قابل مشاهده است، هر Alert چند وضعیت دارد که در بخش مربوط به Alerting باهاشون کامل آشنا خواهیم شد.
  2. بخش Rule ها : در این قسمت هم شروطی که برای ارسال هشدار کانفیگ شده است و به همراه وضعیت آن ها قابل مشاهده است.

زبان PromQL

زبان کوئری نویسی در Prometheus اسمش PromQL هستش، فکر میکنم قبلا برای دیتابیس های دیگه کوئری نوشته باشید ولی کوئری نویسی در دیتابیس های Time Serie کمی متفاوت خواهد بود چون ساختار و مدل ذخیره سازی دیتا در این دیتابیس ها متفاوته و اینجا همه چی روی محور زمان میچرخه و چون زمان همیشه در حال حرکت هستش اجرای یک کوئری ثابت در هر لحظه ممکنه نتیجه ی متفاوتی بده. در ادامه با نحوه کار و برخی کوئری ها و توابع مهمش آشنا خواهیم شد. شما هم میتونید هر کدوم از کوئری ها رو در پنل اجرای کوئری بنویسید و نتیجه رو ببینید.

توجه: من روی برخی متون لینک گذاشتم که با کلیک بر روی لینک ها میتونید مستقیم کوئری های هر بخش رو ببینید. البته در صورتی که سرویس هایی که گفتیم روی داکر ران شده باشه که اگه نشده برای ران شدن سرویس کار زیادی نیاز نیست انجام بدید و فقط کافیه فایل Docker-compose رو با توضیحاتی که ابتدای همین بخش دادم Up کنید :


خروجی کوئری ها: خروجی کوئری ها چند حالت دارد:
1- خروجی یک مقدار است مثلا یک عدد: برای نمونه وقتی از توابع Aggregation مانند Sum یا Increase استفاده میکنیم خروجی میتواند یک عدد باشد. مثال آن هم مجموع تعداد درخواست ها یا مجموع زمان پاسخ درخواست ها می باشد. برای مشاهده اجرای کوئری کلیک کنید

خروجی تک مقداری
خروجی تک مقداری

2- خروجی یک بردار یا مجموعه است: نمونه ای از این خروجی را در زمانهایی که مقدار کلی متریک ها را با لیبل های مختلف یا بر اساس یک گروه بندی خاص میگیریم میتوانیم مشاهده کنیم، مثلا: تعداد درخواست بر اساس نوع پاسخ سرور (تعداد موفق، تعداد ناموفق، تعداد دارای خطا و...). برای مشاهده اجرای کوئری کلیک کنید

خروجی چند مقداری
خروجی چند مقداری




کوئری ساده: ما میتونیم اسم متریک رو مستقیم در پنل کوئری یا در گرافانا وارد کنیم که در این صورت بر اساس نوع متریک خروجی به ما نمایش داده خواهد شد. ما در این پروژه دو متریک اصلی داشتیم (application_request_duration و application_request_counter)
ما میتونیم با وارد کردن اسم متریک در باکس کوئری ببینیم آخرین مقدار application_request_duration چقدر بوده و یا تعداد رخداد application_request_counter چند تا بوده. البته این مدل کوئری خیلی به کار نمیاد و خروجی که میده مفید نخواهد بود ولی لازم بود که بدونیم.

application_request_counter


اعمال شرط روی کوئری: برای اعمال شرط روی کوئری باید بعد از اسم متریک توی یک {} شروط رو بنویسیم:

application_request_counter{instance=&quotex1-web-api:80&quot,service=&quotShopping1&quot}

شرطهایی مثل not یا in هم خیلی شبیه همین شرط هاست، این یک مثال از not هستش

application_request_counter{instance!=&quotex1-web-api:80&quot,service!=&quotShopping1&quot}

یا برای اعمال شرط چندتایی (in, not in)روی یک Label این مثال رو ببینید:

application_request_counter{endpoint=~&quotproduct-detail-page|register-order&quot,responsecode!~&quot400|401|403&quot}

برای اینکه بیشتر با این نوع کوئری ها آشنا بشید میتونید اینجا رو ببینید.

اعمال بازه زمانی روی کوئری: گاهی اوقات نیاز داریم که نتیجه یک کوئری را در n دقیقه (ثانیه یا ...) اخیر بدست بیاوریم، برای مثال مجموع تعداد درخواست ها در 5 دقیقه اخیر، یا میانگین زمان پاسخ در 30 ثانیه اخیر:

ceil(sum(increase(application_request_counter[5m])))


اعمال Offset زمانی روی کوئری: گاهی هم نیاز داریم نتیجه یک کوئری را در زمان های غیر از زمان جاری ببینیم، مثلا تعداد درخواست ها روز گذشته و همین ساعت و دقیقه تا 5 دقیقه قبلش را بدست بیاوریم.

ceil(sum(increase(application_request_counter[5m] offset 1d)))

این مدل کوئری ها در زمانهایی که نیاز داریم وضعیت سیستم را نسبت به زمان مشابه در روز گذشته، هفته گذشته، ساعت گذشته یا ماه گذشته را مقایسه کنیم خیلی بدرد بخور خواهد بود، برای مثال کوئری زیر نشون میده که درصد افزایش یا کاهش تعداد درخواست در 5 دقیقه اخیر نسبت که زمان مشابه در یک ساعت اخیر چقدر بوده (مثلا مقایسه تعداد درخواست از ساعت 11:02 الی 11:07 با ساعت 10:02 الی 10:07) و ما میتونیم بجای یک ساعت از یک روز استفاده کنیم و همیشه وضعیت سیستم رو نسبت به زمان مشابه روز گذشته، هفته ی گذشته و حتی ماه گذشته و بیشتر هم بسنجیم.

( ceil(sum(increase(application_request_counter[5m]))) - ceil(sum(increase(application_request_counter[5m] offset 1h))) ) / ceil(sum(increase(application_request_counter[5m]))) * 100


اعمال گروه بندی روی کوئری: گاهی لازمه مجموع یا میانگین یک متریک رو بر اساس یک Label خاص بسنجیم، برای نمونه تعداد درخواست ها در کلاینت های مختلف (تعداد درخواست های Mobile Application و وبسایت بصورت جداگانه)

ceil(sum by (application)(increase(application_request_counter[5m])))


برخی توابع به درد بخور مثل sum، increase، rate، grouping و... داریم که در بخش بعدی که داشبورد طراحی میکنیم با برخی از اینها سر و کار خواهیم داشت و باهاشون آشنا خواهیم شد.

در قسمت های بعد موارد زیر را بررسی میکنیم:

1. طراحی داشبورد در گرافانا برای متریک ها و دیتای تولید شده

2. کار با AlertManager و ارسال هشدار از طریق ایمیل و اس ام اس


monitoringprometheusgrafanaasp net coreمانیتورینگ
مهندس نرم افزار در آسان پرداخت
شاید از این پست‌ها خوشتان بیاید