示例#1
0
        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))));
        }
示例#2
0
        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))));
        }
示例#3
0
        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);
        }
示例#5
0
        // 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));
        }
示例#6
0
        public static HealthCheckBuilder AddSqlCheck(this HealthCheckBuilder builder, string name,
                                                     string connectionString)
        {
            Guard.ArgumentNotNull(nameof(builder), builder);

            return(AddSqlCheck(builder, name, connectionString, builder.DefaultCacheDuration));
        }
示例#7
0
        // 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);
        }
示例#11
0
        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));
        }
示例#12
0
        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));
        }
示例#13
0
        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));
        }
示例#14
0
        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));
        }
示例#15
0
        //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);
        }
示例#16
0
        // 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);
        }
示例#18
0
        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));
        }
示例#20
0
 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;
 }
示例#21
0
 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;
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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);
        }
示例#26
0
        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);
        }
示例#28
0
        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);
        }
示例#29
0
        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);
        }