Skip to content
This repository has been archived by the owner on Mar 26, 2019. It is now read-only.

Commit

Permalink
Merge pull request #8 from AppMetrics/dev
Browse files Browse the repository at this point in the history
1.1.0 Release
  • Loading branch information
alhardy authored Dec 11, 2018
2 parents 19a8443 + 7450286 commit eceddf4
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 2 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[*]
end_of_line = crlf

[*.xml]
indent_style = space

[*.cs]
dotnet_sort_system_directives_first = true
1 change: 1 addition & 0 deletions HealthAzure.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2D805782-756
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{31A4DDB1-952E-4EED-96EF-29C669279A86}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.travis.yml = .travis.yml
AppMetrics.ruleset = AppMetrics.ruleset
appveyor.yml = appveyor.yml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
using System;
using System.Text;
using System.Threading.Tasks;
using App.Metrics.Health.Checks.AzureServiceBus;
using App.Metrics.Health.Logging;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Management;

// ReSharper disable CheckNamespace
namespace App.Metrics.Health
// ReSharper restore CheckNamespace
// ReSharper restore CheckNamespace
{
public static class AzureServiceBusQueueHealthCheckBuilderExtensions
{
Expand Down Expand Up @@ -67,6 +69,60 @@ public static IHealthBuilder AddAzureServiceBusQueueConnectivityCheck(
return builder.Builder;
}

public static IHealthBuilder AddAzureServiceBusQueueDeadLetterQueueCheck(
this IHealthCheckBuilder builder,
string name,
string connectionString,
string queueName,
long deadLetterWarningThreshold = 1,
long? deadLetterErrorThreshold = null)
{
if (deadLetterErrorThreshold.HasValue && (deadLetterWarningThreshold > deadLetterErrorThreshold))
{
throw new ArgumentException("Error threshold must exceed warning threshold", nameof(deadLetterErrorThreshold));
}

var managementClient = new ManagementClient(connectionString);
builder.AddCheck(
name,
ServiceBusHealthChecks.CheckDeadLetterQueueCount(Logger, queueName, name, GetQueueMessageCount, deadLetterWarningThreshold, deadLetterErrorThreshold));
return builder.Builder;

async Task<MessageCountDetails> GetQueueMessageCount()
{
var info = await managementClient.GetQueueRuntimeInfoAsync(queueName);
return info.MessageCountDetails;
}
}

public static IHealthBuilder AddAzureServiceBusQueueDeadLetterQueueCheck(
this IHealthCheckBuilder builder,
string name,
string connectionString,
string queueName,
TimeSpan cacheDuration,
long deadLetterWarningThreshold = 1,
long? deadLetterErrorThreshold = null)
{
if (deadLetterErrorThreshold.HasValue && (deadLetterWarningThreshold > deadLetterErrorThreshold))
{
throw new ArgumentException("Error threshold must exceed warning threshold", nameof(deadLetterErrorThreshold));
}

var managementClient = new ManagementClient(connectionString);
builder.AddCachedCheck(
name,
ServiceBusHealthChecks.CheckDeadLetterQueueCount(Logger, queueName, name, GetQueueMessageCount, deadLetterWarningThreshold, deadLetterErrorThreshold),
cacheDuration);
return builder.Builder;

async Task<MessageCountDetails> GetQueueMessageCount()
{
var info = await managementClient.GetQueueRuntimeInfoAsync(queueName);
return info.MessageCountDetails;
}
}

private static Func<ValueTask<HealthCheckResult>> CheckServiceBusQueueConnectivity(string name, QueueClient queueClient)
{
return async () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using System;
using System.Text;
using System.Threading.Tasks;
using App.Metrics.Health.Checks.AzureServiceBus;
using App.Metrics.Health.Logging;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Management;

// ReSharper disable CheckNamespace
namespace App.Metrics.Health
Expand Down Expand Up @@ -67,6 +69,62 @@ public static IHealthBuilder AddAzureServiceBusTopicConnectivityCheck(
return builder.Builder;
}

public static IHealthBuilder AddAzureServiceBusTopicSubscriptionDeadLetterQueueCheck(
this IHealthCheckBuilder builder,
string name,
string connectionString,
string topicName,
string subscriptionName,
long deadLetterWarningThreshold = 1,
long? deadLetterErrorThreshold = null)
{
if (deadLetterErrorThreshold.HasValue && (deadLetterWarningThreshold > deadLetterErrorThreshold))
{
throw new ArgumentException("Error threshold must exceed warning threshold", nameof(deadLetterErrorThreshold));
}

var managementClient = new ManagementClient(connectionString);
builder.AddCheck(
name,
ServiceBusHealthChecks.CheckDeadLetterQueueCount(Logger, EntityNameHelper.FormatSubscriptionPath(topicName, subscriptionName), name, GetQueueMessageCount, deadLetterWarningThreshold, deadLetterErrorThreshold));
return builder.Builder;

async Task<MessageCountDetails> GetQueueMessageCount()
{
var info = await managementClient.GetSubscriptionRuntimeInfoAsync(topicName, subscriptionName);
return info.MessageCountDetails;
}
}

public static IHealthBuilder AddAzureServiceBusTopicSubscriptionDeadLetterQueueCheck(
this IHealthCheckBuilder builder,
string name,
string connectionString,
string topicName,
string subscriptionName,
TimeSpan cacheDuration,
long deadLetterWarningThreshold = 1,
long? deadLetterErrorThreshold = null)
{
if (deadLetterErrorThreshold.HasValue && (deadLetterWarningThreshold > deadLetterErrorThreshold))
{
throw new ArgumentException("Error threshold must exceed warning threshold", nameof(deadLetterErrorThreshold));
}

var managementClient = new ManagementClient(connectionString);
builder.AddCachedCheck(
name,
ServiceBusHealthChecks.CheckDeadLetterQueueCount(Logger, EntityNameHelper.FormatSubscriptionPath(topicName, subscriptionName), name, GetQueueMessageCount, deadLetterWarningThreshold, deadLetterErrorThreshold),
cacheDuration);
return builder.Builder;

async Task<MessageCountDetails> GetQueueMessageCount()
{
var info = await managementClient.GetSubscriptionRuntimeInfoAsync(topicName, subscriptionName);
return info.MessageCountDetails;
}
}

private static Func<ValueTask<HealthCheckResult>> CheckServiceBusTopicConnectivity(string name, TopicClient topicClient)
{
return async () =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// <copyright file="ServiceBusHealthChecks.cs" company="App Metrics Contributors">
// Copyright (c) App Metrics Contributors. All rights reserved.
// </copyright>

using System;
using System.Threading.Tasks;
using App.Metrics.Health.Logging;
using Microsoft.Azure.ServiceBus.Management;

namespace App.Metrics.Health.Checks.AzureServiceBus
{
internal static class ServiceBusHealthChecks
{
internal static Func<ValueTask<HealthCheckResult>> CheckDeadLetterQueueCount(ILog logger, string entityPath, string name, Func<Task<MessageCountDetails>> getMessageCount, long deadLetterWarningThreshold, long? deadLetterErrorThreshold)
{
return async () =>
{
var deadLetteredMessages = 0L;
try
{
deadLetteredMessages = (await getMessageCount()).DeadLetterMessageCount;
}
catch (Exception ex)
{
logger.ErrorException($"{name} failed.", ex);

return HealthCheckResult.Unhealthy(ex);
}

if (deadLetterErrorThreshold.HasValue && deadLetteredMessages >= deadLetterErrorThreshold)
{
return HealthCheckResult.Unhealthy($"Unhealthy. '{entityPath}' has {deadLetteredMessages} dead letter messages.");
}
else if (deadLetteredMessages >= deadLetterWarningThreshold)
{
return HealthCheckResult.Degraded($"Degraded. '{entityPath}' has {deadLetteredMessages} dead letter messages.");
}

return HealthCheckResult.Healthy($"OK. {entityPath} has {deadLetteredMessages} dead letter messages.");
};
}
}
}
2 changes: 1 addition & 1 deletion version.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- This file may be overwritten by automation. -->
<Project>
<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionPrefix>1.1.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>

0 comments on commit eceddf4

Please sign in to comment.