Sometimes, during healthchecking, we get error about connection to database. It happens 2-3 times in 2500 healthcheck requests. Could you help us to find possible reason of this error?
Log:
TASWebclient;2022-10-30 23:34:50,139;ERROR;Microsoft.Extensions.Diagnostics.HealthChecks.DefaultHealthCheckService;[.NET ThreadPool Worker];(null);(null);Health check Database Connection with user check with status Unhealthy completed after 4.4974ms with message 'WebClientDbContext could not connect to database.';System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Http.DefaultHttpRequest.get_Scheme()
at Microsoft.AspNetCore.Http.Extensions.UriHelper.GetDisplayUrl(HttpRequest request)
at Abp.EntityHistory.EntityHistoryHelper.CreateEntityChangeSet(ICollection1 entityEntries) at Abp.Zero.EntityFrameworkCore.AbpZeroCommonDbContext
3.SaveChangesAsync(CancellationToken cancellationToken)
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesAsync()
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.CompleteUowAsync()
at Abp.Domain.Uow.UnitOfWorkBase.CompleteAsync()
at TAS.WebClient.HealthChecks.WebClientDbContextUsersHealthCheck.CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken) in D:\BuildAgents\DevOpsAgent39_Work\4\s\TASWebclient\aspnet-core\src\TAS.WebClient.Application\HealthChecks\WebClientDbContextUsersHealthCheck.cs:line 58
;
WebClientDbContextUsersHealthCheck.cs :
using System;
using System.Threading;
using System.Threading.Tasks;
using Abp.Domain.Uow;
using Abp.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using TAS.WebClient.EntityFrameworkCore;
namespace TAS.WebClient.HealthChecks
{
public class WebClientDbContextUsersHealthCheck : IHealthCheck
{
private readonly IDbContextProvider<WebClientDbContext> _dbContextProvider;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public WebClientDbContextUsersHealthCheck(
IDbContextProvider<WebClientDbContext> dbContextProvider,
IUnitOfWorkManager unitOfWorkManager
)
{
_dbContextProvider = dbContextProvider;
_unitOfWorkManager = unitOfWorkManager;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken())
{
try
{
using (var uow = _unitOfWorkManager.Begin())
{
// Switching to host is necessary for single tenant mode.
using (_unitOfWorkManager.Current.SetTenantId(null))
{
var dbContext = await _dbContextProvider.GetDbContextAsync();
if (!await dbContext.Database.CanConnectAsync(cancellationToken))
{
return HealthCheckResult.Unhealthy(
"WebClientDbContext could not connect to database"
);
}
var user = await dbContext.Users.AnyAsync(cancellationToken);
await uow.CompleteAsync();
if (user)
{
return HealthCheckResult.Healthy("WebClientDbContext connected to database and checked whether user added");
}
return HealthCheckResult.Unhealthy("WebClientDbContext connected to database but there is no user.");
}
}
}
catch (Exception e)
{
return HealthCheckResult.Unhealthy("WebClientDbContext could not connect to database.", e);
}
}
}
}
AbpZeroHealthCheck.cs:
using Microsoft.Extensions.DependencyInjection;
using TAS.WebClient.HealthChecks;
namespace TAS.WebClient.Web.HealthCheck
{
public static class AbpZeroHealthCheck
{
public static IHealthChecksBuilder AddAbpZeroHealthCheck(this IServiceCollection services)
{
var builder = services.AddHealthChecks();
builder.AddCheck<WebClientDbContextHealthCheck>("Database Connection");
builder.AddCheck<WebClientDbContextUsersHealthCheck>("Database Connection with user check");
builder.AddCheck<CacheHealthCheck>("Cache");
builder.AddCheck<ExternalApiHealthCheck>("ExternalApi Connection");
builder.AddCheck<DocumentApiHealthCheck>("DocumentApi Connection");
// add your custom health checks here
// builder.AddCheck<MyCustomHealthCheck>("my health check");
return builder;
}
}
}
Startup.cs:
if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
{
services.AddAbpZeroHealthCheck();
var healthCheckUISection = _appConfiguration.GetSection("HealthChecks")?.GetSection("HealthChecksUI");
if (bool.Parse(healthCheckUISection["HealthChecksUIEnabled"]))
{
services.Configure<HealthChecksUISettings>(settings =>
{
healthCheckUISection.Bind(settings, c => c.BindNonPublicProperties = true);
});
services.AddHealthChecksUI()
.AddInMemoryStorage();
}
}
...
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<AbpCommonHub>("/signalr");
endpoints.MapHub<ChatHub>("/signalr-chat");
endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
}
app.ApplicationServices.GetRequiredService<IAbpAspNetCoreConfiguration>().EndpointConfiguration.ConfigureAllEndpoints(endpoints);
});
if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
{
if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksUI:HealthChecksUIEnabled"]))
{
app.UseHealthChecksUI();
}
}
appsettings.json:
"HealthChecks": {
"HealthChecksEnabled": true,
"HealthChecksUI": {
"HealthChecksUIEnabled": true,
"HealthChecks": [
{
"Name": "TAS.WebClient.Web.Host",
"Uri": "https://localhost:44301/health"
}
],
"EvaluationTimeOnSeconds": 10,
"MinimumSecondsBetweenFailureNotifications": 60
}
},
3 Answer(s)
-
0
Hi,
Could you place [DisableAuditing] attribute to CheckHealthAsync method and try again ?
-
0
Thanks Asp.Net Zero Support
We have now tried adding that attribute, see below. No change experienced, still same issue.
[DisableAuditing] public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken()) {
…
Any other suggestions or ideas?
-
0
Hi @henriksorensen
Currently, I don't have any suggestion. Could you create an issue on https://github.com/aspnetzero/aspnet-zero-core/issues ? We will investigate this issue deeper.