Added some kestrel event counters (#21649)
* Added some kestrel event counters - Connection queue length - This is the amount of connections accepted and queued in the thread pool. - Connection count - The number of connections - Total connections - The total number of connections ever connected. - Connection Rate - Connections per second * Added TLS counters - Current TLS handshakes - Total TLS handshakes - Failed TLS handshakes - TLS handshake per second * Added HTTP/2 queue length counter * Improve the event information - Add TLS version to handshake events - Add HTTP version to request queue events - Renamed HTTP/2 request queue length to http request queue Contributes to #4769
This commit is contained in:
parent
dfb126da17
commit
5a0c097ad4
|
|
@ -61,6 +61,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
_transportConnectionManager.AddConnection(id, kestrelConnection);
|
_transportConnectionManager.AddConnection(id, kestrelConnection);
|
||||||
|
|
||||||
Log.ConnectionAccepted(connection.ConnectionId);
|
Log.ConnectionAccepted(connection.ConnectionId);
|
||||||
|
KestrelEventSource.Log.ConnectionQueuedStart(connection);
|
||||||
|
|
||||||
ThreadPool.UnsafeQueueUserWorkItem(kestrelConnection, preferLocal: false);
|
ThreadPool.UnsafeQueueUserWorkItem(kestrelConnection, preferLocal: false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
protected override void OnRequestProcessingEnded()
|
protected override void OnRequestProcessingEnded()
|
||||||
{
|
{
|
||||||
|
if (IsUpgraded)
|
||||||
|
{
|
||||||
|
KestrelEventSource.Log.RequestUpgradedStop(this);
|
||||||
|
|
||||||
|
ServiceContext.ConnectionManager.UpgradedConnectionCount.ReleaseOne();
|
||||||
|
}
|
||||||
|
|
||||||
TimeoutControl.StartDrainTimeout(MinResponseDataRate, ServerOptions.Limits.MaxResponseBufferSize);
|
TimeoutControl.StartDrainTimeout(MinResponseDataRate, ServerOptions.Limits.MaxResponseBufferSize);
|
||||||
|
|
||||||
// Prevent RequestAborted from firing. Free up unneeded feature references.
|
// Prevent RequestAborted from firing. Free up unneeded feature references.
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
IsUpgraded = true;
|
IsUpgraded = true;
|
||||||
|
|
||||||
|
KestrelEventSource.Log.RequestUpgradedStart(this);
|
||||||
|
|
||||||
ConnectionFeatures.Get<IDecrementConcurrentConnectionCountFeature>()?.ReleaseConnection();
|
ConnectionFeatures.Get<IDecrementConcurrentConnectionCountFeature>()?.ReleaseConnection();
|
||||||
|
|
||||||
StatusCode = StatusCodes.Status101SwitchingProtocols;
|
StatusCode = StatusCodes.Status101SwitchingProtocols;
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public int LocalPort { get; set; }
|
public int LocalPort { get; set; }
|
||||||
public string Scheme { get; set; }
|
public string Scheme { get; set; }
|
||||||
public HttpMethod Method { get; set; }
|
public HttpMethod Method { get; set; }
|
||||||
|
public string MethodText => ((IHttpRequestFeature)this).Method;
|
||||||
public string PathBase { get; set; }
|
public string PathBase { get; set; }
|
||||||
|
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -1002,6 +1002,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KestrelEventSource.Log.RequestQueuedStart(_currentHeadersStream, AspNetCore.Http.HttpProtocol.Http2);
|
||||||
// Must not allow app code to block the connection handling loop.
|
// Must not allow app code to block the connection handling loop.
|
||||||
ThreadPool.UnsafeQueueUserWorkItem(_currentHeadersStream, preferLocal: false);
|
ThreadPool.UnsafeQueueUserWorkItem(_currentHeadersStream, preferLocal: false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Abstractions;
|
using Microsoft.AspNetCore.Hosting.Server.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||||
{
|
{
|
||||||
|
|
@ -19,6 +20,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||||
|
|
||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.RequestQueuedStop(this, AspNetCore.Http.HttpProtocol.Http2);
|
||||||
// REVIEW: Should we store this in a field for easy debugging?
|
// REVIEW: Should we store this in a field for easy debugging?
|
||||||
_ = ProcessRequestsAsync(_application);
|
_ = ProcessRequestsAsync(_application);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
|
||||||
{
|
{
|
||||||
_streams[streamId] = http3Stream;
|
_streams[streamId] = http3Stream;
|
||||||
}
|
}
|
||||||
|
KestrelEventSource.Log.RequestQueuedStart(stream, AspNetCore.Http.HttpProtocol.Http3);
|
||||||
ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
|
ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Abstractions;
|
using Microsoft.AspNetCore.Hosting.Server.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
|
||||||
{
|
{
|
||||||
|
|
@ -17,6 +18,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3
|
||||||
|
|
||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.RequestQueuedStop(this, AspNetCore.Http.HttpProtocol.Http3);
|
||||||
|
|
||||||
if (_requestHeaderParsingState == Http3Stream.RequestHeaderParsingState.Ready)
|
if (_requestHeaderParsingState == Http3Stream.RequestHeaderParsingState.Ready)
|
||||||
{
|
{
|
||||||
_ = ProcessRequestAsync(_application);
|
_ = ProcessRequestAsync(_application);
|
||||||
|
|
|
||||||
|
|
@ -107,13 +107,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
{
|
{
|
||||||
Log.LogCritical(0, ex, $"Unexpected exception in {nameof(HttpConnection)}.{nameof(ProcessRequestsAsync)}.");
|
Log.LogCritical(0, ex, $"Unexpected exception in {nameof(HttpConnection)}.{nameof(ProcessRequestsAsync)}.");
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (_http1Connection?.IsUpgraded == true)
|
|
||||||
{
|
|
||||||
_context.ServiceContext.ConnectionManager.UpgradedConnectionCount.ReleaseOne();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing only
|
// For testing only
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.ConnectionQueuedStop(connectionContext);
|
||||||
|
|
||||||
Logger.ConnectionStart(connectionContext.ConnectionId);
|
Logger.ConnectionStart(connectionContext.ConnectionId);
|
||||||
KestrelEventSource.Log.ConnectionStart(connectionContext);
|
KestrelEventSource.Log.ConnectionStart(connectionContext);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Diagnostics.Tracing;
|
using System.Diagnostics.Tracing;
|
||||||
|
using System.Net.Security;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
|
||||||
|
|
@ -13,6 +17,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
{
|
{
|
||||||
public static readonly KestrelEventSource Log = new KestrelEventSource();
|
public static readonly KestrelEventSource Log = new KestrelEventSource();
|
||||||
|
|
||||||
|
private IncrementingPollingCounter _connectionsPerSecondCounter;
|
||||||
|
private IncrementingPollingCounter _tlsHandshakesPerSecondCounter;
|
||||||
|
private PollingCounter _totalConnectionsCounter;
|
||||||
|
private PollingCounter _currentConnectionsCounter;
|
||||||
|
private PollingCounter _totalTlsHandshakesCounter;
|
||||||
|
private PollingCounter _currentTlsHandshakesCounter;
|
||||||
|
private PollingCounter _failedTlsHandshakesCounter;
|
||||||
|
private PollingCounter _connectionQueueLengthCounter;
|
||||||
|
private PollingCounter _httpRequestQueueLengthCounter;
|
||||||
|
private PollingCounter _currrentUpgradedHttpRequestsCounter;
|
||||||
|
|
||||||
|
private long _totalConnections;
|
||||||
|
private long _currentConnections;
|
||||||
|
private long _connectionQueueLength;
|
||||||
|
private long _totalTlsHandshakes;
|
||||||
|
private long _currentTlsHandshakes;
|
||||||
|
private long _failedTlsHandshakes;
|
||||||
|
private long _httpRequestQueueLength;
|
||||||
|
private long _currentUpgradedHttpRequests;
|
||||||
|
|
||||||
private KestrelEventSource()
|
private KestrelEventSource()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -29,6 +53,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
public void ConnectionStart(BaseConnectionContext connection)
|
public void ConnectionStart(BaseConnectionContext connection)
|
||||||
{
|
{
|
||||||
// avoid allocating strings unless this event source is enabled
|
// avoid allocating strings unless this event source is enabled
|
||||||
|
Interlocked.Increment(ref _totalConnections);
|
||||||
|
Interlocked.Increment(ref _currentConnections);
|
||||||
|
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
{
|
{
|
||||||
ConnectionStart(
|
ConnectionStart(
|
||||||
|
|
@ -39,7 +66,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
[Event(1, Level = EventLevel.Verbose)]
|
[Event(1, Level = EventLevel.Informational)]
|
||||||
private void ConnectionStart(string connectionId,
|
private void ConnectionStart(string connectionId,
|
||||||
string localEndPoint,
|
string localEndPoint,
|
||||||
string remoteEndPoint)
|
string remoteEndPoint)
|
||||||
|
|
@ -55,6 +82,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
[NonEvent]
|
[NonEvent]
|
||||||
public void ConnectionStop(BaseConnectionContext connection)
|
public void ConnectionStop(BaseConnectionContext connection)
|
||||||
{
|
{
|
||||||
|
Interlocked.Decrement(ref _currentConnections);
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
{
|
{
|
||||||
ConnectionStop(connection.ConnectionId);
|
ConnectionStop(connection.ConnectionId);
|
||||||
|
|
@ -62,14 +90,48 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
[Event(2, Level = EventLevel.Verbose)]
|
[Event(2, Level = EventLevel.Informational)]
|
||||||
private void ConnectionStop(string connectionId)
|
private void ConnectionStop(string connectionId)
|
||||||
{
|
{
|
||||||
WriteEvent(2, connectionId);
|
WriteEvent(2, connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestStart(HttpProtocol httpProtocol)
|
||||||
|
{
|
||||||
|
// avoid allocating the trace identifier unless logging is enabled
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestStart(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpProtocol.HttpVersion, httpProtocol.Path, httpProtocol.MethodText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
[Event(5, Level = EventLevel.Verbose)]
|
[Event(3, Level = EventLevel.Informational)]
|
||||||
|
private void RequestStart(string connectionId, string requestId, string httpVersion, string path, string method)
|
||||||
|
{
|
||||||
|
WriteEvent(3, connectionId, requestId, httpVersion, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestStop(HttpProtocol httpProtocol)
|
||||||
|
{
|
||||||
|
// avoid allocating the trace identifier unless logging is enabled
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestStop(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpProtocol.HttpVersion, httpProtocol.Path, httpProtocol.MethodText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(4, Level = EventLevel.Informational)]
|
||||||
|
private void RequestStop(string connectionId, string requestId, string httpVersion, string path, string method)
|
||||||
|
{
|
||||||
|
WriteEvent(4, connectionId, requestId, httpVersion, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(5, Level = EventLevel.Informational)]
|
||||||
public void ConnectionRejected(string connectionId)
|
public void ConnectionRejected(string connectionId)
|
||||||
{
|
{
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
|
|
@ -79,37 +141,235 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonEvent]
|
[NonEvent]
|
||||||
public void RequestStart(HttpProtocol httpProtocol)
|
public void ConnectionQueuedStart(BaseConnectionContext connection)
|
||||||
{
|
{
|
||||||
// avoid allocating the trace identifier unless logging is enabled
|
Interlocked.Increment(ref _connectionQueueLength);
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
{
|
{
|
||||||
RequestStart(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier);
|
ConnectionQueuedStart(
|
||||||
|
connection.ConnectionId,
|
||||||
|
connection.LocalEndPoint?.ToString(),
|
||||||
|
connection.RemoteEndPoint?.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
[Event(3, Level = EventLevel.Verbose)]
|
[Event(6, Level = EventLevel.Informational)]
|
||||||
private void RequestStart(string connectionId, string requestId)
|
private void ConnectionQueuedStart(string connectionId,
|
||||||
|
string localEndPoint,
|
||||||
|
string remoteEndPoint)
|
||||||
{
|
{
|
||||||
WriteEvent(3, connectionId, requestId);
|
WriteEvent(
|
||||||
|
6,
|
||||||
|
connectionId,
|
||||||
|
localEndPoint,
|
||||||
|
remoteEndPoint
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonEvent]
|
[NonEvent]
|
||||||
public void RequestStop(HttpProtocol httpProtocol)
|
public void ConnectionQueuedStop(BaseConnectionContext connection)
|
||||||
{
|
{
|
||||||
// avoid allocating the trace identifier unless logging is enabled
|
Interlocked.Decrement(ref _connectionQueueLength);
|
||||||
if (IsEnabled())
|
if (IsEnabled())
|
||||||
{
|
{
|
||||||
RequestStop(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier);
|
ConnectionQueuedStop(
|
||||||
|
connection.ConnectionId,
|
||||||
|
connection.LocalEndPoint?.ToString(),
|
||||||
|
connection.RemoteEndPoint?.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
[Event(4, Level = EventLevel.Verbose)]
|
[Event(7, Level = EventLevel.Informational)]
|
||||||
private void RequestStop(string connectionId, string requestId)
|
private void ConnectionQueuedStop(string connectionId,
|
||||||
|
string localEndPoint,
|
||||||
|
string remoteEndPoint)
|
||||||
{
|
{
|
||||||
WriteEvent(4, connectionId, requestId);
|
WriteEvent(
|
||||||
|
7,
|
||||||
|
connectionId,
|
||||||
|
localEndPoint,
|
||||||
|
remoteEndPoint
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void TlsHandshakeStart(BaseConnectionContext connectionContext, SslServerAuthenticationOptions sslOptions)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _currentTlsHandshakes);
|
||||||
|
Interlocked.Increment(ref _totalTlsHandshakes);
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
TlsHandshakeStart(connectionContext.ConnectionId, sslOptions.EnabledSslProtocols.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(8, Level = EventLevel.Informational)]
|
||||||
|
private void TlsHandshakeStart(string connectionId, string sslProtocols)
|
||||||
|
{
|
||||||
|
WriteEvent(8, connectionId, sslProtocols);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void TlsHandshakeStop(BaseConnectionContext connectionContext, TlsConnectionFeature feature)
|
||||||
|
{
|
||||||
|
Interlocked.Decrement(ref _currentTlsHandshakes);
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
// TODO: Write this without a string allocation using WriteEventData
|
||||||
|
var applicationProtocol = feature == null ? string.Empty : Encoding.UTF8.GetString(feature.ApplicationProtocol.Span);
|
||||||
|
var sslProtocols = feature?.Protocol.ToString() ?? string.Empty;
|
||||||
|
var hostName = feature?.HostName ?? string.Empty;
|
||||||
|
TlsHandshakeStop(connectionContext.ConnectionId, sslProtocols, applicationProtocol, hostName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(9, Level = EventLevel.Informational)]
|
||||||
|
private void TlsHandshakeStop(string connectionId, string sslProtocols, string applicationProtocol, string hostName)
|
||||||
|
{
|
||||||
|
WriteEvent(9, connectionId, sslProtocols, applicationProtocol, hostName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(10, Level = EventLevel.Error)]
|
||||||
|
public void TlsHandshakeFailed(string connectionId)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _failedTlsHandshakes);
|
||||||
|
WriteEvent(10, connectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestQueuedStart(HttpProtocol httpProtocol, string httpVersion)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _httpRequestQueueLength);
|
||||||
|
// avoid allocating the trace identifier unless logging is enabled
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestQueuedStart(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(11, Level = EventLevel.Informational)]
|
||||||
|
private void RequestQueuedStart(string connectionId, string requestId, string httpVersion)
|
||||||
|
{
|
||||||
|
WriteEvent(11, connectionId, requestId, httpVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestQueuedStop(HttpProtocol httpProtocol, string httpVersion)
|
||||||
|
{
|
||||||
|
Interlocked.Decrement(ref _httpRequestQueueLength);
|
||||||
|
// avoid allocating the trace identifier unless logging is enabled
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestQueuedStop(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(12, Level = EventLevel.Informational)]
|
||||||
|
private void RequestQueuedStop(string connectionId, string requestId, string httpVersion)
|
||||||
|
{
|
||||||
|
WriteEvent(12, connectionId, requestId, httpVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestUpgradedStart(HttpProtocol httpProtocol)
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref _currentUpgradedHttpRequests);
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestUpgradedStart(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpProtocol.HttpVersion, httpProtocol.Path, httpProtocol.MethodText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(13, Level = EventLevel.Informational)]
|
||||||
|
private void RequestUpgradedStart(string connectionId, string requestId, string httpVersion, string path, string method)
|
||||||
|
{
|
||||||
|
WriteEvent(13, connectionId, requestId, httpVersion, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonEvent]
|
||||||
|
public void RequestUpgradedStop(HttpProtocol httpProtocol)
|
||||||
|
{
|
||||||
|
Interlocked.Decrement(ref _currentUpgradedHttpRequests);
|
||||||
|
if (IsEnabled())
|
||||||
|
{
|
||||||
|
RequestUpgradedStop(httpProtocol.ConnectionIdFeature, httpProtocol.TraceIdentifier, httpProtocol.HttpVersion, httpProtocol.Path, httpProtocol.MethodText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
[Event(14, Level = EventLevel.Informational)]
|
||||||
|
private void RequestUpgradedStop(string connectionId, string requestId, string httpVersion, string path, string method)
|
||||||
|
{
|
||||||
|
WriteEvent(14, connectionId, requestId, httpVersion, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnEventCommand(EventCommandEventArgs command)
|
||||||
|
{
|
||||||
|
if (command.Command == EventCommand.Enable)
|
||||||
|
{
|
||||||
|
// This is the convention for initializing counters in the RuntimeEventSource (lazily on the first enable command).
|
||||||
|
// They aren't disabled afterwards...
|
||||||
|
|
||||||
|
_connectionsPerSecondCounter ??= new IncrementingPollingCounter("connections-per-second", this, () => _totalConnections)
|
||||||
|
{
|
||||||
|
DisplayName = "Connection Rate",
|
||||||
|
DisplayRateTimeScale = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
_totalConnectionsCounter ??= new PollingCounter("total-connections", this, () => _totalConnections)
|
||||||
|
{
|
||||||
|
DisplayName = "Total Connections",
|
||||||
|
};
|
||||||
|
|
||||||
|
_tlsHandshakesPerSecondCounter ??= new IncrementingPollingCounter("tls-handshakes-per-second", this, () => _totalTlsHandshakes)
|
||||||
|
{
|
||||||
|
DisplayName = "TLS Handshake Rate",
|
||||||
|
DisplayRateTimeScale = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
_totalTlsHandshakesCounter ??= new PollingCounter("total-tls-handshakes", this, () => _totalTlsHandshakes)
|
||||||
|
{
|
||||||
|
DisplayName = "Total TLS Handshakes",
|
||||||
|
};
|
||||||
|
|
||||||
|
_currentTlsHandshakesCounter ??= new PollingCounter("current-tls-handshakes", this, () => _currentTlsHandshakes)
|
||||||
|
{
|
||||||
|
DisplayName = "Current TLS Handshakes"
|
||||||
|
};
|
||||||
|
|
||||||
|
_failedTlsHandshakesCounter ??= new PollingCounter("failed-tls-handshakes", this, () => _failedTlsHandshakes)
|
||||||
|
{
|
||||||
|
DisplayName = "Failed TLS Handshakes"
|
||||||
|
};
|
||||||
|
|
||||||
|
_currentConnectionsCounter ??= new PollingCounter("current-connections", this, () => _currentConnections)
|
||||||
|
{
|
||||||
|
DisplayName = "Current Connections"
|
||||||
|
};
|
||||||
|
|
||||||
|
_connectionQueueLengthCounter ??= new PollingCounter("connection-queue-length", this, () => _connectionQueueLength)
|
||||||
|
{
|
||||||
|
DisplayName = "Connection Queue Length"
|
||||||
|
};
|
||||||
|
|
||||||
|
_httpRequestQueueLengthCounter ??= new PollingCounter("request-queue-length", this, () => _httpRequestQueueLength)
|
||||||
|
{
|
||||||
|
DisplayName = "Request Queue Length"
|
||||||
|
};
|
||||||
|
|
||||||
|
_currrentUpgradedHttpRequestsCounter ??= new PollingCounter("current-upgraded-requests", this, () => _currentUpgradedHttpRequests)
|
||||||
|
{
|
||||||
|
DisplayName = "Current Upgraded Requests (WebSockets)"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
||||||
{
|
{
|
||||||
public X509Certificate2 ClientCertificate { get; set; }
|
public X509Certificate2 ClientCertificate { get; set; }
|
||||||
|
|
||||||
|
public string HostName { get; set; }
|
||||||
|
|
||||||
public ReadOnlyMemory<byte> ApplicationProtocol { get; set; }
|
public ReadOnlyMemory<byte> ApplicationProtocol { get; set; }
|
||||||
|
|
||||||
public SslProtocols Protocol { get; set; }
|
public SslProtocols Protocol { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ using System.Security.Authentication;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Certificates.Generation;
|
|
||||||
using Microsoft.AspNetCore.Connections;
|
using Microsoft.AspNetCore.Connections;
|
||||||
using Microsoft.AspNetCore.Connections.Features;
|
using Microsoft.AspNetCore.Connections.Features;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Features;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
|
||||||
|
|
@ -169,6 +169,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
||||||
{
|
{
|
||||||
selector = (sender, name) =>
|
selector = (sender, name) =>
|
||||||
{
|
{
|
||||||
|
feature.HostName = name;
|
||||||
context.Features.Set(sslStream);
|
context.Features.Set(sslStream);
|
||||||
var cert = _serverCertificateSelector(context, name);
|
var cert = _serverCertificateSelector(context, name);
|
||||||
if (cert != null)
|
if (cert != null)
|
||||||
|
|
@ -204,22 +205,33 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
||||||
|
|
||||||
_options.OnAuthenticate?.Invoke(context, sslOptions);
|
_options.OnAuthenticate?.Invoke(context, sslOptions);
|
||||||
|
|
||||||
|
KestrelEventSource.Log.TlsHandshakeStart(context, sslOptions);
|
||||||
|
|
||||||
await sslStream.AuthenticateAsServerAsync(sslOptions, cancellationTokeSource.Token);
|
await sslStream.AuthenticateAsServerAsync(sslOptions, cancellationTokeSource.Token);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.TlsHandshakeFailed(context.ConnectionId);
|
||||||
|
KestrelEventSource.Log.TlsHandshakeStop(context, null);
|
||||||
|
|
||||||
_logger.LogDebug(2, CoreStrings.AuthenticationTimedOut);
|
_logger.LogDebug(2, CoreStrings.AuthenticationTimedOut);
|
||||||
await sslStream.DisposeAsync();
|
await sslStream.DisposeAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.TlsHandshakeFailed(context.ConnectionId);
|
||||||
|
KestrelEventSource.Log.TlsHandshakeStop(context, null);
|
||||||
|
|
||||||
_logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
_logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
||||||
await sslStream.DisposeAsync();
|
await sslStream.DisposeAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (AuthenticationException ex)
|
catch (AuthenticationException ex)
|
||||||
{
|
{
|
||||||
|
KestrelEventSource.Log.TlsHandshakeFailed(context.ConnectionId);
|
||||||
|
KestrelEventSource.Log.TlsHandshakeStop(context, null);
|
||||||
|
|
||||||
_logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
_logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed);
|
||||||
|
|
||||||
await sslStream.DisposeAsync();
|
await sslStream.DisposeAsync();
|
||||||
|
|
@ -238,6 +250,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal
|
||||||
feature.KeyExchangeStrength = sslStream.KeyExchangeStrength;
|
feature.KeyExchangeStrength = sslStream.KeyExchangeStrength;
|
||||||
feature.Protocol = sslStream.SslProtocol;
|
feature.Protocol = sslStream.SslProtocol;
|
||||||
|
|
||||||
|
KestrelEventSource.Log.TlsHandshakeStop(context, feature);
|
||||||
|
|
||||||
var originalTransport = context.Transport;
|
var originalTransport = context.Transport;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue