public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable <string> urlItems, string groupName, CheckStatus partialSuccessStatus, Func <HttpResponseMessage, Task <IHealthCheckResult> > checkFunc) { Guard.ArgumentNotNull(nameof(checkFunc), checkFunc); return(AddUrlChecks(builder, urlItems, groupName, partialSuccessStatus, response => new ValueTask <IHealthCheckResult>(checkFunc(response)))); }
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func <HttpResponseMessage, Task <IHealthCheckResult> > checkFunc) { Guard.ArgumentNotNull(nameof(checkFunc), checkFunc); return(AddUrlCheck(builder, url, response => new ValueTask <IHealthCheckResult>(checkFunc(response)))); }
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func <IHealthCheckResult> check, TimeSpan cacheDuration) { Guard.ArgumentNotNull(nameof(builder), builder); builder.AddCheck(name, HealthCheck.FromCheck(check, cacheDuration)); return(builder); }
public static HealthCheckBuilder AddAzureTableStorageCheck(HealthCheckBuilder builder, CloudStorageAccount storageAccount, string tableName = null, TimeSpan?cacheDuration = null) { builder.AddCheck($"AzureTableStorageCheck {storageAccount.TableStorageUri} {tableName}", async() => { bool result; try { var tableClient = storageAccount.CreateCloudTableClient(); var properties = await tableClient.GetServicePropertiesAsync().ConfigureAwait(false); if (String.IsNullOrWhiteSpace(tableName)) { var table = tableClient.GetTableReference(tableName); result = await table.ExistsAsync(); } result = true; } catch (Exception) { result = false; } return(result ? HealthCheckResult.Healthy($"AzureTableStorage {storageAccount.BlobStorageUri} is available") : HealthCheckResult.Unhealthy($"AzureTableStorage {storageAccount.BlobStorageUri} is unavailable")); }, cacheDuration ?? builder.DefaultCacheDuration); return(builder); }
// Type versions of AddCheck public static HealthCheckBuilder AddCheck <TCheck>(this HealthCheckBuilder builder, string name) where TCheck : class, IHealthCheck { Guard.ArgumentNotNull(nameof(builder), builder); return(builder.AddCheck <TCheck>(name, builder.DefaultCacheDuration)); }
public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name, string connectionString) { Guard.ArgumentNotNull(nameof(builder), builder); return(AddSqlCheck(builder, name, connectionString, builder.DefaultCacheDuration)); }
// Func returning ValueTask<IHealthCheckResult> public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func <HttpResponseMessage, ValueTask <IHealthCheckResult> > checkFunc) { Guard.ArgumentNotNull(nameof(builder), builder); return(AddUrlCheck(builder, url, checkFunc, builder.DefaultCacheDuration)); }
public static HealthCheckBuilder AddMongoDbCheck(this HealthCheckBuilder builder, string name, string connectionString, string databaseName, TimeSpan cacheDuration) { builder.AddCheck($"MongoDbCheck({name})", async() => { try { var client = new MongoClient(connectionString); IMongoDatabase database = client.GetDatabase(databaseName); BsonDocument result = await database.RunCommandAsync((Command <BsonDocument>) "{ping:1}").ConfigureAwait(false); ServerState serverState = client.Cluster.Description.Servers.FirstOrDefault()?.State ?? ServerState.Disconnected; if (serverState == ServerState.Disconnected) { return(HealthCheckResult.Unhealthy($"MongoDbCheck({name}): Unhealthy")); } else { return(HealthCheckResult.Healthy($"MongoDbCheck({name}): Healthy")); } } catch (Exception ex) { return(HealthCheckResult.Unhealthy($"MongoDbCheck({name}): Exception during check: {ex.GetType().FullName}")); } }, cacheDuration); return(builder); }
public static HealthCheckBuilder AddAzureBlobStorageCheck(this HealthCheckBuilder builder, string accountName, string accountKey, string containerName = null) { var credentials = new StorageCredentials(accountName, accountKey); var storageAccount = new CloudStorageAccount(credentials, true); return(AddAzureBlobStorageCheck(builder, storageAccount, containerName)); }
public static HealthCheckBuilder AddRedisCheck(this HealthCheckBuilder builder, string name, TimeSpan cacheDuration, string connectionString) { builder.AddCheck($"RedisCheck({name})", () => { try { ConnectionMultiplexer connect = ConnectionMultiplexer.Connect(new ConfigurationOptions() { }); var response = connect.GetStatus(); if (response != null && response.Any()) { return(HealthCheckResult.Healthy($"RedisCheck({name}): Healthy")); } return(HealthCheckResult.Unhealthy($"RedisCheck({name}): Unhealthy")); } catch (Exception ex) { return(HealthCheckResult.Unhealthy($"RedisCheck({name}): Exception during check: {ex.GetType().FullName}")); } }, cacheDuration); return(builder); }
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func <CancellationToken, ValueTask <IHealthCheckResult> > check, TimeSpan cacheDuration) { Guard.ArgumentNotNull(nameof(builder), builder); return(builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check), cacheDuration)); }
public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string name, Func <CancellationToken, IHealthCheckResult> check) { Guard.ArgumentNotNull(nameof(builder), builder); return(builder.AddCheck(name, HealthCheck.FromCheck(check), builder.DefaultCacheDuration)); }
public static HealthCheckBuilder AddMaxValueCheck <T>(this HealthCheckBuilder builder, string name, T maxValue, Func <T> currentValueFunc) where T : IComparable <T> { Guard.ArgumentNotNull(nameof(builder), builder); return(AddMaxValueCheck(builder, name, maxValue, currentValueFunc, builder.DefaultCacheDuration)); }
public static HealthCheckBuilder AddValueTaskCheck(this HealthCheckBuilder builder, string name, Func <ValueTask <IHealthCheckResult> > check) { Guard.ArgumentNotNull(nameof(builder), builder); return(builder.AddCheck(name, HealthCheck.FromValueTaskCheck(check), builder.DefaultCacheDuration)); }
//TODO: Move this into a seperate project. Avoid DB dependencies in the main lib. //TODO: It is probably better if this is more generic, not SQL specific. public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string connectionString) { builder.AddCheck($"SQL Check:", async() => { try { //TODO: There is probably a much better way to do this. using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandType = CommandType.Text; command.CommandText = "SELECT 1"; var result = (int)await command.ExecuteScalarAsync(); if (result == 1) { return(HealthCheckResult.Healthy($"AddSqlCheck: {connectionString}")); } return(HealthCheckResult.Unhealthy($"AddSqlCheck: {connectionString}")); } } } catch { return(HealthCheckResult.Unhealthy($"AddSqlCheck: {connectionString}")); } }); return(builder); }
// IHealthCheck versions of AddCheck public static HealthCheckBuilder AddCheck(this HealthCheckBuilder builder, string checkName, IHealthCheck check) { Guard.ArgumentNotNull(nameof(builder), builder); return(builder.AddCheck(checkName, check, builder.DefaultCacheDuration)); }
public static HealthCheckBuilder AddAzureFileStorageCheck(HealthCheckBuilder builder, CloudStorageAccount storageAccount, string shareName = null) { builder.AddCheck($"AzureFileStorageCheck {storageAccount.FileStorageUri} {shareName}", async() => { bool result; try { var fileClient = storageAccount.CreateCloudFileClient(); var properties = await fileClient.GetServicePropertiesAsync(); if (!String.IsNullOrWhiteSpace(shareName)) { var share = fileClient.GetShareReference(shareName); result = await share.ExistsAsync(); } result = true; } catch (Exception) { result = false; } return(result ? HealthCheckResult.Healthy($"AzureFileStorage {storageAccount.BlobStorageUri} is available") : HealthCheckResult.Unhealthy($"AzureFileStorage {storageAccount.BlobStorageUri} is unavailable")); }); return(builder); }
public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name, string connectionString, TimeSpan cacheDuration) { builder.AddCheck($"SqlCheck({name})", async() => { try { //TODO: There is probably a much better way to do this. using (var connection = new SqlConnection(connectionString)) { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandType = CommandType.Text; command.CommandText = "SELECT 1"; var result = (int)await command.ExecuteScalarAsync().ConfigureAwait(false); if (result == 1) { return(HealthCheckResult.Healthy($"SqlCheck({name}): Healthy")); } return(HealthCheckResult.Unhealthy($"SqlCheck({name}): Unhealthy")); } } } catch (Exception ex) { return(HealthCheckResult.Unhealthy( $"SqlCheck({name}): Exception during check: {ex.GetType().FullName}")); } }, cacheDuration); return(builder); }
public static HealthCheckBuilder AddAzureFileStorageCheck(this HealthCheckBuilder builder, string accountName, string accountKey, string shareName = null, TimeSpan?cacheDuration = null) { var credentials = new StorageCredentials(accountName, accountKey); var storageAccount = new CloudStorageAccount(credentials, true); return(AddAzureFileStorageCheck(builder, storageAccount, shareName, cacheDuration)); }
public HealthCheckService(HealthCheckBuilder builder, IServiceProvider serviceProvider, IServiceScopeFactory serviceScopeFactory) { _builder = builder; _groups = GetGroups().Where(group => group.GroupName != string.Empty).ToList(); _root = GetGroup(string.Empty); _serviceProvider = serviceProvider; _serviceScopeFactory = serviceScopeFactory; }
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func <HttpResponseMessage, HealthCheckResult> checkFunc) { builder.AddCheck($"UrlCheck ({url})", async() => { var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("cache-control", "no-cache"); var response = await httpClient.GetAsync(url); return(checkFunc(response)); }); return(builder); }
/// <summary> /// This constructor should only be used when creating a grouped health check builder. /// </summary> public HealthCheckBuilder(HealthCheckBuilder rootBuilder, HealthCheckGroup currentGroup) { Guard.ArgumentNotNull(nameof(rootBuilder), rootBuilder); Guard.ArgumentNotNull(nameof(currentGroup), currentGroup); _checksByName = rootBuilder._checksByName; _currentGroup = currentGroup; _groups = rootBuilder._groups; DefaultCacheDuration = rootBuilder.DefaultCacheDuration; }
public static void Build(Action <HealthCheckBuilder> buildout, IServiceProvider serviceProvider, IServiceScopeFactory serviceScopeFactory) { Guard.ArgumentNotNull(nameof(buildout), buildout); Guard.OperationValid(_service == null, "You may only call Build once."); var builder = new HealthCheckBuilder(); buildout(builder); _service = new HealthCheckService(builder, serviceProvider ?? new NoOpServiceProvider(), serviceScopeFactory); }
public static HealthCheckBuilder AddUrlCheck(this HealthCheckBuilder builder, string url, Func <HttpResponseMessage, ValueTask <IHealthCheckResult> > checkFunc) { Guard.ArgumentNotNull(nameof(builder), builder); Guard.ArgumentNotNullOrEmpty(nameof(url), url); Guard.ArgumentNotNull(nameof(checkFunc), checkFunc); var urlCheck = new UrlChecker(checkFunc, url); builder.AddCheck($"UrlCheck({url})", () => urlCheck.CheckAsync()); return(builder); }
public static HealthCheckBuilder AddVirtualMemorySizeCheck(this HealthCheckBuilder builder, long maxSize) { builder.AddCheck($"VirtualMemorySize ({maxSize})", () => { if (Process.GetCurrentProcess().VirtualMemorySize64 <= maxSize) { return(HealthCheckResult.Healthy($"AddVirtualMemorySizeCheck, maxSize: {maxSize}")); } return(HealthCheckResult.Unhealthy($"AddVirtualMemorySizeCheck, maxSize: {maxSize}")); }); return(builder); }
public static HealthCheckBuilder AddWorkingSetCheck(this HealthCheckBuilder builder, long maxSize) { builder.AddCheck($"WorkingSet64 ({maxSize})", () => { if (Process.GetCurrentProcess().WorkingSet64 <= maxSize) { return(HealthCheckResult.Healthy($"AddWorkingSetCheck, maxSize: {maxSize}")); } return(HealthCheckResult.Unhealthy($"AddWorkingSetCheck, maxSize: {maxSize}")); }); return(builder); }
public static IServiceCollection AddHealthChecks(this IServiceCollection services, Action <HealthCheckBuilder> checks) { Guard.OperationValid(!services.Any(descriptor => descriptor.ServiceType == HealthCheckServiceInterface), "AddHealthChecks may only be called once."); var builder = new HealthCheckBuilder(); services.AddSingleton <IHealthCheckService, HealthCheckService>(serviceProvider => { var serviceScopeFactory = serviceProvider.GetService <IServiceScopeFactory>(); return(new HealthCheckService(builder, serviceProvider, serviceScopeFactory)); }); checks(builder); return(services); }
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable <string> urlItems, string groupName, CheckStatus partialSuccessStatus, Func <HttpResponseMessage, ValueTask <IHealthCheckResult> > checkFunc) { var urls = urlItems?.ToArray(); Guard.ArgumentNotNull(nameof(builder), builder); Guard.ArgumentNotNullOrEmpty(nameof(urlItems), urls); Guard.ArgumentNotNullOrWhitespace(nameof(groupName), groupName); var urlChecker = new UrlChecker(checkFunc, urls) { PartiallyHealthyStatus = partialSuccessStatus }; builder.AddCheck($"UrlChecks({groupName})", () => urlChecker.CheckAsync()); return(builder); }
public static HealthCheckBuilder AddUrlChecks(this HealthCheckBuilder builder, IEnumerable <string> urlItems, string group) { var urls = urlItems.ToList(); builder.AddCheck($"UrlChecks ({group})", async() => { var successfulChecks = 0; var description = new StringBuilder(); var httpClient = new HttpClient(); foreach (var url in urlItems) { try { httpClient.DefaultRequestHeaders.Add("cache-control", "no-cache"); var response = await httpClient.GetAsync(url); if (response.StatusCode == HttpStatusCode.OK) { successfulChecks++; description.Append($"UrlCheck SUCCESS ({url}) "); } else { description.Append($"UrlCheck FAILED ({url}) "); } } catch { description.Append($"UrlCheck FAILED ({url}) "); } } if (successfulChecks == urls.Count) { return(HealthCheckResult.Healthy(description.ToString())); } else if (successfulChecks > 0) { return(HealthCheckResult.Warning(description.ToString())); } return(HealthCheckResult.Unhealthy(description.ToString())); }); return(builder); }
/// <summary> /// Creates a new health check group, to which you can add one or more health /// checks. /// </summary> public HealthCheckBuilder AddHealthCheckGroup(string groupName, Action <HealthCheckBuilder> groupChecks, CheckStatus partialSuccessStatus) { Guard.ArgumentNotNullOrEmpty(nameof(groupName), groupName); Guard.ArgumentNotNull(nameof(groupChecks), groupChecks); Guard.ArgumentValid(partialSuccessStatus != CheckStatus.Unknown, nameof(partialSuccessStatus), "Check status 'Unknown' is not valid for partial success."); Guard.ArgumentValid(!_groups.ContainsKey(groupName), nameof(groupName), $"A group with name '{groupName}' has already been registered."); Guard.OperationValid(_currentGroup.GroupName == string.Empty, "Nested groups are not supported by HealthCheckBuilder."); var group = new HealthCheckGroup(groupName, partialSuccessStatus); _groups.Add(groupName, group); var innerBuilder = new HealthCheckBuilder(this, group); groupChecks(innerBuilder); return(this); }