Log client errors as Debug (#12262)
This commit is contained in:
parent
771989b71d
commit
9c19577d49
|
|
@ -571,6 +571,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
Log.RequestProcessingError(ConnectionId, ex);
|
||||
}
|
||||
catch (ConnectionAbortedException ex)
|
||||
{
|
||||
Log.RequestProcessingError(ConnectionId, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.LogWarning(0, ex, CoreStrings.RequestProcessingEndError);
|
||||
|
|
|
|||
|
|
@ -244,6 +244,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
Log.RequestProcessingError(ConnectionId, ex);
|
||||
error = ex;
|
||||
}
|
||||
catch (ConnectionAbortedException ex)
|
||||
{
|
||||
Log.RequestProcessingError(ConnectionId, ex);
|
||||
error = ex;
|
||||
}
|
||||
catch (Http2ConnectionErrorException ex)
|
||||
{
|
||||
Log.Http2ConnectionError(ConnectionId, ex);
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
LoggerMessage.Define(LogLevel.Debug, new EventId(16, nameof(NotAllConnectionsClosedGracefully)), "Some connections failed to close gracefully during server shutdown.");
|
||||
|
||||
private static readonly Action<ILogger, string, string, Exception> _connectionBadRequest =
|
||||
LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(17, nameof(ConnectionBadRequest)), @"Connection id ""{ConnectionId}"" bad request data: ""{message}""");
|
||||
LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(17, nameof(ConnectionBadRequest)), @"Connection id ""{ConnectionId}"" bad request data: ""{message}""");
|
||||
|
||||
private static readonly Action<ILogger, string, long, Exception> _connectionHeadResponseBodyWrite =
|
||||
LoggerMessage.Define<string, long>(LogLevel.Debug, new EventId(18, nameof(ConnectionHeadResponseBodyWrite)), @"Connection id ""{ConnectionId}"" write of ""{count}"" body bytes to non-body HEAD response.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _requestProcessingError =
|
||||
LoggerMessage.Define<string>(LogLevel.Information, new EventId(20, nameof(RequestProcessingError)), @"Connection id ""{ConnectionId}"" request processing ended abnormally.");
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(20, nameof(RequestProcessingError)), @"Connection id ""{ConnectionId}"" request processing ended abnormally.");
|
||||
|
||||
private static readonly Action<ILogger, Exception> _notAllConnectionsAborted =
|
||||
LoggerMessage.Define(LogLevel.Debug, new EventId(21, nameof(NotAllConnectionsAborted)), "Some connections failed to abort during server shutdown.");
|
||||
|
|
@ -64,19 +64,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(26, nameof(RequestBodyDone)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": done reading request body.");
|
||||
|
||||
private static readonly Action<ILogger, string, string, double, Exception> _requestBodyMinimumDataRateNotSatisfied =
|
||||
LoggerMessage.Define<string, string, double>(LogLevel.Information, new EventId(27, nameof(RequestBodyMinimumDataRateNotSatisfied)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": the request timed out because it was not sent by the client at a minimum of {Rate} bytes/second.");
|
||||
LoggerMessage.Define<string, string, double>(LogLevel.Debug, new EventId(27, nameof(RequestBodyMinimumDataRateNotSatisfied)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": the request timed out because it was not sent by the client at a minimum of {Rate} bytes/second.");
|
||||
|
||||
private static readonly Action<ILogger, string, string, Exception> _responseMinimumDataRateNotSatisfied =
|
||||
LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(28, nameof(ResponseMinimumDataRateNotSatisfied)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": the connection was closed because the response was not read by the client at the specified minimum data rate.");
|
||||
LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(28, nameof(ResponseMinimumDataRateNotSatisfied)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": the connection was closed because the response was not read by the client at the specified minimum data rate.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _http2ConnectionError =
|
||||
LoggerMessage.Define<string>(LogLevel.Information, new EventId(29, nameof(Http2ConnectionError)), @"Connection id ""{ConnectionId}"": HTTP/2 connection error.");
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(29, nameof(Http2ConnectionError)), @"Connection id ""{ConnectionId}"": HTTP/2 connection error.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _http2StreamError =
|
||||
LoggerMessage.Define<string>(LogLevel.Information, new EventId(30, nameof(Http2StreamError)), @"Connection id ""{ConnectionId}"": HTTP/2 stream error.");
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(30, nameof(Http2StreamError)), @"Connection id ""{ConnectionId}"": HTTP/2 stream error.");
|
||||
|
||||
private static readonly Action<ILogger, string, int, Exception> _hpackDecodingError =
|
||||
LoggerMessage.Define<string, int>(LogLevel.Information, new EventId(31, nameof(HPackDecodingError)), @"Connection id ""{ConnectionId}"": HPACK decoding error while decoding headers for stream ID {StreamId}.");
|
||||
LoggerMessage.Define<string, int>(LogLevel.Debug, new EventId(31, nameof(HPackDecodingError)), @"Connection id ""{ConnectionId}"": HPACK decoding error while decoding headers for stream ID {StreamId}.");
|
||||
|
||||
private static readonly Action<ILogger, string, string, Exception> _requestBodyNotEntirelyRead =
|
||||
LoggerMessage.Define<string, string>(LogLevel.Information, new EventId(32, nameof(RequestBodyNotEntirelyRead)), @"Connection id ""{ConnectionId}"", Request id ""{TraceIdentifier}"": the application completed without reading the entire request body.");
|
||||
|
|
|
|||
|
|
@ -46,9 +46,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW
|
|||
private TaskCompletionSource<FlushResult> _currentFlushTcs;
|
||||
private bool _bufferedWritePending;
|
||||
|
||||
// We're trusting the Http2FrameWriter and Http1OutputProducer to not call into the PipeWriter after calling Abort() or Complete()
|
||||
// If an abort occurs while a flush is in progress, we clean up after the flush completes, and don't flush again.
|
||||
// We're trusting the Http2FrameWriter and Http1OutputProducer to not call into the PipeWriter after calling Abort() or Complete().
|
||||
// If an Abort() is called while a flush is in progress, we clean up after the next flush completes, and don't flush again.
|
||||
private bool _aborted;
|
||||
// If an Complete() is called while a flush is in progress, we clean up after the flush loop completes, and call Complete() on the inner PipeWriter.
|
||||
private Exception _completeException;
|
||||
|
||||
public ConcurrentPipeWriter(PipeWriter innerPipeWriter, MemoryPool<byte> pool, object sync)
|
||||
|
|
@ -123,7 +124,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW
|
|||
return flushTask;
|
||||
}
|
||||
|
||||
// Use a TCS instead of something resettable so it can be awaited by multiple awaiters.
|
||||
// Use a TCS instead of something custom so it can be awaited by multiple awaiters.
|
||||
_currentFlushTcs = new TaskCompletionSource<FlushResult>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var result = new ValueTask<FlushResult>(_currentFlushTcs.Task);
|
||||
|
||||
|
|
@ -153,7 +154,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW
|
|||
|
||||
if (flushResult.IsCanceled)
|
||||
{
|
||||
// Complete anyone currently awaiting a flush since CancelPendingFlush() was called
|
||||
// Complete anyone currently awaiting a flush with the canceled FlushResult since CancelPendingFlush() was called.
|
||||
_currentFlushTcs.SetResult(flushResult);
|
||||
// Reset _currentFlushTcs, so we don't enter passthrough mode while we're still flushing.
|
||||
_currentFlushTcs = new TaskCompletionSource<FlushResult>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
|
@ -176,18 +177,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW
|
|||
|
||||
public override void CancelPendingFlush()
|
||||
{
|
||||
// We propagate IsCanceled when we do multiple flushes in a loop. If FlushResult.IsCanceled is true with more data pending to flush,
|
||||
// _currentFlushTcs with canceled flush task, but rekick the FlushAsync loop.
|
||||
// FlushAsyncAwaited never ignores a canceled FlushResult.
|
||||
_innerPipeWriter.CancelPendingFlush();
|
||||
}
|
||||
|
||||
// To return all the segments without completing the inner pipe, call Abort().
|
||||
public override void Complete(Exception exception = null)
|
||||
{
|
||||
// We store the complete exception or s sentinel exception instance in a field if a flush was ongoing.
|
||||
// We call the inner Complete() method after the flush loop ended.
|
||||
|
||||
// To simply ensure everything gets returned after the PipeWriter is left in some unknown state (say GetMemory() was
|
||||
// called but not Advance(), or there's a flush pending), but you don't want to complete the inner pipe, just call Abort().
|
||||
// Store the exception or sentinel in a field so that if a flush is ongoing, we call the
|
||||
// inner Complete() method with the correct exception or lack thereof once the flush loop ends.
|
||||
_completeException = exception ?? _successfullyCompletedSentinel;
|
||||
|
||||
if (_currentFlushTcs == null)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
|||
// ConnectionWriteCallback: Reserved: 12
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _connectionError =
|
||||
LoggerMessage.Define<string>(LogLevel.Information, new EventId(14, nameof(ConnectionError)), @"Connection id ""{ConnectionId}"" communication error.");
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(14, nameof(ConnectionError)), @"Connection id ""{ConnectionId}"" communication error.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _connectionReset =
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(19, nameof(ConnectionReset)), @"Connection id ""{ConnectionId}"" reset.");
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
// ConnectionWriteCallback: Reserved: 12
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _connectionError =
|
||||
LoggerMessage.Define<string>(LogLevel.Information, new EventId(14, nameof(ConnectionError)), @"Connection id ""{ConnectionId}"" communication error.");
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(14, nameof(ConnectionError)), @"Connection id ""{ConnectionId}"" communication error.");
|
||||
|
||||
private static readonly Action<ILogger, string, Exception> _connectionReset =
|
||||
LoggerMessage.Define<string>(LogLevel.Debug, new EventId(19, nameof(ConnectionReset)), @"Connection id ""{ConnectionId}"" reset.");
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BadRequestLogsAreNotHigherThanInformation()
|
||||
public async Task BadRequestLogsAreNotHigherThanDebug()
|
||||
{
|
||||
await using (var server = new TestServer(async context =>
|
||||
{
|
||||
|
|
@ -168,8 +168,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
Assert.All(TestSink.Writes, w => Assert.InRange(w.LogLevel, LogLevel.Trace, LogLevel.Information));
|
||||
Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information);
|
||||
Assert.All(TestSink.Writes, w => Assert.InRange(w.LogLevel, LogLevel.Trace, LogLevel.Debug));
|
||||
Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -3731,7 +3731,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void IOExceptionDuringFrameProcessingLoggedAsInfo()
|
||||
public void IOExceptionDuringFrameProcessingIsNotLoggedHigherThanDebug()
|
||||
{
|
||||
CreateConnection();
|
||||
|
||||
|
|
@ -3740,9 +3740,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
Assert.Equal(TaskStatus.RanToCompletion, _connection.ProcessRequestsAsync(new DummyApplication(_noopApplication)).Status);
|
||||
|
||||
var logMessage = TestApplicationErrorLogger.Messages.Single(m => m.LogLevel >= LogLevel.Information);
|
||||
Assert.All(TestApplicationErrorLogger.Messages, w => Assert.InRange(w.LogLevel, LogLevel.Trace, LogLevel.Debug));
|
||||
|
||||
var logMessage = TestApplicationErrorLogger.Messages.Single(m => m.EventId == 20);
|
||||
|
||||
Assert.Equal(LogLevel.Information, logMessage.LogLevel);
|
||||
Assert.Equal("Connection id \"(null)\" request processing ended abnormally.", logMessage.Message);
|
||||
Assert.Same(ioException, logMessage.Exception);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.NotNull(transportConnection.AbortReason);
|
||||
Assert.Equal(CoreStrings.ConnectionTimedBecauseResponseMininumDataRateNotSatisfied, transportConnection.AbortReason.Message);
|
||||
|
||||
Assert.Single(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 28 && w.LogLevel == LogLevel.Information);
|
||||
Assert.Single(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 28 && w.LogLevel <= LogLevel.Debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
|
||||
Assert.NotNull(readException);
|
||||
|
||||
Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information && w.Exception is BadHttpRequestException
|
||||
Assert.Contains(TestSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
|
|
@ -1750,7 +1750,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information && w.Exception is BadHttpRequestException
|
||||
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
|
|
@ -1802,7 +1802,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
{
|
||||
while (TestApplicationErrorLogger.Messages.TryDequeue(out var message))
|
||||
{
|
||||
if (message.EventId.Id == 17 && message.LogLevel == LogLevel.Information && message.Exception is BadHttpRequestException
|
||||
if (message.EventId.Id == 17 && message.LogLevel <= LogLevel.Debug && message.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)message.Exception).StatusCode == StatusCodes.Status400BadRequest)
|
||||
{
|
||||
foundMessage = true;
|
||||
|
|
@ -1863,7 +1863,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
}
|
||||
}
|
||||
|
||||
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information && w.Exception is BadHttpRequestException
|
||||
Assert.Contains(TestApplicationErrorLogger.Messages, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
|
||||
}
|
||||
|
||||
|
|
@ -4118,13 +4118,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
|||
|
||||
if (sendMalformedRequest)
|
||||
{
|
||||
Assert.Contains(testSink.Writes, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information && w.Exception is BadHttpRequestException
|
||||
Assert.Contains(testSink.Writes, w => w.EventId.Id == 17 && w.LogLevel <= LogLevel.Debug && w.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.DoesNotContain(testSink.Writes, w => w.EventId.Id == 17 && w.LogLevel == LogLevel.Information && w.Exception is BadHttpRequestException
|
||||
&& ((BadHttpRequestException)w.Exception).StatusCode == StatusCodes.Status400BadRequest);
|
||||
Assert.DoesNotContain(testSink.Writes, w => w.EventId.Id == 17);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue