Skip to content

Commit 27b00fe

Browse files
Merge branch 'master' into 10332-work
2 parents c4790a0 + c18fc3d commit 27b00fe

File tree

93 files changed

+1104
-1143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+1104
-1143
lines changed

.azure/pipelines/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ jobs:
328328
agentOs: Windows
329329
isTestingJob: true
330330
buildScript: ./eng/scripts/cibuild.cmd
331-
buildArgs: -test -BuildNative "/p:SkipIISBackwardsCompatibilityTests=true /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISForwardsCompatibilityTests=true /p:RunTemplateTests=false /p:BuildSiteExtensions=false"
331+
buildArgs: -test -BuildNative "/p:SkipIISNewHandlerTests=true /p:SkipIISTests=true /p:SkipIISExpressTests=true /p:SkipIISNewShimTests=true /p:RunTemplateTests=false /p:BuildSiteExtensions=false"
332332
beforeBuild:
333333
- powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
334334
displayName: Setup IISExpress test certificates and schema

eng/Version.Details.xml

Lines changed: 188 additions & 188 deletions
Large diffs are not rendered by default.

eng/Versions.props

Lines changed: 94 additions & 94 deletions
Large diffs are not rendered by default.

eng/Workarounds.props

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,4 @@
1212
<_ProjectExtensionsWereImported>true</_ProjectExtensionsWereImported>
1313
<WixTargetsPath>$(WixInstallPath)\wix2010.targets</WixTargetsPath>
1414
</PropertyGroup>
15-
16-
<!-- Workaround https://developercommunity.visualstudio.com/content/problem/434385/vs2019-preview-2-targetframeworkversion-or-platfor.html -->
17-
<PropertyGroup>
18-
<VCToolsVersion Condition = "'$(VCToolsVersion)' == ''" >14.16.27023</VCToolsVersion>
19-
</PropertyGroup>
2015
</Project>

eng/scripts/vs.buildtools.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
"Microsoft.VisualStudio.Component.NuGet.BuildTools",
1818
"Microsoft.VisualStudio.Component.VC.ATL",
1919
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
20-
"Microsoft.VisualStudio.Component.VC.v141.ATL",
21-
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
2220
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
2321
"Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools",
2422
"Microsoft.VisualStudio.Workload.MSBuildTools",

eng/scripts/vs.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
"Microsoft.VisualStudio.Component.Azure.Storage.Emulator",
1616
"Microsoft.VisualStudio.Component.VC.ATL",
1717
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
18-
"Microsoft.VisualStudio.Component.VC.v141.ATL",
19-
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
2018
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
2119
"Microsoft.VisualStudio.Workload.ManagedDesktop",
2220
"Microsoft.VisualStudio.Workload.NativeDesktop",

korebuild.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
"requiredWorkloads": [
1717
"Microsoft.VisualStudio.Component.VC.ATL",
1818
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
19-
"Microsoft.VisualStudio.Component.VC.v141.ATL",
20-
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
2119
"Microsoft.VisualStudio.Component.Windows10SDK.17134"
2220
]
2321
}

src/Hosting/Hosting/ref/Microsoft.AspNetCore.Hosting.netcoreapp3.0.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ public static partial class HostingEnvironmentExtensions
145145
public static void Initialize(this Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment, string contentRootPath, Microsoft.AspNetCore.Hosting.Internal.WebHostOptions options) { }
146146
public static void Initialize(this Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment, string contentRootPath, Microsoft.AspNetCore.Hosting.Internal.WebHostOptions options) { }
147147
}
148-
[System.Diagnostics.Tracing.EventSourceAttribute(Name="Microsoft-AspNetCore-Hosting")]
149148
public sealed partial class HostingEventSource : System.Diagnostics.Tracing.EventSource
150149
{
151150
internal HostingEventSource() { }
@@ -154,6 +153,7 @@ internal HostingEventSource() { }
154153
public void HostStart() { }
155154
[System.Diagnostics.Tracing.EventAttribute(2, Level=System.Diagnostics.Tracing.EventLevel.Informational)]
156155
public void HostStop() { }
156+
protected override void OnEventCommand(System.Diagnostics.Tracing.EventCommandEventArgs command) { }
157157
[System.Diagnostics.Tracing.EventAttribute(3, Level=System.Diagnostics.Tracing.EventLevel.Informational)]
158158
public void RequestStart(string method, string path) { }
159159
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Diagnostics.Tracing.EventAttribute(4, Level=System.Diagnostics.Tracing.EventLevel.Informational)]

