Skip to content

Commit ff8bdf1

Browse files
committed
Move request cancellations to a separate log
1 parent d95cb8a commit ff8bdf1

File tree

6 files changed

+187
-218
lines changed

6 files changed

+187
-218
lines changed

src/ReverseProxy/Forwarder/HttpForwarder.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,11 @@ private static class Log
982982
EventIds.ForwardingError,
983983
"{error}: {message}");
984984

985+
private static readonly Action<ILogger, ForwarderError, string, Exception> _proxyRequestCancelled = LoggerMessage.Define<ForwarderError, string>(
986+
LogLevel.Debug,
987+
EventIds.ForwardingRequestCancelled,
988+
"{error}: {message}");
989+
985990
private static readonly Action<ILogger, int, Exception?> _notProxying = LoggerMessage.Define<int>(
986991
LogLevel.Information,
987992
EventIds.NotForwarding,
@@ -1031,7 +1036,21 @@ public static void InvalidSecWebSocketKeyHeader(ILogger logger, string? key)
10311036

10321037
public static void ErrorProxying(ILogger logger, ForwarderError error, Exception ex)
10331038
{
1034-
_proxyError(logger, error, GetMessage(error), ex);
1039+
var message = GetMessage(error);
1040+
1041+
if (error is
1042+
ForwarderError.RequestCanceled or
1043+
ForwarderError.RequestBodyCanceled or
1044+
ForwarderError.UpgradeRequestCanceled)
1045+
{
1046+
// These error conditions are triggered by the client and are not generally indicative of a problem with the proxy.
1047+
// It's unlikely that they will be useful in most cases, so we log them at Debug level to reduce noise.
1048+
_proxyRequestCancelled(logger, error, message, ex);
1049+
}
1050+
else
1051+
{
1052+
_proxyError(logger, error, message, ex);
1053+
}
10351054
}
10361055

10371056
public static void RetryingWebSocketDowngradeNoConnect(ILogger logger)

src/ReverseProxy/Utilities/EventIds.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,5 @@ internal static class EventIds
6969
public static readonly EventId InvalidSecWebSocketKeyHeader = new EventId(63, "InvalidSecWebSocketKeyHeader");
7070
public static readonly EventId TimeoutNotApplied = new(64, nameof(TimeoutNotApplied));
7171
public static readonly EventId DelegationQueueNoLongerExists = new(65, nameof(DelegationQueueNoLongerExists));
72+
public static readonly EventId ForwardingRequestCancelled = new(66, nameof(ForwardingRequestCancelled));
7273
}
Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
54
using System.Collections.Generic;
65
using System.Diagnostics.Tracing;
76
using System.Threading;
@@ -10,13 +9,12 @@ namespace Yarp.Tests.Common;
109

1110
internal static class TestEventListener
1211
{
13-
private static readonly AsyncLocal<List<EventWrittenEventArgs>> _eventsAsyncLocal = new AsyncLocal<List<EventWrittenEventArgs>>();
14-
private static readonly InternalEventListener _listener = new InternalEventListener();
12+
private static readonly AsyncLocal<List<EventWrittenEventArgs>> _eventsAsyncLocal = new();
13+
#pragma warning disable IDE0052 // Remove unread private members
14+
private static readonly InternalEventListener _listener = new();
15+
#pragma warning restore IDE0052
1516

16-
public static List<EventWrittenEventArgs> Collect()
17-
{
18-
return _eventsAsyncLocal.Value = new List<EventWrittenEventArgs>();
19-
}
17+
public static List<EventWrittenEventArgs> Collect() => _eventsAsyncLocal.Value ??= [];
2018

2119
private sealed class InternalEventListener : EventListener
2220
{
@@ -28,14 +26,7 @@ protected override void OnEventSourceCreated(EventSource eventSource)
2826
}
2927
}
3028

31-
protected override void OnEventWritten(EventWrittenEventArgs eventData)
32-
{
33-
if (eventData.EventId == 0)
34-
{
35-
throw new Exception($"EventSource error received: {eventData.Payload[0]}");
36-
}
37-
29+
protected override void OnEventWritten(EventWrittenEventArgs eventData) =>
3830
_eventsAsyncLocal.Value?.Add(eventData);
39-
}
4031
}
4132
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Threading;
7+
using Microsoft.Extensions.Logging;
8+
9+
namespace Yarp.ReverseProxy.Common;
10+
11+
internal sealed class TestLogger(ILogger xunitLogger, string categoryName) : ILogger
12+
{
13+
public record LogEntry(string CategoryName, LogLevel LogLevel, EventId EventId, string Message, Exception Exception);
14+
15+
private static readonly AsyncLocal<List<LogEntry>> _logsAsyncLocal = new();
16+
17+
public static List<LogEntry> Collect() => _logsAsyncLocal.Value ??= [];
18+
19+
public IDisposable BeginScope<TState>(TState state) where TState : notnull => xunitLogger.BeginScope(state);
20+
21+
public bool IsEnabled(LogLevel logLevel) => true;
22+
23+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
24+
{
25+
_logsAsyncLocal.Value?.Add(new LogEntry(categoryName, logLevel, eventId, formatter(state, exception), exception));
26+
27+
xunitLogger.Log(logLevel, eventId, state, exception, formatter);
28+
}
29+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.Extensions.Logging;
5+
using Microsoft.Extensions.Logging.Testing;
6+
using Xunit.Abstractions;
7+
8+
namespace Yarp.ReverseProxy.Common;
9+
10+
internal sealed class TestLoggerProvider(ITestOutputHelper output) : ILoggerProvider
11+
{
12+
private readonly XunitLoggerProvider _xunitLoggerProvider = new(output);
13+
14+
public ILogger CreateLogger(string categoryName) => new TestLogger(_xunitLoggerProvider.CreateLogger(categoryName), categoryName);
15+
16+
public void Dispose() => _xunitLoggerProvider.Dispose();
17+
}

0 commit comments

Comments
 (0)