.NET Core 2.1 NLog 4.6 xUnit 2.3.1
У меня есть библиотека классов с xUnit, которая вызывает отдельную библиотеку с API-интерфейсами на основе REST, которая отвечает за создание различных журналов для системы.
Поскольку библиотека классов модульного тестирования напрямую вызывает контроллер API на основе REST, класс Startup класса не загружается, поэтому я не верю, что NLog настраивается.Это нужно будет сделать в библиотеке классов модульных тестов, но я не могу понять это.
Я могу загрузить конфигурацию nlog API на основе REST из вызывающей библиотеки и затем выполнить NLogs непосредственно из LogManager, но реализация NLog, явно используемая в API на основе REST, не регистрирует и не выдает никакой ошибки.,
Если я использую мыльный клиент, такой как SOAPUI, и вызываю библиотеку классов REST, журналы создаются, как ожидается.Это означает, что библиотека классов модульных тестов неправильно настраивает ведение журнала.
// Unit Test's base class for wiring up DI and other configuration including Logging
public BaseTests()
{
// Configuration
string loggingServiceAPIPath = @"../../../../../../LoggingService/API/CM.LoggingService.API";
var builder = new ConfigurationBuilder().SetBasePath(Path.GetFullPath(loggingServiceAPIPath)).AddJsonFile("appsettings.json");
var configuration = builder.Build();
// Configure logging
LogManager.Configuration = new XmlLoggingConfiguration(Path.GetFullPath($"{ loggingServiceAPIPath }/nlog.config"));
// Application-Wide Services
IServiceCollection services = new ServiceCollection();
services.AddMvc();
services.AddLogging();
services.AddSingleton(configuration);
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddSingleton<IMemoryCache, MemoryCache>();
services.AddSingleton<ILoggingServiceController, LoggingServiceController>();
services.AddApplicationServices();
services.AddOptions();
services.ConfigureConfigServerClientOptions(configuration);
services.AddConfiguration(configuration);
services.Configure<ConfigServerData>(configuration);
this._serviceProvider = services.BuildServiceProvider();
// Persist configuration
IMemoryCache iMemoryCache = this._serviceProvider.GetService<IMemoryCache>();
IOptionsSnapshot<ConfigServerData> iConfigServerData = this._serviceProvider.GetService<IOptionsSnapshot<ConfigServerData>>();
if (iMemoryCache != null && iConfigServerData != null) { iMemoryCache.Set(CM.Common.Constants.ConfigKey, iConfigServerData.Value); }
}
// Unit Test being called from a class library
[Fact]
public async void Test_LogDebugSuccess()
{
LoggingServiceRequest request = new LoggingServiceRequest
{
ErrorException = new Exception(),
Message = System.Reflection.MethodBase.GetCurrentMethod().Name
};
// This is not capturing NLog probably due to not being called in a hosted environment.
var result = await
this._iLoggingServiceController.LogDebug(request);
// Assert
Assert.Null(result as NotFoundObjectResult);
var okObjectResult = result as OkObjectResult;
Assert.True((okObjectResult != null &&
okObjectResult.StatusCode.GetValueOrDefault(0) == Convert.ToInt32(System.Net.HttpStatusCode.OK)), "Log was not created.");
}
// LoggingService
public class Program
{
/// <summary>
/// Main
/// </summary>
/// <param name="args">Arguments</param>
public static void Main(string[] args)
{
// NLog: setup the logger first to catch all errors
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Debug("Init Main");
Program.BuildWebHost(args).Run();
}
catch (Exception ex)
{
logger.Error(ex, $"Stopped program because of exception: { ex.Message }");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
/// <summary>
/// Build WebHost
/// </summary>
/// <param name="args">Arguments</param>
/// <returns>WebHost interface</returns>
public static IWebHost BuildWebHost(string[] args)
{
try
{
var config = WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(false)
.AddConfigServer()
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog() // NLog: setup NLog for Dependency injection
.Build();
return config;
}
catch (Exception ex)
{
throw ex;
}
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(
config =>
{
config.Filters.Add(typeof(CustomExceptionFilter));
}
);
// Add memory cache
services.AddMemoryCache();
services.AddMvc();
services.AddCors(o => o.AddPolicy("corspolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()));
services.AddSingleton(this.Configuration);
// Application-Wide Services
services.AddApplicationServices();
// Configuration
services.AddOptions();
services.ConfigureConfigServerClientOptions(this.Configuration);
services.AddConfiguration(this.Configuration);
services.Configure<ConfigServerData>(this.Configuration);
// Configure Swagger
services.AddSwaggerGen(s =>
{
s.SwaggerDoc("v1", new Info { Title = "CM LoggingService APIs", Version = "V1" });
});
}
public void Configure(IApplicationBuilder iApplicationBuilder, IHostingEnvironment iHostingEnvironment, IConfigurationManager iConfigurationManager, IMemoryCache iMemoryCache, IApplicationLifetime iApplicationLifetime, ILogger<LoggingServiceController> iLogger)
{
if (iHostingEnvironment.IsDevelopment() == true)
{
iApplicationBuilder.UseDeveloperExceptionPage();
iApplicationBuilder.UseStatusCodePages();
iApplicationBuilder.UseDatabaseErrorPage();
iApplicationBuilder.UseBrowserLink();
}
if (iHostingEnvironment.IsProduction() == false)
{
// Swagger - API Documentation
iApplicationBuilder.UseSwagger();
iApplicationBuilder.UseSwaggerUI(s =>
{
s.SwaggerEndpoint("./v1/swagger.json", "CM LoggingService APIs");
});
}
// Persist Steeltoe configuration
iConfigurationManager.Init();
if (iMemoryCache != null && iConfigurationManager != null) { iMemoryCache.Set(CM.Common.Constants.MEMORYCACHE_CONFIGURATIONMANAGER_KEY, iConfigurationManager); }
iConfigurationManager.LogConfiguration();
// Configure global exception handler
iApplicationBuilder.ConfigureExceptionHandler(iLogger);
iApplicationBuilder.UseMvc();
// Application Events
iApplicationLifetime.ApplicationStarted.Register(this.OnApplicationStarted);
iApplicationLifetime.ApplicationStopped.Register(this.OnApplicationStopping);
}
public class LoggingServiceController : Controller, ILoggingServiceController
{
private readonly ILogger<LoggingServiceController> _iLogger = null;
private readonly ILoggingServiceDomainController _iLoggingServiceDomainController = null;
public LoggingServiceController(ILogger<LoggingServiceController> iLogger, ILoggingServiceDomainController iLoggingServiceDomainController)
{
this._iLogger = iLogger;
this._iLoggingServiceDomainController = iLoggingServiceDomainController;
}
[HttpPost("LogError")]
public async Task<IActionResult> LogError([FromBody] LoggingServiceRequest request)
{
bool result = false;
try
{
// Validation
if (ModelState.IsValid == false)
{
this._iLogger.LogError($"{ CM.Common.ExceptionHandling.ExceptionTypes.VALIDATION }: { typeof(LoggingServiceRequest).Name } (request) is not valid.");
return BadRequest();
}
// Log
result = this._iLogger.LogError(request.ErrorException, request.Message, request.Args);
if (result == false) { return NotFound(); }
}
catch (Exception ex)
{
this._iLogger.LogError(ex, $"{ CM.Common.ExceptionHandling.ExceptionTypes.UNSPECIFIED }: { ex.Message }");
}
return Ok(result);
}
}