mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 09:12:57 -07:00
Added health checks
This commit is contained in:
parent
483f021e29
commit
99d9ccc7dd
9 changed files with 150 additions and 14 deletions
16
src/Ombi.HealthChecks/HealthCheckExtensions.cs
Normal file
16
src/Ombi.HealthChecks/HealthCheckExtensions.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ombi.HealthChecks
|
||||||
|
{
|
||||||
|
public static class HealthCheckExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
public static IHealthChecksBuilder AddOmbiHealthChecks(this IHealthChecksBuilder builder)
|
||||||
|
{
|
||||||
|
builder.AddCheck<PlexHealthCheck>("Plex", tags: new string[] { "MediaServer" });
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/Ombi.HealthChecks/Ombi.HealthChecks.csproj
Normal file
15
src/Ombi.HealthChecks/Ombi.HealthChecks.csproj
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
50
src/Ombi.HealthChecks/PlexHealthCheck.cs
Normal file
50
src/Ombi.HealthChecks/PlexHealthCheck.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
using Ombi.Api.Plex;
|
||||||
|
using Ombi.Api.Plex.Models.Status;
|
||||||
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Core.Settings.Models.External;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ombi.HealthChecks
|
||||||
|
{
|
||||||
|
public class PlexHealthCheck : IHealthCheck
|
||||||
|
{
|
||||||
|
private readonly IPlexApi _plexApi;
|
||||||
|
private readonly ISettingsService<PlexSettings> _settings;
|
||||||
|
public PlexHealthCheck(IPlexApi plexApi, ISettingsService<PlexSettings> settings)
|
||||||
|
{
|
||||||
|
_plexApi = plexApi;
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
public async Task<HealthCheckResult> CheckHealthAsync(
|
||||||
|
HealthCheckContext context,
|
||||||
|
CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
var settings = await _settings.GetSettingsAsync();
|
||||||
|
if (settings == null)
|
||||||
|
{
|
||||||
|
return HealthCheckResult.Healthy("Plex is not confiured.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var taskResult = new List<Task<PlexStatus>>();
|
||||||
|
foreach (var server in settings.Servers)
|
||||||
|
{
|
||||||
|
taskResult.Add(_plexApi.GetStatus(server.PlexAuthToken, server.FullUri));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await Task.WhenAll(taskResult.ToArray());
|
||||||
|
return HealthCheckResult.Healthy();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return HealthCheckResult.Unhealthy("Could not communicate with Plex", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -110,7 +110,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.GroupMe", "Ombi.Ap
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MusicBrainz", "Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj", "{C5C1769B-4197-4410-A160-0EEF39EDDC98}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MusicBrainz", "Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj", "{C5C1769B-4197-4410-A160-0EEF39EDDC98}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Twilio", "Ombi.Api.Twilio\Ombi.Api.Twilio.csproj", "{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Twilio", "Ombi.Api.Twilio\Ombi.Api.Twilio.csproj", "{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.HealthChecks", "Ombi.HealthChecks\Ombi.HealthChecks.csproj", "{59D19538-0496-44EE-936E-EBBC22CF7B27}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -298,6 +300,10 @@ Global
|
||||||
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{59D19538-0496-44EE-936E-EBBC22CF7B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{59D19538-0496-44EE-936E-EBBC22CF7B27}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{59D19538-0496-44EE-936E-EBBC22CF7B27}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{59D19538-0496-44EE-936E-EBBC22CF7B27}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -341,6 +347,7 @@ Global
|
||||||
{9266403C-B04D-4C0F-AC39-82F12C781949} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{9266403C-B04D-4C0F-AC39-82F12C781949} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
{C5C1769B-4197-4410-A160-0EEF39EDDC98} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{C5C1769B-4197-4410-A160-0EEF39EDDC98} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
|
{59D19538-0496-44EE-936E-EBBC22CF7B27} = {410F36CF-9C60-428A-B191-6FD90610991A}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
|
@ -17,7 +18,7 @@ namespace Ombi.Extensions
|
||||||
public const string SqliteDatabase = "Sqlite";
|
public const string SqliteDatabase = "Sqlite";
|
||||||
public const string MySqlDatabase = "MySQL";
|
public const string MySqlDatabase = "MySQL";
|
||||||
|
|
||||||
public static void ConfigureDatabases(this IServiceCollection services)
|
public static void ConfigureDatabases(this IServiceCollection services, IHealthChecksBuilder hcBuilder)
|
||||||
{
|
{
|
||||||
var configuration = GetDatabaseConfiguration();
|
var configuration = GetDatabaseConfiguration();
|
||||||
|
|
||||||
|
@ -26,9 +27,11 @@ namespace Ombi.Extensions
|
||||||
{
|
{
|
||||||
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<OmbiContext, OmbiSqliteContext>(x => ConfigureSqlite(x, configuration.OmbiDatabase));
|
services.AddDbContext<OmbiContext, OmbiSqliteContext>(x => ConfigureSqlite(x, configuration.OmbiDatabase));
|
||||||
|
AddSqliteHealthCheck(hcBuilder, "Ombi Database", configuration.OmbiDatabase);
|
||||||
break;
|
break;
|
||||||
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<OmbiContext, OmbiMySqlContext>(x => ConfigureMySql(x, configuration.OmbiDatabase));
|
services.AddDbContext<OmbiContext, OmbiMySqlContext>(x => ConfigureMySql(x, configuration.OmbiDatabase));
|
||||||
|
AddMySqlHealthCheck(hcBuilder, "Ombi Database", configuration.OmbiDatabase);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +39,11 @@ namespace Ombi.Extensions
|
||||||
{
|
{
|
||||||
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<ExternalContext, ExternalSqliteContext>(x => ConfigureSqlite(x, configuration.ExternalDatabase));
|
services.AddDbContext<ExternalContext, ExternalSqliteContext>(x => ConfigureSqlite(x, configuration.ExternalDatabase));
|
||||||
|
AddSqliteHealthCheck(hcBuilder, "External Database", configuration.ExternalDatabase);
|
||||||
break;
|
break;
|
||||||
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<ExternalContext, ExternalMySqlContext>(x => ConfigureMySql(x, configuration.ExternalDatabase));
|
services.AddDbContext<ExternalContext, ExternalMySqlContext>(x => ConfigureMySql(x, configuration.ExternalDatabase));
|
||||||
|
AddMySqlHealthCheck(hcBuilder, "External Database", configuration.ExternalDatabase);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +51,11 @@ namespace Ombi.Extensions
|
||||||
{
|
{
|
||||||
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(SqliteDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<SettingsContext, SettingsSqliteContext>(x => ConfigureSqlite(x, configuration.SettingsDatabase));
|
services.AddDbContext<SettingsContext, SettingsSqliteContext>(x => ConfigureSqlite(x, configuration.SettingsDatabase));
|
||||||
|
AddSqliteHealthCheck(hcBuilder, "Settings Database", configuration.SettingsDatabase);
|
||||||
break;
|
break;
|
||||||
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
case var type when type.Equals(MySqlDatabase, StringComparison.InvariantCultureIgnoreCase):
|
||||||
services.AddDbContext<SettingsContext, SettingsMySqlContext>(x => ConfigureMySql(x, configuration.SettingsDatabase));
|
services.AddDbContext<SettingsContext, SettingsMySqlContext>(x => ConfigureMySql(x, configuration.SettingsDatabase));
|
||||||
|
AddMySqlHealthCheck(hcBuilder, "Settings Database", configuration.SettingsDatabase);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,11 +85,36 @@ namespace Ombi.Extensions
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void AddSqliteHealthCheck(IHealthChecksBuilder builder, string dbName, PerDatabaseConfiguration config)
|
||||||
|
{
|
||||||
|
if (builder != null)
|
||||||
|
{
|
||||||
|
builder.AddSqlite(
|
||||||
|
sqliteConnectionString: config.ConnectionString,
|
||||||
|
name: dbName,
|
||||||
|
failureStatus: HealthStatus.Unhealthy,
|
||||||
|
tags: new string[] { "db" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddMySqlHealthCheck(IHealthChecksBuilder builder, string dbName, PerDatabaseConfiguration config)
|
||||||
|
{
|
||||||
|
if (builder != null)
|
||||||
|
{
|
||||||
|
builder.AddMySql(
|
||||||
|
connectionString: config.ConnectionString,
|
||||||
|
name: dbName,
|
||||||
|
failureStatus: HealthStatus.Unhealthy,
|
||||||
|
tags: new string[] { "db" }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ConfigureSqlite(DbContextOptionsBuilder options, PerDatabaseConfiguration config)
|
public static void ConfigureSqlite(DbContextOptionsBuilder options, PerDatabaseConfiguration config)
|
||||||
{
|
{
|
||||||
SQLitePCL.Batteries.Init();
|
SQLitePCL.Batteries.Init();
|
||||||
SQLitePCL.raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD);
|
SQLitePCL.raw.sqlite3_config(raw.SQLITE_CONFIG_MULTITHREAD);
|
||||||
|
|
||||||
options.UseSqlite(config.ConnectionString);
|
options.UseSqlite(config.ConnectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,10 @@
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="3.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="3.0.0" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="3.0.9" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="3.0.2" />
|
||||||
<PackageReference Include="AutoMapper" Version="6.1.1" />
|
<PackageReference Include="AutoMapper" Version="6.1.1" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.6.0" />
|
<PackageReference Include="CommandLineParser" Version="2.6.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.1" />
|
||||||
|
@ -85,6 +89,7 @@
|
||||||
<ProjectReference Include="..\Ombi.Api.Twilio\Ombi.Api.Twilio.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Twilio\Ombi.Api.Twilio.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.HealthChecks\Ombi.HealthChecks.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Hubs\Ombi.Hubs.csproj" />
|
<ProjectReference Include="..\Ombi.Hubs\Ombi.Hubs.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Mapping\Ombi.Mapping.csproj" />
|
<ProjectReference Include="..\Ombi.Mapping\Ombi.Mapping.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />
|
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace Ombi
|
||||||
//CheckAndMigrate();
|
//CheckAndMigrate();
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
services.ConfigureDatabases();
|
services.ConfigureDatabases(null);
|
||||||
using (var provider = services.BuildServiceProvider())
|
using (var provider = services.BuildServiceProvider())
|
||||||
{
|
{
|
||||||
var settingsDb = provider.GetRequiredService<SettingsContext>();
|
var settingsDb = provider.GetRequiredService<SettingsContext>();
|
||||||
|
|
|
@ -28,6 +28,9 @@ using Microsoft.AspNetCore.StaticFiles.Infrastructure;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using ILogger = Serilog.ILogger;
|
using ILogger = Serilog.ILogger;
|
||||||
|
using HealthChecks.UI.Client;
|
||||||
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||||
|
using Ombi.HealthChecks;
|
||||||
|
|
||||||
namespace Ombi
|
namespace Ombi
|
||||||
{
|
{
|
||||||
|
@ -73,8 +76,13 @@ namespace Ombi
|
||||||
options.User.AllowedUserNameCharacters = string.Empty;
|
options.User.AllowedUserNameCharacters = string.Empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
services.ConfigureDatabases();
|
var hcBuilder = services.AddHealthChecks();
|
||||||
services.AddHealthChecks();
|
hcBuilder.AddOmbiHealthChecks();
|
||||||
|
services.ConfigureDatabases(hcBuilder);
|
||||||
|
services.AddHealthChecksUI(setupSettings: setup =>
|
||||||
|
{
|
||||||
|
setup.AddHealthCheckEndpoint("Ombi", "http://localhost:3577/healthz");
|
||||||
|
});
|
||||||
services.AddMemoryCache();
|
services.AddMemoryCache();
|
||||||
|
|
||||||
services.AddJwtAuthentication(Configuration);
|
services.AddJwtAuthentication(Configuration);
|
||||||
|
@ -205,17 +213,20 @@ namespace Ombi
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
endpoints.MapHub<NotificationHub>("/hubs/notification");
|
endpoints.MapHub<NotificationHub>("/hubs/notification");
|
||||||
endpoints.MapHealthChecks("/health");
|
endpoints.MapHealthChecks("/health");
|
||||||
|
endpoints.MapHealthChecks("/healthz", new HealthCheckOptions
|
||||||
|
{
|
||||||
|
Predicate = _ => true,
|
||||||
|
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
||||||
|
});
|
||||||
|
endpoints.MapHealthChecksUI();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.UseSpa(spa =>
|
app.UseSpa(spa =>
|
||||||
{
|
{
|
||||||
#if DEBUG
|
//#if DEBUG
|
||||||
//if (env.IsDevelopment())
|
// spa.Options.SourcePath = "ClientApp";
|
||||||
//{
|
// spa.UseProxyToSpaDevelopmentServer("http://localhost:3578");
|
||||||
spa.Options.SourcePath = "ClientApp";
|
//#endif
|
||||||
spa.UseProxyToSpaDevelopmentServer("http://localhost:3578");
|
|
||||||
//}
|
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
BIN
src/Ombi/healthchecksdb
Normal file
BIN
src/Ombi/healthchecksdb
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue