// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Concurrent; using System.Threading.Tasks; using System.Linq; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Testing { public class TestApplicationErrorLogger : ILogger { // Application errors are logged using 13 as the eventId. private const int ApplicationErrorEventId = 13; private TaskCompletionSource _messageLoggedTcs = new TaskCompletionSource(); public bool ThrowOnCriticalErrors { get; set; } = true; public ConcurrentBag Messages { get; } = new ConcurrentBag(); public int TotalErrorsLogged => Messages.Count(message => message.LogLevel == LogLevel.Error); public int CriticalErrorsLogged => Messages.Count(message => message.LogLevel == LogLevel.Critical); public int ApplicationErrorsLogged => Messages.Count(message => message.EventId.Id == ApplicationErrorEventId); public Task MessageLoggedTask => _messageLoggedTcs.Task; public IDisposable BeginScope(TState state) { return new Disposable(() => { }); } public bool IsEnabled(LogLevel logLevel) { return true; } public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { #if true if (logLevel == LogLevel.Critical && ThrowOnCriticalErrors) #endif { Console.WriteLine($"Log {logLevel}[{eventId}]: {formatter(state, exception)} {exception?.Message}"); if (logLevel == LogLevel.Critical && ThrowOnCriticalErrors) { throw new Exception("Unexpected critical error.", exception); } } Messages.Add(new LogMessage { LogLevel = logLevel, EventId = eventId, Exception = exception, Message = formatter(state, exception) }); _messageLoggedTcs.TrySetResult(null); } public class LogMessage { public LogLevel LogLevel { get; set; } public EventId EventId { get; set; } public Exception Exception { get; set; } public string Message { get; set; } } } }