Skip to content

Commit 58ea539

Browse files
mathewcmhoeger
authored andcommitted
Make MetricEvent.Completed more robust (#6973) (#6974)
1 parent c674120 commit 58ea539

File tree

4 files changed

+63
-17
lines changed

4 files changed

+63
-17
lines changed

src/WebJobs.Script.WebHost/Diagnostics/MetricsEventManager.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,8 @@ public void EndEvent(object eventHandle)
7979
SystemMetricEvent evt = eventHandle as SystemMetricEvent;
8080
if (evt != null)
8181
{
82-
long latencyMS = 0;
83-
evt.StopWatch.Stop();
84-
if (evt.StopWatch != null)
85-
{
86-
evt.Duration = evt.StopWatch.Elapsed;
87-
latencyMS = evt.StopWatch.ElapsedMilliseconds;
88-
}
89-
else
90-
{
91-
evt.Duration = DateTime.UtcNow - evt.Timestamp;
92-
latencyMS = (long)evt.Duration.TotalMilliseconds;
93-
}
82+
evt.Complete();
83+
long latencyMS = (long)evt.Duration.TotalMilliseconds;
9484

9585
// event aggregation is based on this key
9686
// for each unique key, there will be only 1
@@ -165,6 +155,7 @@ internal void FunctionStarted(FunctionStartedEvent startedEvent)
165155

166156
internal void FunctionCompleted(FunctionStartedEvent completedEvent)
167157
{
158+
completedEvent.Complete();
168159
_functionActivityTracker.FunctionCompleted(completedEvent);
169160
}
170161

src/WebJobs.Script.WebHost/Diagnostics/WebHostMetricsLogger.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ public void EndEvent(MetricEvent metricEvent)
5454
{
5555
if (metricEvent is FunctionStartedEvent completedEvent)
5656
{
57-
completedEvent.Duration = DateTime.UtcNow - completedEvent.Timestamp;
5857
_metricsEventManager.FunctionCompleted(completedEvent);
5958
}
6059
else

src/WebJobs.Script/Diagnostics/MetricEvent.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,29 @@ public abstract class MetricEvent
1414

1515
public Stopwatch StopWatch { get; set; }
1616

17-
public TimeSpan Duration { get; set; }
17+
public TimeSpan Duration { get; private set; }
1818

1919
public string Data { get; set; }
2020

2121
public string RuntimeSiteName { get; set; }
2222

2323
public string SlotName { get; set; }
2424

25-
public bool Completed
25+
public bool Completed { get; private set; }
26+
27+
public void Complete()
2628
{
27-
get
29+
if (StopWatch != null)
30+
{
31+
StopWatch.Stop();
32+
Duration = StopWatch.Elapsed;
33+
}
34+
else
2835
{
29-
return Duration != default(TimeSpan);
36+
Duration = DateTime.UtcNow - Timestamp;
3037
}
38+
39+
Completed = true;
3140
}
3241
}
3342
}

test/WebJobs.Script.Tests.Integration/Diagnostics/MetricsEventManagerTests.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics;
67
using System.Linq;
78
using System.Reflection;
89
using System.Text;
@@ -205,6 +206,52 @@ public void LogEvent_Function_AggregatesIntoExistingEvent()
205206
Assert.Null(metricEvent.FunctionName);
206207
}
207208

209+
[Fact]
210+
public async Task Complete_TimestampSet_CompletesEvent()
211+
{
212+
var metadata = new FunctionMetadata();
213+
var evt = new FunctionStartedEvent(Guid.NewGuid(), metadata);
214+
evt.Timestamp = DateTime.UtcNow;
215+
Assert.False(evt.Completed);
216+
217+
// complete immediately (potentially within system timer resolution)
218+
evt.Complete();
219+
Assert.True(evt.Completed);
220+
221+
evt = new FunctionStartedEvent(Guid.NewGuid(), metadata);
222+
evt.Timestamp = DateTime.UtcNow;
223+
Assert.False(evt.Completed);
224+
225+
// complete after a delay
226+
await Task.Delay(250);
227+
evt.Complete();
228+
Assert.True(evt.Completed);
229+
}
230+
231+
[Fact]
232+
public async Task Complete_StopwatchSet_CompletesEvent()
233+
{
234+
var metadata = new FunctionMetadata();
235+
var evt = new FunctionStartedEvent(Guid.NewGuid(), metadata);
236+
evt.StopWatch = Stopwatch.StartNew();
237+
Assert.False(evt.Completed);
238+
239+
// complete immediately (potentially within system timer resolution)
240+
evt.Complete();
241+
Assert.True(evt.Completed);
242+
Assert.False(evt.StopWatch.IsRunning);
243+
244+
evt = new FunctionStartedEvent(Guid.NewGuid(), metadata);
245+
evt.StopWatch = Stopwatch.StartNew();
246+
Assert.False(evt.Completed);
247+
248+
// complete after a delay
249+
await Task.Delay(250);
250+
evt.Complete();
251+
Assert.True(evt.Completed);
252+
Assert.False(evt.StopWatch.IsRunning);
253+
}
254+
208255
[Fact]
209256
public void BeginEvent_ReturnsEventHandle()
210257
{

0 commit comments

Comments
 (0)