diff --git a/src/TelemetryConsumption/Kestrel/IKestrelTelemetryConsumer.cs b/src/TelemetryConsumption/Kestrel/IKestrelTelemetryConsumer.cs index 26b99773b..62bd503ed 100644 --- a/src/TelemetryConsumption/Kestrel/IKestrelTelemetryConsumer.cs +++ b/src/TelemetryConsumption/Kestrel/IKestrelTelemetryConsumer.cs @@ -10,6 +10,22 @@ namespace Yarp.Telemetry.Consumption; /// public interface IKestrelTelemetryConsumer { + /// + /// Called at the start of a connection. + /// + /// Timestamp when the event was fired. + /// ID of the connection. + /// Local endpoint for the connection. + /// Remote endpoint for the connection. + void OnConnectionStart(DateTime timestamp, string connectionId, string localEndPoint, string remoteEndPoint) { } + + /// + /// Called at the end of a connection. + /// + /// Timestamp when the event was fired. + /// ID of the connection. + void OnConnectionStop(DateTime timestamp, string connectionId) { } + /// /// Called at the start of a request. /// diff --git a/src/TelemetryConsumption/Kestrel/KestrelEventListenerService.cs b/src/TelemetryConsumption/Kestrel/KestrelEventListenerService.cs index 2d0b5f4f7..afd086a22 100644 --- a/src/TelemetryConsumption/Kestrel/KestrelEventListenerService.cs +++ b/src/TelemetryConsumption/Kestrel/KestrelEventListenerService.cs @@ -28,6 +28,30 @@ protected override void OnEvent(IKestrelTelemetryConsumer[] consumers, EventWrit switch (eventData.EventId) { + case 1: + Debug.Assert(eventData.EventName == "ConnectionStart" && payload.Count == 3); + { + var connectionId = (string)payload[0]; + var LocalEndPoint = (string)payload[1]; + var remoteEndPoint = (string)payload[2]; + foreach (var consumer in consumers) + { + consumer.OnConnectionStart(eventData.TimeStamp, connectionId, LocalEndPoint, remoteEndPoint); + } + } + break; + + case 2: + Debug.Assert(eventData.EventName == "ConnectionStop" && payload.Count == 1); + { + var connectionId = (string)payload[0]; + foreach (var consumer in consumers) + { + consumer.OnConnectionStop(eventData.TimeStamp, connectionId); + } + } + break; + case 3: Debug.Assert(eventData.EventName == "RequestStart" && payload.Count == 5); { diff --git a/test/ReverseProxy.FunctionalTests/TelemetryConsumptionTests.cs b/test/ReverseProxy.FunctionalTests/TelemetryConsumptionTests.cs index b89b17c93..3b595b11c 100644 --- a/test/ReverseProxy.FunctionalTests/TelemetryConsumptionTests.cs +++ b/test/ReverseProxy.FunctionalTests/TelemetryConsumptionTests.cs @@ -123,6 +123,7 @@ await test.Invoke(async uri => var expected = new[] { + "OnConnectionStart-Kestrel", "OnRequestStart-Kestrel", "OnForwarderInvoke", "OnForwarderStart", @@ -144,6 +145,7 @@ await test.Invoke(async uri => "OnContentTransferred", "OnForwarderStop", "OnRequestStop-Kestrel", + "OnConnectionStop-Kestrel", }; if (!useHttpsOnDestination) @@ -283,8 +285,10 @@ public void OnRequestStart(DateTime timestamp, string scheme, string host, int p public void OnConnectStart(DateTime timestamp, string address) => AddStage(nameof(OnConnectStart), timestamp); public void OnConnectStop(DateTime timestamp) => AddStage(nameof(OnConnectStop), timestamp); public void OnConnectFailed(DateTime timestamp, SocketError error, string exceptionMessage) => AddStage(nameof(OnConnectFailed), timestamp); + public void OnConnectionStart(DateTime timestamp, string connectionId, string localEndPoint, string remoteEndPoint) => AddStage($"{nameof(OnConnectionStart)}-Kestrel", timestamp); public void OnRequestStart(DateTime timestamp, string connectionId, string requestId, string httpVersion, string path, string method) => AddStage($"{nameof(OnRequestStart)}-Kestrel", timestamp); public void OnRequestStop(DateTime timestamp, string connectionId, string requestId, string httpVersion, string path, string method) => AddStage($"{nameof(OnRequestStop)}-Kestrel", timestamp); + public void OnConnectionStop(DateTime timestamp, string connectionId) => AddStage($"{nameof(OnConnectionStop)}-Kestrel", timestamp); public void OnRedirect(DateTime timestamp, string redirectUri) => AddStage(nameof(OnRedirect), timestamp); }