Log all startup errors in KestrelServer
This commit is contained in:
parent
972be6e8c1
commit
7bd30ea693
|
|
@ -56,17 +56,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
|
|
||||||
public void Start<TContext>(IHttpApplication<TContext> application)
|
public void Start<TContext>(IHttpApplication<TContext> 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<IDisposable>();
|
|
||||||
|
|
||||||
try
|
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<IDisposable>();
|
||||||
|
|
||||||
var dateHeaderValueManager = new DateHeaderValueManager();
|
var dateHeaderValueManager = new DateHeaderValueManager();
|
||||||
var trace = new KestrelTrace(_logger);
|
var trace = new KestrelTrace(_logger);
|
||||||
var engine = new KestrelEngine(new ServiceContext
|
var engine = new KestrelEngine(new ServiceContext
|
||||||
|
|
@ -180,8 +180,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel
|
||||||
throw new InvalidOperationException("No recognized listening addresses were configured.");
|
throw new InvalidOperationException("No recognized listening addresses were configured.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_logger.LogCritical(0, ex, "Unable to start Kestrel.");
|
||||||
Dispose();
|
Dispose();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,32 +21,38 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
[InlineData(-1337)]
|
[InlineData(-1337)]
|
||||||
public void StartWithNonPositiveThreadCountThrows(int threadCount)
|
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<ArgumentOutOfRangeException>(() => StartDummyApplication(server));
|
var exception = Assert.Throws<ArgumentOutOfRangeException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
Assert.Equal("threadCount", exception.ParamName);
|
Assert.Equal("threadCount", exception.ParamName);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void StartWithInvalidAddressThrows()
|
public void StartWithInvalidAddressThrows()
|
||||||
{
|
{
|
||||||
var server = CreateServer(new KestrelServerOptions());
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
|
var server = CreateServer(new KestrelServerOptions(), testLogger);
|
||||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add("http:/asdf");
|
server.Features.Get<IServerAddressesFeature>().Addresses.Add("http:/asdf");
|
||||||
|
|
||||||
var exception = Assert.Throws<FormatException>(() => StartDummyApplication(server));
|
var exception = Assert.Throws<FormatException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
Assert.Contains("Invalid URL", exception.Message);
|
Assert.Contains("Invalid URL", exception.Message);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void StartWithEmptyAddressesThrows()
|
public void StartWithEmptyAddressesThrows()
|
||||||
{
|
{
|
||||||
var server = CreateServer(new KestrelServerOptions());
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
|
var server = CreateServer(new KestrelServerOptions(), testLogger);
|
||||||
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
Assert.Equal("No recognized listening addresses were configured.", exception.Message);
|
Assert.Equal("No recognized listening addresses were configured.", exception.Message);
|
||||||
|
Assert.Equal(1, testLogger.CriticalErrorsLogged);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -54,30 +60,56 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
[InlineData(int.MaxValue - 1, int.MaxValue)]
|
[InlineData(int.MaxValue - 1, int.MaxValue)]
|
||||||
public void StartWithMaxRequestBufferSizeLessThanMaxRequestLineSizeThrows(long maxRequestBufferSize, int maxRequestLineSize)
|
public void StartWithMaxRequestBufferSizeLessThanMaxRequestLineSizeThrows(long maxRequestBufferSize, int maxRequestLineSize)
|
||||||
{
|
{
|
||||||
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
var options = new KestrelServerOptions();
|
var options = new KestrelServerOptions();
|
||||||
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
options.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
||||||
options.Limits.MaxRequestLineSize = maxRequestLineSize;
|
options.Limits.MaxRequestLineSize = maxRequestLineSize;
|
||||||
|
|
||||||
var server = CreateServer(options);
|
var server = CreateServer(options, testLogger);
|
||||||
|
|
||||||
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
var exception = Assert.Throws<InvalidOperationException>(() => StartDummyApplication(server));
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).",
|
$"Maximum request buffer size ({maxRequestBufferSize}) must be greater than or equal to maximum request line size ({maxRequestLineSize}).",
|
||||||
exception.Message);
|
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 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)
|
private static void StartDummyApplication(IServer server)
|
||||||
{
|
{
|
||||||
server.Start(new DummyApplication(context => TaskUtilities.CompletedTask));
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
|
|
||||||
public int TotalErrorsLogged { get; set; }
|
public int TotalErrorsLogged { get; set; }
|
||||||
|
|
||||||
|
public int CriticalErrorsLogged { get; set; }
|
||||||
|
|
||||||
public int ApplicationErrorsLogged { get; set; }
|
public int ApplicationErrorsLogged { get; set; }
|
||||||
|
|
||||||
public IDisposable BeginScope<TState>(TState state)
|
public IDisposable BeginScope<TState>(TState state)
|
||||||
|
|
@ -42,6 +44,11 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
{
|
{
|
||||||
TotalErrorsLogged++;
|
TotalErrorsLogged++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (logLevel == LogLevel.Critical)
|
||||||
|
{
|
||||||
|
CriticalErrorsLogged++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue