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

Make connection reset logs less scary #1199

Merged
merged 1 commit into from
Nov 5, 2016
Merged

Make connection reset logs less scary #1199

merged 1 commit into from
Nov 5, 2016

Conversation

halter73
Copy link
Member

@halter73 halter73 commented Nov 5, 2016

  • Particularly between requests, connection resets aren't that abnormal.

#1176

@halter73
Copy link
Member Author

halter73 commented Nov 5, 2016

@CesarBS

@@ -188,6 +209,10 @@ public class Frame<TContext> : Frame
// SetBadRequestState logs the error.
SetBadRequestState(ex);
}
catch (IOException ex) when (ex.InnerException is UvException)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you do all checks here and avoid the new try/catch block around the code that reads the request line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't for that. The try/catch above handles that and completely swallows it if it's incomplete. This replaces the "Connection processing ended abnormally" with a better one which has an eventId, connectionId, etc... Since we know a bad connection can cause SocketInput to throw and cause request processing to end abnormally, it's better to handle that explicitly. This catch will handle any connection error, not just resets.

Log.LogWarning(0,... is generally reserved for things we don't expect to happen under normalish circumstances.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, what I meant was, let the code above throw and catch it here, then check those conditions up there (_requestLineStatus and StatusCodes) here and make the appropriate trace call.

I might be missing something, but I don't see the need for the try/catch above and going through the whole thing with _requestProcessingStopping being false. You're ending the loop anyways, just let it throw.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍 👍

if (!Constants.ECONNRESET.HasValue)
{
_logger.LogWarning("Unable to determine ECONNRESET value on this platform.");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add new line after this block

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied the formatting directly from 1.0.0. You wrote that, right? 😝 I think having them together is fine since they're so closely related.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol

when I see two if blocks like that I sometimes mentally insert a non-existing else before the second if when reading the code.

But this is not really critical so you can leave it as is.

Assert.True(await connectionResetLogged.WaitAsync(_semaphoreWaitTimeout));

// Check the no log level higher than Debug was used for a reset before a request
Assert.True(testSink.MaxLogLevel <= LogLevel.Debug);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert equality here.

@@ -191,12 +192,12 @@ public Task RemoteIPv6Address()
}

[Fact]
public async Task ConnectionResetAbortsRequest()
public async Task ConnectionResetPriorToRequestIsLoggedQuietly()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...LoggedAsDebug is more precise

Assert.Contains("reset", testSink.ConnectionResetMessage);
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove extra blank line

Assert.All(waitAsyncResults, Assert.True);

// Check the no log level lower than Information was used for a reset mid-request
Assert.True(testSink.MaxLogLevel >= LogLevel.Information);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert equality.

catch (IOException ex)
{
// Silence ECONNRESET errors made between requests
if (_requestLineStatus == RequestLineStatus.Empty &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place requestLineStatus in an outer scope - better than making it a Frame member.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that we need to move TakeStartLine out of the while condition, or do assignment in the condition. Both seemd icky to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't C# allow while (... && (requestLineStatus = TakeStartLine(...)) != ...) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, but I don't like it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You dislike it more than a break in a catch block? :trollface:



[Fact]
public async Task ConnectionResetMidRequestIsLoggedLessQuietly()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...LoggedAsInformation

@halter73
Copy link
Member Author

halter73 commented Nov 5, 2016

Addressed pr feedback.

{
// Don't log ECONNRESET errors made between requests. Browsers like IE will reset connections regularly.
if (requestLineStatus != RequestLineStatus.Empty ||
((UvException)ex.InnerException).StatusCode != Constants.ECONNRESET.Value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check HasValue first

((UvException)ex.InnerException).StatusCode != Constants.ECONNRESET.Value)
{
Log.RequestProcessingError(ConnectionId, ex);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else Log.ConnectionReset?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already log that in Connection.OnRead. Part of this was getting rid of that double logging.

- Particularly between requests, connection resets aren't that abnormal.
@halter73 halter73 merged commit 0d55946 into dev Nov 5, 2016
@halter73 halter73 deleted the halter73/1176 branch November 5, 2016 04:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants