From 7bd30ea693df64ae75271a256c08b2b968239bf3 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Thu, 18 Aug 2016 10:42:01 -0700 Subject: [PATCH] Log all startup errors in KestrelServer --- .../KestrelServer.cs | 21 +++++---- .../KestrelServerTests.cs | 46 ++++++++++++++++--- .../TestHelpers/TestApplicationErrorLogger.cs | 7 +++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs index 09ddb1a6b5..0bf4baf9c9 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel/KestrelServer.cs @@ -56,17 +56,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel public void Start(IHttpApplication application) { - ValidateOptions(); - - if (_disposables != null) - { - // The server has already started and/or has not been cleaned up yet - throw new InvalidOperationException("Server has already started."); - } - _disposables = new Stack(); - try { + ValidateOptions(); + + if (_disposables != null) + { + // The server has already started and/or has not been cleaned up yet + throw new InvalidOperationException("Server has already started."); + } + _disposables = new Stack(); + var dateHeaderValueManager = new DateHeaderValueManager(); var trace = new KestrelTrace(_logger); var engine = new KestrelEngine(new ServiceContext @@ -180,8 +180,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel throw new InvalidOperationException("No recognized listening addresses were configured."); } } - catch + catch (Exception ex) { + _logger.LogCritical(0, ex, "Unable to start Kestrel."); Dispose(); throw; } diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs index d14df869a1..b93e4a0450 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/KestrelServerTests.cs @@ -21,32 +21,38 @@ namespace Microsoft.AspNetCore.Server.KestrelTests [InlineData(-1337)] public void StartWithNonPositiveThreadCountThrows(int threadCount) { - var server = CreateServer(new KestrelServerOptions() { ThreadCount = threadCount }); + var testLogger = new TestApplicationErrorLogger(); + var server = CreateServer(new KestrelServerOptions() { ThreadCount = threadCount }, testLogger); var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Equal("threadCount", exception.ParamName); + Assert.Equal(1, testLogger.CriticalErrorsLogged); } [Fact] public void StartWithInvalidAddressThrows() { - var server = CreateServer(new KestrelServerOptions()); + var testLogger = new TestApplicationErrorLogger(); + var server = CreateServer(new KestrelServerOptions(), testLogger); server.Features.Get().Addresses.Add("http:/asdf"); var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Contains("Invalid URL", exception.Message); + Assert.Equal(1, testLogger.CriticalErrorsLogged); } [Fact] public void StartWithEmptyAddressesThrows() { - var server = CreateServer(new KestrelServerOptions()); + var testLogger = new TestApplicationErrorLogger(); + var server = CreateServer(new KestrelServerOptions(), testLogger); var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Equal("No recognized listening addresses were configured.", exception.Message); + Assert.Equal(1, testLogger.CriticalErrorsLogged); } [Theory] @@ -54,30 +60,56 @@ namespace Microsoft.AspNetCore.Server.KestrelTests [InlineData(int.MaxValue - 1, int.MaxValue)] public void StartWithMaxRequestBufferSizeLessThanMaxRequestLineSizeThrows(long maxRequestBufferSize, int maxRequestLineSize) { + var testLogger = new TestApplicationErrorLogger(); var options = new KestrelServerOptions(); options.Limits.MaxRequestBufferSize = maxRequestBufferSize; options.Limits.MaxRequestLineSize = maxRequestLineSize; - var server = CreateServer(options); + var server = CreateServer(options, testLogger); var exception = Assert.Throws(() => StartDummyApplication(server)); Assert.Equal( $"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).", exception.Message); + Assert.Equal(1, testLogger.CriticalErrorsLogged); } - private static KestrelServer CreateServer(KestrelServerOptions options) + private static KestrelServer CreateServer(KestrelServerOptions options, ILogger testLogger) { var lifetime = new LifetimeNotImplemented(); - var logger = new LoggerFactory(); - return new KestrelServer(Options.Create(options), lifetime, logger); + return new KestrelServer(Options.Create(options), lifetime, new TestLoggerFactory(testLogger)); } private static void StartDummyApplication(IServer server) { server.Start(new DummyApplication(context => TaskUtilities.CompletedTask)); } + + private class TestLoggerFactory : ILoggerFactory + { + private readonly ILogger _testLogger; + + public TestLoggerFactory(ILogger testLogger) + { + _testLogger = testLogger; + } + + public ILogger CreateLogger(string categoryName) + { + return _testLogger; + } + + public void AddProvider(ILoggerProvider provider) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + throw new NotImplementedException(); + } + } } } diff --git a/test/Microsoft.AspNetCore.Server.KestrelTests/TestHelpers/TestApplicationErrorLogger.cs b/test/Microsoft.AspNetCore.Server.KestrelTests/TestHelpers/TestApplicationErrorLogger.cs index 2534de82da..419a617407 100644 --- a/test/Microsoft.AspNetCore.Server.KestrelTests/TestHelpers/TestApplicationErrorLogger.cs +++ b/test/Microsoft.AspNetCore.Server.KestrelTests/TestHelpers/TestApplicationErrorLogger.cs @@ -15,6 +15,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests public int TotalErrorsLogged { get; set; } + public int CriticalErrorsLogged { get; set; } + public int ApplicationErrorsLogged { get; set; } public IDisposable BeginScope(TState state) @@ -42,6 +44,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests { TotalErrorsLogged++; } + + if (logLevel == LogLevel.Critical) + { + CriticalErrorsLogged++; + } } } }