Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 47efdee

Browse files
author
Nate McMaster
committed
Create KestrelEventSource
Adds an EventSource for Kestrel named 'Microsoft-AspNetCore-Server-Kestrel' with the following event and properties: ConnectionStart: - connectionId - serverAddress - localEndPoint - remoteEndPoint Resolves #1211
1 parent b2d45c3 commit 47efdee

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ runtimes/
3232
launchSettings.json
3333
BenchmarkDotNet.Artifacts/
3434
BDN.Generated/
35+
.idea/

src/Microsoft.AspNetCore.Server.Kestrel/Internal/Http/Connection.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ internal Connection()
8585
public void Start()
8686
{
8787
Log.ConnectionStart(ConnectionId);
88+
KestrelEventSource.Log.ConnectionStart(this);
8889

8990
// Start socket prior to applying the ConnectionFilter
9091
_socket.ReadStart(_allocCallback, _readCallback, this);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Diagnostics.Tracing;
5+
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
6+
7+
namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure
8+
{
9+
[EventSource(Name = "Microsoft-AspNetCore-Server-Kestrel")]
10+
public sealed class KestrelEventSource : EventSource
11+
{
12+
public static readonly KestrelEventSource Log = new KestrelEventSource();
13+
14+
private KestrelEventSource()
15+
{
16+
}
17+
18+
[NonEvent]
19+
public void ConnectionStart(Connection connection)
20+
{
21+
if (IsEnabled())
22+
{
23+
ConnectionStart(
24+
connection.ConnectionId,
25+
connection.ListenerContext.ServerAddress.ToString(),
26+
connection.RemoteEndPoint.ToString(),
27+
connection.LocalEndPoint.ToString());
28+
}
29+
}
30+
31+
[Event(1, Level = EventLevel.Informational)]
32+
private void ConnectionStart(string connectionId,
33+
string serverAddress,
34+
string remoteEndPoint,
35+
string localEndPoint)
36+
{
37+
WriteEvent(
38+
1,
39+
connectionId,
40+
serverAddress,
41+
remoteEndPoint,
42+
localEndPoint
43+
);
44+
}
45+
}
46+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics.Tracing;
7+
using System.Linq;
8+
using System.Threading.Tasks;
9+
using Microsoft.AspNetCore.Http;
10+
using Microsoft.AspNetCore.Builder;
11+
using Microsoft.AspNetCore.Hosting;
12+
using Microsoft.AspNetCore.Http.Features;
13+
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
14+
using Microsoft.AspNetCore.Testing;
15+
using Xunit;
16+
17+
namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
18+
{
19+
public class EventSourceTests
20+
{
21+
[Fact]
22+
public async Task LogsConnection()
23+
{
24+
var listener = new TestEventListener();
25+
listener.EnableEvents(KestrelEventSource.Log, EventLevel.Informational);
26+
27+
var host = new WebHostBuilder()
28+
.UseUrls("http://127.0.0.1:0")
29+
.UseKestrel()
30+
.Configure(app =>
31+
{
32+
app.Run(context =>
33+
{
34+
var id = context.Features.Get<IHttpConnectionFeature>().ConnectionId;
35+
context.Response.ContentLength = id.Length;
36+
return context.Response.WriteAsync(id);
37+
});
38+
})
39+
.Build();
40+
41+
string connectionId;
42+
using (host)
43+
{
44+
host.Start();
45+
46+
connectionId = await HttpClientSlim.GetStringAsync($"http://127.0.0.1:{host.GetPort()}/")
47+
.TimeoutAfter(TimeSpan.FromSeconds(10));
48+
}
49+
50+
// capture list here as other tests executing in parallel may log events
51+
var events = listener.EventData.ToList();
52+
#if NET451
53+
// collection may contain connection events from other tests
54+
var start = Assert.Single(listener.EventData, e => (e.Payload.FirstOrDefault() as string) == connectionId);
55+
#else
56+
var start = Assert.Single(listener.EventData, e => GetProperty(e, "connectionId") == connectionId);
57+
Assert.Equal("ConnectionStart", start.EventName);
58+
Assert.All(new[] {"serverAddress", "connectionId", "remoteEndPoint", "localEndPoint"},
59+
p => Assert.Contains(p, start.PayloadNames));
60+
Assert.Equal($"http://127.0.0.1:{host.GetPort()}", GetProperty(start, "serverAddress"));
61+
Assert.Equal(connectionId, GetProperty(start, "connectionId"));
62+
#endif
63+
Assert.Same(KestrelEventSource.Log, start.EventSource);
64+
}
65+
66+
#if !NET451
67+
private string GetProperty(EventWrittenEventArgs data, string propName)
68+
=> data.Payload[data.PayloadNames.IndexOf(propName)] as string;
69+
#endif
70+
71+
private class TestEventListener : EventListener
72+
{
73+
private List<EventWrittenEventArgs> _events = new List<EventWrittenEventArgs>();
74+
75+
public IEnumerable<EventWrittenEventArgs> EventData => _events;
76+
77+
protected override void OnEventWritten(EventWrittenEventArgs eventData)
78+
{
79+
_events.Add(eventData);
80+
}
81+
}
82+
}
83+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Diagnostics.Tracing;
6+
using System.Reflection;
7+
using Microsoft.AspNetCore.Server.Kestrel;
8+
using Xunit;
9+
10+
namespace Microsoft.AspNetCore.Server.KestrelTests
11+
{
12+
public class KestrelEventSourceTests
13+
{
14+
[Fact]
15+
public void ExistsWithCorrectId()
16+
{
17+
var esType = typeof(KestrelServer).GetTypeInfo().Assembly.GetType(
18+
"Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure.KestrelEventSource",
19+
throwOnError: true,
20+
ignoreCase: false
21+
);
22+
23+
Assert.NotNull(esType);
24+
25+
Assert.Equal("Microsoft-AspNetCore-Server-Kestrel", EventSource.GetName(esType));
26+
Assert.Equal(Guid.Parse("bdeb4676-a36e-5442-db99-4764e2326c7d"), EventSource.GetGuid(esType));
27+
Assert.NotEmpty(EventSource.GenerateManifest(esType, "assemblyPathToIncludeInManifest"));
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)