Skip to content

Commit e401ab0

Browse files
authored
Merge pull request #396 from prom-client-net/observe-duration-exception-handler
Add exception handler overloads to ObserveDuration
2 parents e3cf3f6 + cc4dd2d commit e401ab0

File tree

2 files changed

+523
-0
lines changed

2 files changed

+523
-0
lines changed

src/Prometheus.Client.Abstractions/ValueObserverExtensions.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ public static void ObserveDuration(this IValueObserver observer, Action method)
2020
}
2121
}
2222

23+
public static void ObserveDuration(this IValueObserver observer, Action method, Action<Exception> onObserveException)
24+
{
25+
var ts = Stopwatch.GetTimestamp();
26+
try
27+
{
28+
method();
29+
}
30+
finally
31+
{
32+
ObserveHandlingException(observer, GetDuration(ts), onObserveException);
33+
}
34+
}
35+
2336
public static T ObserveDuration<T>(this IValueObserver observer, Func<T> method)
2437
{
2538
var ts = Stopwatch.GetTimestamp();
@@ -33,6 +46,19 @@ public static T ObserveDuration<T>(this IValueObserver observer, Func<T> method)
3346
}
3447
}
3548

49+
public static T ObserveDuration<T>(this IValueObserver observer, Func<T> method, Action<Exception> onObserveException)
50+
{
51+
var ts = Stopwatch.GetTimestamp();
52+
try
53+
{
54+
return method();
55+
}
56+
finally
57+
{
58+
ObserveHandlingException(observer, GetDuration(ts), onObserveException);
59+
}
60+
}
61+
3662
public static async Task ObserveDurationAsync(this IValueObserver observer, Func<Task> method)
3763
{
3864
var ts = Stopwatch.GetTimestamp();
@@ -46,6 +72,19 @@ public static async Task ObserveDurationAsync(this IValueObserver observer, Func
4672
}
4773
}
4874

75+
public static async Task ObserveDurationAsync(this IValueObserver observer, Func<Task> method, Action<Exception> onObserveException)
76+
{
77+
var ts = Stopwatch.GetTimestamp();
78+
try
79+
{
80+
await method().ConfigureAwait(false);
81+
}
82+
finally
83+
{
84+
ObserveHandlingException(observer, GetDuration(ts), onObserveException);
85+
}
86+
}
87+
4988
public static async Task<T> ObserveDurationAsync<T>(this IValueObserver observer, Func<Task<T>> method)
5089
{
5190
var ts = Stopwatch.GetTimestamp();
@@ -59,6 +98,19 @@ public static async Task<T> ObserveDurationAsync<T>(this IValueObserver observer
5998
}
6099
}
61100

101+
public static async Task<T> ObserveDurationAsync<T>(this IValueObserver observer, Func<Task<T>> method, Action<Exception> onObserveException)
102+
{
103+
var ts = Stopwatch.GetTimestamp();
104+
try
105+
{
106+
return await method().ConfigureAwait(false);
107+
}
108+
finally
109+
{
110+
ObserveHandlingException(observer, GetDuration(ts), onObserveException);
111+
}
112+
}
113+
62114
[MethodImpl(MethodImplOptions.AggressiveInlining)]
63115
private static double GetDuration(long startTs)
64116
{
@@ -67,4 +119,29 @@ private static double GetDuration(long startTs)
67119

68120
return elapsed / frequency;
69121
}
122+
123+
private static void ObserveHandlingException(IValueObserver observer, double duration, Action<Exception> onObserveException)
124+
{
125+
if (onObserveException is null)
126+
{
127+
observer.Observe(duration);
128+
return;
129+
}
130+
131+
try
132+
{
133+
observer.Observe(duration);
134+
}
135+
catch (Exception ex)
136+
{
137+
try
138+
{
139+
onObserveException(ex);
140+
}
141+
catch
142+
{
143+
// Swallow exceptions from the handler so ObserveDuration* does not throw due to handler failures
144+
}
145+
}
146+
}
70147
}

0 commit comments

Comments
 (0)