src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,19 @@ public void RequestEnd(HttpContext httpContext, Exception exception, HostingAppl
136136
StopActivity(httpContext, activity, context.HasDiagnosticListener);
137137
}
138138

139-
if (context.EventLogEnabled && exception != null)
139+
if (context.EventLogEnabled)
140140
{
141-
// Non-inline
142-
HostingEventSource.Log.UnhandledException();
141+
if (exception != null)
142+
{
143+
// Non-inline
144+
HostingEventSource.Log.UnhandledException();
145+
}
146+
147+
// Count 500 as failed requests
148+
if (httpContext.Response.StatusCode >= 500)
149+
{
150+
HostingEventSource.Log.RequestFailed();
151+
}
143152
}
144153

145154
// Logging Scope is finshed with

src/Hosting/Hosting/src/Internal/HostingEventSource.cs

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// 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.Diagnostics.Tracing;
56
using System.Runtime.CompilerServices;
7+
using System.Threading;
68

79
namespace Microsoft.AspNetCore.Hosting.Internal
810
{
9-
[EventSource(Name = "Microsoft-AspNetCore-Hosting")]
1011
public sealed class HostingEventSource : EventSource
1112
{
1213
public static readonly HostingEventSource Log = new HostingEventSource();
1314

14-
private HostingEventSource() { }
15+
private IncrementingPollingCounter _requestsPerSecondCounter;
16+
private PollingCounter _totalRequestsCounter;
17+
private PollingCounter _failedRequestsCounter;
18+
private PollingCounter _currentRequestsCounter;
19+
20+
private long _totalRequests;
21+
private long _currentRequests;
22+
private long _failedRequests;
23+
24+
internal HostingEventSource()
25+
: this("Microsoft.AspNetCore.Hosting")
26+
{
27+
28+
}
29+
30+
// Used for testing
31+
internal HostingEventSource(string eventSourceName)
32+
: base(eventSourceName)
33+
{
34+
}
1535

1636
// NOTE
1737
// - The 'Start' and 'Stop' suffixes on the following event names have special meaning in EventSource. They
@@ -35,13 +55,16 @@ public void HostStop()
3555
[Event(3, Level = EventLevel.Informational)]
3656
public void RequestStart(string method, string path)
3757
{
58+
Interlocked.Increment(ref _totalRequests);
59+
Interlocked.Increment(ref _currentRequests);
3860
WriteEvent(3, method, path);
3961
}
4062

4163
[MethodImpl(MethodImplOptions.NoInlining)]
4264
[Event(4, Level = EventLevel.Informational)]
4365
public void RequestStop()
4466
{
67+
Interlocked.Decrement(ref _currentRequests);
4568
WriteEvent(4);
4669
}
4770

@@ -51,5 +74,40 @@ public void UnhandledException()
5174
{
5275
WriteEvent(5);
5376
}
77+
78+
internal void RequestFailed()
79+
{
80+
Interlocked.Increment(ref _failedRequests);
81+
}
82+
83+
protected override void OnEventCommand(EventCommandEventArgs command)
84+
{
85+
if (command.Command == EventCommand.Enable)
86+
{
87+
// This is the convention for initializing counters in the RuntimeEventSource (lazily on the first enable command).
88+
// They aren't disabled afterwards...
89+
90+
_requestsPerSecondCounter ??= new IncrementingPollingCounter("requests-per-second", this, () => _totalRequests)
91+
{
92+
DisplayName = "Request Rate",
93+
DisplayRateTimeScale = TimeSpan.FromSeconds(1)
94+
};
95+
96+
_totalRequestsCounter ??= new PollingCounter("total-requests", this, () => _totalRequests)
97+
{
98+
DisplayName = "Total Requests",
99+
};
100+
101+
_currentRequestsCounter ??= new PollingCounter("current-requests", this, () => _currentRequests)
102+
{
103+
DisplayName = "Current Requests"
104+
};
105+
106+
_failedRequestsCounter ??= new PollingCounter("failed-requests", this, () => _failedRequests)
107+
{
108+
DisplayName = "Failed Requests"
109+
};
110+
}
111+
}
54112
}
55113
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Text;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace System.Collections.Generic
7+
{
8+
internal static class AsyncEnumerableExtensions
9+
{
10+
public static async Task<T> FirstOrDefault<T>(this IAsyncEnumerator<T> values, Func<T, bool> filter)
11+
{
12+
while (await values.MoveNextAsync())
13+
{
14+
if (filter(values.Current))
15+
{
16+
return values.Current;
17+
}
18+
}
19+
20+
return default;
21+
}
22+
}
23+
}

src/Hosting/Hosting/test/Internal/HostingEventSourceTests.cs

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Diagnostics.Tracing;
6-
using System.Reflection;
7+
using System.Threading;
8+
using System.Threading.Channels;
9+
using System.Threading.Tasks;
710
using Microsoft.AspNetCore.Http;
811
using Microsoft.AspNetCore.Testing;
912
using Microsoft.AspNetCore.Testing.xunit;
@@ -17,16 +20,11 @@ public class HostingEventSourceTests
1720
public void MatchesNameAndGuid()
1821
{
1922
// Arrange & Act
20-
var eventSourceType = typeof(WebHost).GetTypeInfo().Assembly.GetType(
21-
"Microsoft.AspNetCore.Hosting.Internal.HostingEventSource",
22-
throwOnError: true,
23-
ignoreCase: false);
23+
var eventSource = new HostingEventSource();
2424

2525
// Assert
26-
Assert.NotNull(eventSourceType);
27-
Assert.Equal("Microsoft-AspNetCore-Hosting", EventSource.GetName(eventSourceType));
28-
Assert.Equal(Guid.Parse("9e620d2a-55d4-5ade-deb7-c26046d245a8"), EventSource.GetGuid(eventSourceType));
29-
Assert.NotEmpty(EventSource.GenerateManifest(eventSourceType, "assemblyPathToIncludeInManifest"));
26+
Assert.Equal("Microsoft.AspNetCore.Hosting", eventSource.Name);
27+
Assert.Equal(Guid.Parse("9ded64a4-414c-5251-dcf7-1e4e20c15e70"), eventSource.Guid);
3028
}
3129

3230
[Fact]
@@ -35,7 +33,7 @@ public void HostStart()
3533
// Arrange
3634
var expectedEventId = 1;
3735
var eventListener = new TestEventListener(expectedEventId);
38-
var hostingEventSource = HostingEventSource.Log;
36+
var hostingEventSource = GetHostingEventSource();
3937
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational);
4038

4139
// Act
@@ -58,7 +56,7 @@ public void HostStop()
5856
// Arrange
5957
var expectedEventId = 2;
6058
var eventListener = new TestEventListener(expectedEventId);
61-
var hostingEventSource = HostingEventSource.Log;
59+
var hostingEventSource = GetHostingEventSource();
6260
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational);
6361

6462
// Act
@@ -115,7 +113,7 @@ public void RequestStart(DefaultHttpContext httpContext, string[] expected)
115113
// Arrange
116114
var expectedEventId = 3;
117115
var eventListener = new TestEventListener(expectedEventId);
118-
var hostingEventSource = HostingEventSource.Log;
116+
var hostingEventSource = GetHostingEventSource();
119117
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational);
120118

121119
// Act
@@ -144,7 +142,7 @@ public void RequestStop()
144142
// Arrange
145143
var expectedEventId = 4;
146144
var eventListener = new TestEventListener(expectedEventId);
147-
var hostingEventSource = HostingEventSource.Log;
145+
var hostingEventSource = GetHostingEventSource();
148146
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational);
149147

150148
// Act
@@ -166,7 +164,7 @@ public void UnhandledException()
166164
// Arrange
167165
var expectedEventId = 5;
168166
var eventListener = new TestEventListener(expectedEventId);
169-
var hostingEventSource = HostingEventSource.Log;
167+
var hostingEventSource = GetHostingEventSource();
170168
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational);
171169

172170
// Act
@@ -182,16 +180,65 @@ public void UnhandledException()
182180
Assert.Empty(eventData.Payload);
183181
}
184182

