Added execution time duration (HealthReportEntry TotalDuration) (#493)
* Added execution time duration into HealthReportEntry and TotalDuration on HealthReport * review PR feedback from @rynowak. * added the same duration into HealthReportEntry and log when the health check throw
This commit is contained in:
parent
c29b0e6131
commit
fa961b003f
|
|
@ -73,30 +73,40 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await healthCheck.CheckHealthAsync(context, cancellationToken);
|
var result = await healthCheck.CheckHealthAsync(context, cancellationToken);
|
||||||
|
var duration = stopwatch.GetElapsedTime();
|
||||||
|
|
||||||
entry = new HealthReportEntry(
|
entry = new HealthReportEntry(
|
||||||
result.Result ? HealthStatus.Healthy : registration.FailureStatus,
|
status: result.Result ? HealthStatus.Healthy : registration.FailureStatus,
|
||||||
result.Description,
|
description: result.Description,
|
||||||
result.Exception,
|
duration: duration,
|
||||||
result.Data);
|
exception: result.Exception,
|
||||||
|
data: result.Data);
|
||||||
|
|
||||||
Log.HealthCheckEnd(_logger, registration, entry, stopwatch.GetElapsedTime());
|
Log.HealthCheckEnd(_logger, registration, entry, duration);
|
||||||
Log.HealthCheckData(_logger, registration, entry);
|
Log.HealthCheckData(_logger, registration, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow cancellation to propagate.
|
// Allow cancellation to propagate.
|
||||||
catch (Exception ex) when (ex as OperationCanceledException == null)
|
catch (Exception ex) when (ex as OperationCanceledException == null)
|
||||||
{
|
{
|
||||||
entry = new HealthReportEntry(HealthStatus.Failed, ex.Message, ex, data: null);
|
var duration = stopwatch.GetElapsedTime();
|
||||||
Log.HealthCheckError(_logger, registration, ex, stopwatch.GetElapsedTime());
|
entry = new HealthReportEntry(
|
||||||
|
status: HealthStatus.Failed,
|
||||||
|
description: ex.Message,
|
||||||
|
duration: duration,
|
||||||
|
exception: ex,
|
||||||
|
data: null);
|
||||||
|
|
||||||
|
Log.HealthCheckError(_logger, registration, ex, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
entries[registration.Name] = entry;
|
entries[registration.Name] = entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var report = new HealthReport(entries);
|
var totalElapsedTime = totalTime.GetElapsedTime();
|
||||||
Log.HealthCheckProcessingEnd(_logger, report.Status, totalTime.GetElapsedTime());
|
var report = new HealthReport(entries, totalElapsedTime);
|
||||||
|
Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime);
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
|
|
@ -14,10 +15,12 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
/// Create a new <see cref="HealthReport"/> from the specified results.
|
/// Create a new <see cref="HealthReport"/> from the specified results.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entries">A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.</param>
|
/// <param name="entries">A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.</param>
|
||||||
public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries)
|
/// <param name="totalDuration">A value indicating the time the health check service took to execute.</param>
|
||||||
|
public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries, TimeSpan totalDuration)
|
||||||
{
|
{
|
||||||
Entries = entries;
|
Entries = entries;
|
||||||
Status = CalculateAggregateStatus(entries.Values);
|
Status = CalculateAggregateStatus(entries.Values);
|
||||||
|
TotalDuration = totalDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -35,6 +38,11 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HealthStatus Status { get; }
|
public HealthStatus Status { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time the health check service took to execute.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan TotalDuration { get; }
|
||||||
|
|
||||||
private HealthStatus CalculateAggregateStatus(IEnumerable<HealthReportEntry> entries)
|
private HealthStatus CalculateAggregateStatus(IEnumerable<HealthReportEntry> entries)
|
||||||
{
|
{
|
||||||
// This is basically a Min() check, but we know the possible range, so we don't need to walk the whole list
|
// This is basically a Min() check, but we know the possible range, so we don't need to walk the whole list
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,14 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="status">A value indicating the health status of the component that was checked.</param>
|
/// <param name="status">A value indicating the health status of the component that was checked.</param>
|
||||||
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
|
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
|
||||||
|
/// <param name="duration">A value indicating the health execution duration.</param>
|
||||||
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
|
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
|
||||||
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
|
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
|
||||||
public HealthReportEntry(HealthStatus status, string description, Exception exception, IReadOnlyDictionary<string, object> data)
|
public HealthReportEntry(HealthStatus status, string description, TimeSpan duration, Exception exception, IReadOnlyDictionary<string, object> data)
|
||||||
{
|
{
|
||||||
Status = status;
|
Status = status;
|
||||||
Description = description;
|
Description = description;
|
||||||
|
Duration = duration;
|
||||||
Exception = exception;
|
Exception = exception;
|
||||||
Data = data ?? _emptyReadOnlyDictionary;
|
Data = data ?? _emptyReadOnlyDictionary;
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +41,11 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the health check execution duration.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan Duration { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an <see cref="System.Exception"/> representing the exception that was thrown when checking for status (if any).
|
/// Gets an <see cref="System.Exception"/> representing the exception that was thrown when checking for status (if any).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -17,15 +18,29 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
|
||||||
{
|
{
|
||||||
var result = new HealthReport(new Dictionary<string, HealthReportEntry>()
|
var result = new HealthReport(new Dictionary<string, HealthReportEntry>()
|
||||||
{
|
{
|
||||||
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
|
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null,TimeSpan.MinValue, null, null) },
|
||||||
{"Bar", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
|
{"Bar", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue,null, null) },
|
||||||
{"Baz", new HealthReportEntry(status, exception: null, description: null, data: null) },
|
{"Baz", new HealthReportEntry(status, exception: null, description: null,duration:TimeSpan.MinValue, data: null) },
|
||||||
{"Quick", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
|
{"Quick", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
|
||||||
{"Quack", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
|
{"Quack", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
|
||||||
{"Quock", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
|
{"Quock", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
|
||||||
});
|
}, totalDuration: TimeSpan.MinValue);
|
||||||
|
|
||||||
Assert.Equal(status, result.Status);
|
Assert.Equal(status, result.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(200)]
|
||||||
|
[InlineData(300)]
|
||||||
|
[InlineData(400)]
|
||||||
|
public void TotalDuration_MatchesTotalDurationParameter(int milliseconds)
|
||||||
|
{
|
||||||
|
var result = new HealthReport(new Dictionary<string, HealthReportEntry>()
|
||||||
|
{
|
||||||
|
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null,TimeSpan.MinValue, null, null) }
|
||||||
|
}, totalDuration: TimeSpan.FromMilliseconds(milliseconds));
|
||||||
|
|
||||||
|
Assert.Equal(TimeSpan.FromMilliseconds(milliseconds), result.TotalDuration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue