ASP.NET Core Health Check

زمانی که در حال توسعه پروژه بزرگی هستیم که ممکن است چندین API و یا سرویس را در آن استفاده کرده باشیم ، مشاهده فوری سلامت سرویس ها و API ها کار دشواری به نظر می رسد.در این مقاله قصد دارم نحوه تنظیم کردن ASP.NET Core Health Checks و نحوه استفاده از آن در پروژه هایی با چند سرویس را بیان کنم.تنظیماتبرای این منظور یک پروژه ASP.NET WEB API Core ایجاد میکنیم ، شما میتوانید از پروژه های MVC Core ، Console و یا حتی Blazor نیز استفاده کنید.dotnet new webapi -n HealthCheck dotnet new sln dotnet sln add HealthCheckدر قدم بعدی پکیج HealthCheck را روی پروژه نصب میکنیم.cd HealthCheck/ dotnet add package AspNetCore.HealthChecks.UIبعد از نصب پکیج باید Middleware آن را در پروژه رجیستر کنیم.تنظیمات اپلیکیشندر فایل Startup.cs و در متد ConfigureService این دستور را می نویسیم.services.AddHealthChecks(); و در متد Configure این endpoint را اضافه میکنیم تا وضعیت کنونی اپلیکیشن را چک کنیم app.UseEndpoints(endpoints => { endpoints.MapControllers(); // Mapping a new endpoint to see the health endpoints.MapHealthChecks(&quot/health&quot); });اما این روش زیاد سودمند نیست. پکیج health checks شامل فرمت های خروجی بسیاری می باشد. این پکیج به گونه ای است که شما حتی میتوانید خروجی شخصی سازی شده ای را داشته باشید. اما بصورت کلی اگر اپلیکیشن شما دارای چندین سرویس مختلف می باشد ، منطقی ترین گزینه استفاده از خروجی به صورت JSON می باشد.داشبورد Health Checkهمانطور که در ابتدای این مقاله ذکر کردم برای دسترسی سریع به سرویس ها نیاز به داشبوردی داریم که بتوانیم سرویس های استفاده شده در اپلیکیشن خود را در آن مانیتور کنیم. برای این منظور از همین پروژه خود به عنوان پروژه مانیتورینگ استفاده کرده تا سلامت پروژه هایی که در ادامه به آن اضافه میکنیم را مانیتور کنیم. دیاگرام زیر هدف نهایی را توضیح می دهد. پروژه اول خود را با کمک داکر به Redis متصل میکنیم و برای پروژه دوم از سرویس نمونه ای برای مشاهده سلامت سیستم استفاده خواهیم کرد.برای مشاهده از داشبورد ما نیاز به استفاده از پکیج زیر داریم:AspNetCore.HealthChecks.UI.InMemory.Storagedotnet add package AspNetCore.HealthChecks.UI.InMemory.Storageحالا متد های بالا را به صورت زیر تغییر می دهیم. services.AddHealthChecksUI() .AddInMemoryStorage(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHealthChecksUI(); }); در این بخش حالا سرویس های موردنظر را به solution خود اضافه می کنیم.dotnet new webapi -n Service1 dotnet new webapi -n Service2 dotnet sln add Service1 Service2در ادامه در فایل های Services1.csproj و Services2.csproj پکیج رفرنس های زیر را جای گذاری میکنیم<PackageReference Include=&quotAspNetCore.HealthChecks.UI&quot Version=&quot5.0.1&quot /> <PackageReference Include=&quotAspNetCore.HealthChecks.UI.Client&quot Version=&quot5.0.1&quot />در آخر در فایل appsettings.json پروژه HealthCheck ، سرویس های خود را رجیستر میکنیم . دقت داشته باشید که آدرس ها به درستی وارد شود. برای مشاهده آدرس هر پروژه به فولدر Properties و فایل launchSettings.json مراجعه کنید. همچنین توجه داشته باشید که این آدرس بستگی به اسفاده شما از IIS و یا Kestrel ممکن است تغییر کند.&quotHealthChecksUI&quot: { &quotHealthChecks&quot: [ { &quotName&quot: &quotService 1&quot, &quotUri&quot: &quothttps://localhost:5011/health&quot }, { &quotName&quot: &quotService 2&quot, &quotUri&quot: &quothttps://localhost:5021/health&quot } ], &quotEvaluationTimeInSeconds&quot: 10 },اکنون اگر شما همزمان سه پروژه را استارت کنید قادر خواهید بود که داشبورد health check را مشاهده کنید.آدرس پیشفرض داشبورد: https://localhost:<app port>/healthchecks-uiآدرس پیشفرض برای مشاهده JSON ها:https://localhost:<app port>/healthchecks-apiرجیستر کردن Health Checksبدون اضافه کردن هیچ پیش نیازی ، سه حالت گزارش را با هم بررسی می کنیم.برای کسب اطلاعات بیشتر برای حالت های مختلفی که health check پشتیبانی میکند به لینک زیر مراجعه کنید: https://github.com/xabaril/AspNetCore.Diagnostics.HealthChecks#health-checksدر ادامه چند مورد از آنها را بررسی میکنیم تا ببینم خروجی داشبورد به چه گونه می باشد.برای این منظور کد زیر را جای کد قبلی در Service1/Startup.cs جایگزین میکنیم.services.AddHealthChecks() .AddCheck(&quotFoo&quot, () => HealthCheckResult.Healthy(&quotFoo is OK!&quot), tags: new[] { &quotfoo_tag&quot }) .AddCheck(&quotBar&quot, () => HealthCheckResult.Unhealthy(&quotBar is unhealthy!&quot), tags: new[] { &quotbar_tag&quot }) .AddCheck(&quotBaz&quot, () => HealthCheckResult.Degraded(&quotBaz is degraded!&quot), tags: new[] { &quotbaz_tag&quot });سه حالت گزارشدر ادامه می خواهیم Service1 خود را به Redis متصل کنیم تا health check آنرا تست کنیم.به این منظور پکیج زیر را در پروژه Service1 خود نصب میکنیم.dotnet add package AspNetCore.HealthChecks.Redisهم چنین در فایل appsettings.json این پروژه، connectionString خود را اضافه میکنیم:&quotRedis&quot: { &quotConnectionString&quot: &quotlocalhost:5002&quot }, و در فایل Service1/Startup.csاین کد را جایگذاری کد قبل میکنیم:services.AddHealthChecks() .AddRedis(Configuration.GetSection(&quotRedis&quot)[&quotConnectionString&quot]);حالا Redis خود را به کمک داکر و دستور زیر روی پورت 5002 اجرا میکنیم:docker run --name redis-cache -p 5002:6379 -d redisداشبورد:حالا داکر کانتینر خود را متوقف میکنیم تا خطایی ایجاد کرده و آنرا در داشبورد مشاهده کنیم:اضافه کردن Health Checks دلخواه:به سراغ سرویس شماره دو رفته تا سرویس دلخواه خود را برای health check پیاده سازی کنیم.برای این منظور ما یک کلاس می سازیم که شامل متدی است که با هر بار اجرا بصورت رندوم وضعیت آن تغییر میکند.public class RemoteHealthCheck : IHealthCheck { public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken()) { var isHealthy = CheckRemoteEndpointHealth(); return Task.FromResult(isHealthy ? HealthCheckResult.Healthy(&quotRemote endpoint is healthy.&quot) : HealthCheckResult.Unhealthy(&quotRemote endpoint is unhealthy&quot)); } private bool CheckRemoteEndpointHealth() { // Just stubbing it out for demo var random = new Random().Next(1, 5); return random % 2 != 0; } }این کلاس را در Startup پروژه جای کد قبلی رجیستر میکنیم.services.AddHealthChecks() .AddCheck<RemoteHealthCheck>(nameof(RemoteHealthCheck));مشاهده میکنید که داشبورد با هر Evaluation یک وضعیت از Service2 نمایش خواهد داد. شما می توانید با تغییر پارامتر EvaluationTimeInSeconds در فایل appsettings.json زمان آپدیت داشبورد را کم کنید تا نتیجه را سریعتر مشاهده کنید.منابع:https://github.com/Xabaril/AspNetCore.Diagnostics.HealthCheckshttps://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-5.0https://dev.to/sahan/asp-net-core-health-checks-9al