Skip to content

Commit

Permalink
Working on more health checks functions (#681)
Browse files Browse the repository at this point in the history
* Working on more health checks functions

* Additionals changes

* Changes are changed

* Changes are made

* additional white space fixes

* more white space fixes

* white space fixes

* whitespace fixes

* one more

* add checks to ensure we only run the test when we have the setting set

* use other strings for queries

* Address concerns from Gilian

* address concern Gilian

* Did some code cleanup.

---------

Co-authored-by: Mike van Mourik <[email protected]>
Co-authored-by: Gilian <[email protected]>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent 4644748 commit 545eca0
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using GeeksCoreLibrary.Core.Middlewares;
using GeeksCoreLibrary.Core.Models;
using GeeksCoreLibrary.Core.Services;
using GeeksCoreLibrary.Modules.HealthChecks.Services;
using GeeksCoreLibrary.Modules.ItemFiles.Interfaces;
using GeeksCoreLibrary.Modules.ItemFiles.Services;
using GeeksCoreLibrary.Modules.Languages.Interfaces;
Expand Down Expand Up @@ -49,7 +50,6 @@
using GeeksCoreLibrary.Modules.Barcodes.Services;
using GeeksCoreLibrary.Modules.Databases.Interfaces;
using GeeksCoreLibrary.Modules.Databases.Services;
using GeeksCoreLibrary.Modules.HealthChecks.Services;
using GeeksCoreLibrary.Modules.ItemFiles.Middlewares;
using JetBrains.Annotations;
using Microsoft.Extensions.Diagnostics.HealthChecks;
Expand Down Expand Up @@ -137,10 +137,8 @@ public static IApplicationBuilder UseGclMiddleware(this IApplicationBuilder buil
});

builder.HandleStartupFunctions();

return builder;
}