185-
private static Exception GetException()
183+
[Fact]
184+
public async Task VerifyCountersFireWithCorrectValues()
186185
{
187-
try
188-
{
189-
throw new InvalidOperationException("An invalid operation has occurred");
190-
}
191-
catch (Exception ex)
192-
{
193-
return ex;
194-
}
186+
// Arrange
187+
var eventListener = new CounterListener(new[] {
188+
"requests-per-second",
189+
"total-requests",
190+
"current-requests",
191+
"failed-requests"
192+
});
193+
194+
var hostingEventSource = GetHostingEventSource();
195+
196+
using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5));
197+
198+
var rpsValues = eventListener.GetCounterValues("requests-per-second", timeoutTokenSource.Token).GetAsyncEnumerator();
199+
var totalRequestValues = eventListener.GetCounterValues("total-requests", timeoutTokenSource.Token).GetAsyncEnumerator();
200+
var currentRequestValues = eventListener.GetCounterValues("current-requests", timeoutTokenSource.Token).GetAsyncEnumerator();
201+
var failedRequestValues = eventListener.GetCounterValues("failed-requests", timeoutTokenSource.Token).GetAsyncEnumerator();
202+
203+
eventListener.EnableEvents(hostingEventSource, EventLevel.Informational, EventKeywords.None,
204+
new Dictionary<string, string>
205+
{
206+
{ "EventCounterIntervalSec", "1" }
207+
});
208+
209+
hostingEventSource.RequestStart("GET", "/");
210+
211+
Assert.Equal(1, await totalRequestValues.FirstOrDefault(v => v == 1));
212+
Assert.Equal(1, await rpsValues.FirstOrDefault(v => v == 1));
213+
Assert.Equal(1, await currentRequestValues.FirstOrDefault(v => v == 1));
214+
Assert.Equal(0, await failedRequestValues.FirstOrDefault(v => v == 0));
215+
216+
hostingEventSource.RequestStop();
217+
218+
Assert.Equal(1, await totalRequestValues.FirstOrDefault(v => v == 1));
219+
Assert.Equal(0, await rpsValues.FirstOrDefault(v => v == 0));
220+
Assert.Equal(0, await currentRequestValues.FirstOrDefault(v => v == 0));
221+
Assert.Equal(0, await failedRequestValues.FirstOrDefault(v => v == 0));
222+
223+
hostingEventSource.RequestStart("POST", "/");
224+
225+
Assert.Equal(2, await totalRequestValues.FirstOrDefault(v => v == 2));
226+
Assert.Equal(1, await rpsValues.FirstOrDefault(v => v == 1));
227+
Assert.Equal(1, await currentRequestValues.FirstOrDefault(v => v == 1));
228+
Assert.Equal(0, await failedRequestValues.FirstOrDefault(v => v == 0));
229+
230+
hostingEventSource.RequestFailed();
231+
hostingEventSource.RequestStop();
232+
233+
Assert.Equal(2, await totalRequestValues.FirstOrDefault(v => v == 2));
234+
Assert.Equal(0, await rpsValues.FirstOrDefault(v => v == 0));
235+
Assert.Equal(0, await currentRequestValues.FirstOrDefault(v => v == 0));
236+
Assert.Equal(1, await failedRequestValues.FirstOrDefault(v => v == 1));
237+
}
238+
239+
private static HostingEventSource GetHostingEventSource()
240+
{
241+
return new HostingEventSource(Guid.NewGuid().ToString());
195242
}
196243

197244
private class TestEventListener : EventListener
@@ -216,5 +263,36 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData)
216263
}
217264
}
218265
}
266+
267+
private class CounterListener : EventListener
268+
{
269+
private readonly Dictionary<string, Channel<double>> _counters = new Dictionary<string, Channel<double>>();
270+
271+
public CounterListener(string[] counterNames)
272+
{
273+
foreach (var item in counterNames)
274+
{
275+
_counters[item] = Channel.CreateUnbounded<double>();
276+
}
277+
}
278+
279+
public IAsyncEnumerable<double> GetCounterValues(string counterName, CancellationToken cancellationToken = default)
280+
{
281+
return _counters[counterName].Reader.ReadAllAsync(cancellationToken);
282+
}
283+
284+
protected override void OnEventWritten(EventWrittenEventArgs eventData)
285+
{
286+
if (eventData.EventName == "EventCounters")
287+
{
288+
var payload = (IDictionary<string, object>)eventData.Payload[0];
289+
var counter = (string)payload["Name"];
290+
payload.TryGetValue("Increment", out var increment);
291+
payload.TryGetValue("Mean", out var mean);
292+
var writer = _counters[counter].Writer;
293+
writer.TryWrite((double)(increment ?? mean));
294+
}
295+
}
296+
}
219297
}
220298
}

0 commit comments

Comments
 (0)