Skip to content

Commit fa961b0

Browse files
unaizorrillarynowak
authored andcommitted
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
1 parent c29b0e6 commit fa961b0

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

src/Microsoft.Extensions.Diagnostics.HealthChecks/DefaultHealthCheckService.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,30 +73,40 @@ public override async Task<HealthReport> CheckHealthAsync(
7373
try
7474
{
7575
var result = await healthCheck.CheckHealthAsync(context, cancellationToken);
76+
var duration = stopwatch.GetElapsedTime();
7677

7778
entry = new HealthReportEntry(
78-
result.Result ? HealthStatus.Healthy : registration.FailureStatus,
79-
result.Description,
80-
result.Exception,
81-
result.Data);
79+
status: result.Result ? HealthStatus.Healthy : registration.FailureStatus,
80+
description: result.Description,
81+
duration: duration,
82+
exception: result.Exception,
83+
data: result.Data);
8284

83-
Log.HealthCheckEnd(_logger, registration, entry, stopwatch.GetElapsedTime());
85+
Log.HealthCheckEnd(_logger, registration, entry, duration);
8486
Log.HealthCheckData(_logger, registration, entry);
8587
}
8688

8789
// Allow cancellation to propagate.
8890
catch (Exception ex) when (ex as OperationCanceledException == null)
8991
{
90-
entry = new HealthReportEntry(HealthStatus.Failed, ex.Message, ex, data: null);
91-
Log.HealthCheckError(_logger, registration, ex, stopwatch.GetElapsedTime());
92+
var duration = stopwatch.GetElapsedTime();
93+
entry = new HealthReportEntry(
94+
status: HealthStatus.Failed,
95+
description: ex.Message,
96+
duration: duration,
97+
exception: ex,
98+
data: null);
99+
100+
Log.HealthCheckError(_logger, registration, ex, duration);
92101
}
93102

94103
entries[registration.Name] = entry;
95104
}
96105
}
97106

98-
var report = new HealthReport(entries);
99-
Log.HealthCheckProcessingEnd(_logger, report.Status, totalTime.GetElapsedTime());
107+
var totalElapsedTime = totalTime.GetElapsedTime();
108+
var report = new HealthReport(entries, totalElapsedTime);
109+
Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime);
100110
return report;
101111
}
102112
}

src/Microsoft.Extensions.Diagnostics.HealthChecks/HealthReport.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Collections.Generic;
56

67
namespace Microsoft.Extensions.Diagnostics.HealthChecks
@@ -14,10 +15,12 @@ public sealed class HealthReport
1415
/// Create a new <see cref="HealthReport"/> from the specified results.
1516
/// </summary>
1617
/// <param name="entries">A <see cref="IReadOnlyDictionary{TKey, T}"/> containing the results from each health check.</param>
17-
public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries)
18+
/// <param name="totalDuration">A value indicating the time the health check service took to execute.</param>
19+
public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries, TimeSpan totalDuration)
1820
{
1921
Entries = entries;
2022
Status = CalculateAggregateStatus(entries.Values);
23+
TotalDuration = totalDuration;
2124
}
2225

2326
/// <summary>
@@ -35,6 +38,11 @@ public HealthReport(IReadOnlyDictionary<string, HealthReportEntry> entries)
3538
/// </summary>
3639
public HealthStatus Status { get; }
3740

41+
/// <summary>
42+
/// Gets the time the health check service took to execute.
43+
/// </summary>
44+
public TimeSpan TotalDuration { get; }
45+
3846
private HealthStatus CalculateAggregateStatus(IEnumerable<HealthReportEntry> entries)
3947
{
4048
// This is basically a Min() check, but we know the possible range, so we don't need to walk the whole list

src/Microsoft.Extensions.Diagnostics.HealthChecks/HealthReportEntry.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ public struct HealthReportEntry
1919
/// </summary>
2020
/// <param name="status">A value indicating the health status of the component that was checked.</param>
2121
/// <param name="description">A human-readable description of the status of the component that was checked.</param>
22+
/// <param name="duration">A value indicating the health execution duration.</param>
2223
/// <param name="exception">An <see cref="Exception"/> representing the exception that was thrown when checking for status (if any).</param>
2324
/// <param name="data">Additional key-value pairs describing the health of the component.</param>
24-
public HealthReportEntry(HealthStatus status, string description, Exception exception, IReadOnlyDictionary<string, object> data)
25+
public HealthReportEntry(HealthStatus status, string description, TimeSpan duration, Exception exception, IReadOnlyDictionary<string, object> data)
2526
{
2627
Status = status;
2728
Description = description;
29+
Duration = duration;
2830
Exception = exception;
2931
Data = data ?? _emptyReadOnlyDictionary;
3032
}
@@ -39,6 +41,11 @@ public HealthReportEntry(HealthStatus status, string description, Exception exce
3941
/// </summary>
4042
public string Description { get; }
4143

44+
/// <summary>
45+
/// Gets the health check execution duration.
46+
/// </summary>
47+
public TimeSpan Duration { get; }
48+
4249
/// <summary>
4350
/// Gets an <see cref="System.Exception"/> representing the exception that was thrown when checking for status (if any).
4451
/// </summary>

test/Microsoft.Extensions.Diagnostics.HealthChecks.Tests/HealthReportTest.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Collections.Generic;
56
using Xunit;
67

@@ -17,15 +18,29 @@ public void Status_MatchesWorstStatusInResults(HealthStatus status)
1718
{
1819
var result = new HealthReport(new Dictionary<string, HealthReportEntry>()
1920
{
20-
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
21-
{"Bar", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
22-
{"Baz", new HealthReportEntry(status, exception: null, description: null, data: null) },
23-
{"Quick", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
24-
{"Quack", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
25-
{"Quock", new HealthReportEntry(HealthStatus.Healthy, null, null, null) },
26-
});
21+
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null,TimeSpan.MinValue, null, null) },
22+
{"Bar", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue,null, null) },
23+
{"Baz", new HealthReportEntry(status, exception: null, description: null,duration:TimeSpan.MinValue, data: null) },
24+
{"Quick", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
25+
{"Quack", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
26+
{"Quock", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
27+
}, totalDuration: TimeSpan.MinValue);
2728

2829
Assert.Equal(status, result.Status);
2930
}
31+
32+
[Theory]
33+
[InlineData(200)]
34+
[InlineData(300)]
35+
[InlineData(400)]
36+
public void TotalDuration_MatchesTotalDurationParameter(int milliseconds)
37+
{
38+
var result = new HealthReport(new Dictionary<string, HealthReportEntry>()
39+
{
40+
{"Foo", new HealthReportEntry(HealthStatus.Healthy, null,TimeSpan.MinValue, null, null) }
41+
}, totalDuration: TimeSpan.FromMilliseconds(milliseconds));
42+
43+
Assert.Equal(TimeSpan.FromMilliseconds(milliseconds), result.TotalDuration);
44+
}
3045
}
3146
}

0 commit comments

Comments
 (0)