/// <summary>
/// Handle and execute some functions that are needed to be done during startup of the application.
/// Don't call this method if you're already calling UseGclMiddleware, because this is called inside that.
Expand All @@ -157,7 +155,6 @@ public static IApplicationBuilder HandleStartupFunctions(this IApplicationBuilde
{
using var scope = builder.ApplicationServices.CreateScope();
var databaseHelpersService = scope.ServiceProvider.GetRequiredService<IDatabaseHelpersService>();

var gclSettings = scope.ServiceProvider.GetRequiredService<IOptions<GclSettings>>();
var tablesToUpdate = new List<string>
{
Expand Down Expand Up @@ -232,7 +229,8 @@ public static IServiceCollection AddGclServices(this IServiceCollection services
{
services.AddHealthChecks()
.AddMySql(gclSettings.ConnectionString, name: "MySqlRead", tags: new []{"Database"})
.AddCheck<WtsHealthService>("WTS Health Check", HealthStatus.Degraded, new []{"WTS", "Wiser Task Scheduler"});
.AddCheck<WtsHealthService>("WTS Health Check", HealthStatus.Degraded, new []{"WTS", "Wiser Task Scheduler"})
.AddCheck<DatabaseHealthService>("Database Health Check", tags: new[]{ "Database" });
if (!String.IsNullOrWhiteSpace(gclSettings.ConnectionStringForWriting))
{
services.AddHealthChecks().AddMySql(gclSettings.ConnectionString, name: "MySqlWrite", tags: new []{"Database"});
Expand Down Expand Up @@ -291,7 +289,10 @@ public static IServiceCollection AddGclServices(this IServiceCollection services
// Enable session.
if (isWeb)
{
services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); });
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
});
}

// Manual additions.
Expand Down
6 changes: 4 additions & 2 deletions GeeksCoreLibrary/Core/Helpers/HttpContextHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public static class HttpContextHelpers
$"/{Components.OrderProcess.Models.Constants.PaymentInPage}",
$"/{Components.OrderProcess.Models.Constants.PaymentOutPage}",
"/health",
"/health/wts"
"/health/wts",
"/health/database"
};

/// <summary>
Expand Down Expand Up @@ -372,7 +373,8 @@ public static UriBuilder GetOriginalRequestUriBuilder(HttpContext httpContext)

var result = new UriBuilder
{
Host = httpContext.Request.Host.Host,
// When the host is empty, go back to localhost.
Host = String.IsNullOrWhiteSpace(httpContext.Request.Host.Host) ? "localhost" : httpContext.Request.Host.Host,
Scheme = httpContext.Request.Scheme,
Port = httpContext.Request.Host.Port ?? (httpContext.Request.IsHttps ? 443 : 80)
};
Expand Down
5 changes: 5 additions & 0 deletions GeeksCoreLibrary/Core/Models/GclSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ public GclSettings()
/// The SMTP settings for sending emails.
/// </summary>
public SmtpSettings SmtpSettings { get; set; }

/// <summary>
/// The Healthcheck settings for the Database check.
/// </summary>
public HealthChecksSettings HealthChecks { get; set; }

/// <summary>
/// The license key for the library EvoPdf.
Expand Down
7 changes: 7 additions & 0 deletions GeeksCoreLibrary/Core/Models/HealthChecksSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace GeeksCoreLibrary.Core.Models;

public class HealthChecksSettings
{
public int MaximumDatabaseConnections { get; set; }
public int MaximumConnectionsInTime { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using GeeksCoreLibrary.Core.Models;
using GeeksCoreLibrary.Modules.Databases.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;

namespace GeeksCoreLibrary.Modules.HealthChecks.Services;
public class DatabaseHealthService : IHealthCheck
{
private readonly IDatabaseConnection databaseConnection;
private readonly HealthChecksSettings healthChecksSettings;

public DatabaseHealthService(IDatabaseConnection databaseConnection, IOptions<HealthChecksSettings> healthChecksSettings)
{
this.databaseConnection = databaseConnection;
this.healthChecksSettings = healthChecksSettings.Value;
}

/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
CancellationToken cancellationToken = new CancellationToken())
{
// A new query to check the max active connections from the DatabaseHealthCheck.
var query = "SELECT COUNT(*) AS active_connections FROM information_schema.PROCESSLIST;";
var datatable = await databaseConnection.GetAsync(query);

var healthCheckConnections = healthChecksSettings.MaximumDatabaseConnections;
var healthCheckConnectionsTime = healthChecksSettings.MaximumConnectionsInTime;

// If no value is set, we are skipping this test.
if (healthCheckConnections > 0)
{
// Retrieve the count of active connections.
var activeConnections = Convert.ToInt32(datatable.Rows[0]["active_connections"]);

// Check if the number of active connections exceeds the limit.
if (activeConnections > healthCheckConnections)
{
return HealthCheckResult.Unhealthy($"Too many database connections. There are currently {activeConnections} connections active, which is more than the threshold {healthCheckConnections} that is set in the appSettings.");
}
}

// If no value is set, we are skipping this test.
if (healthCheckConnectionsTime > 0)
{
// Query to check the max open connections in time from the DatabaseHealthCheck.
query = "SELECT ID, USER, HOST, TIME AS connection_time_in_sec FROM information_schema.PROCESSLIST WHERE USER != 'repluser' AND HOST != 'localhost' ORDER BY connection_time_in_sec DESC";
datatable = await databaseConnection.GetAsync(query);
if (datatable.Rows.Count == 0)
{
// If the query returns no results, it means that there are no open connections.
// But we can connect to the database, otherwise we would get an exception. So this means the database is healthy.
return HealthCheckResult.Healthy();
}

// Retrieve the count of open connections in time.
var connectionTime = Convert.ToInt32(datatable.Rows[0]["connection_time_in_sec"]);

// Check if the time from open connections exceeds the limit.
if (connectionTime > healthCheckConnectionsTime)
{
return HealthCheckResult.Unhealthy($"There is at least one opened connection that has been open for more than {healthCheckConnectionsTime} seconds. There most likely is an issue with this connection.");
}
}

return HealthCheckResult.Healthy();
}
}

0 comments on commit 545eca0

Please sign in to comment.