Для отладки основного приложения .net, которое не работает при запуске, я хотел бы написать журналы из файла startup.cs. У меня есть настройка ведения журнала в файле, который можно использовать в остальной части приложения вне файла startup.cs, но не уверен, как записывать журналы из самого файла startup.cs.
Как записывать журналы из Startup.cs
Ответ 1
Это значительно изменилось с выпуском ASP.NET Core 2.0. В ASP.NET Core 2.x ведение журнала создается в компоновщике хоста. Это означает, что протоколирование доступно через DI по умолчанию и может быть внедрено в класс Startup
:
public class Startup
{
private readonly ILogger<Startup> _logger;
public IConfiguration Configuration { get; }
public Startup(ILogger<Startup> logger, IConfiguration configuration)
{
_logger = logger;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
_logger.LogInformation("ConfigureServices called");
// …
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
_logger.LogInformation("Configure called");
// …
}
}
К сожалению, для ASP.NET Core 3.0 ситуация снова несколько иная. В шаблонах по умолчанию используется HostBuilder
(вместо WebHostBuilder
), который устанавливает новый универсальный хост, который может размещать множество различных приложений, не ограничиваясь веб-приложениями. Частью этого нового хоста также является удаление второго контейнера внедрения зависимостей, который ранее существовал для веб-хоста. В конечном итоге это означает, что вы не сможете внедрить любые зависимости, кроме IConfiguration
в класс Startup
. Таким образом, вы не сможете войти во время метода ConfigureServices
. Однако вы можете добавить регистратор в метод Configure
и войти туда:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
{
logger.LogInformation("Configure called");
// …
}
Если вам абсолютно необходимо войти в ConfigureServices
, то вы можете продолжать использовать WebHostBuilder
который создаст устаревший WebHost
который может внедрить регистратор в класс Startup
. Обратите внимание, что вполне вероятно, что веб-хостинг будет удален в будущем. Таким образом, вы должны попытаться найти решение, которое работает для вас без входа в ConfigureServices
.
Ответ 2
Вариант 1: Непосредственно используйте журнал (например, Serilog) при запуске -
public class Startup
{
public Startup(IHostingEnvironment env)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "Serilog-{Date}.txt"))
.CreateLogger();
Log.Information("Inside Startup ctor");
....
}
public void ConfigureServices(IServiceCollection services)
{
Log.Information("ConfigureServices");
....
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
Log.Information("Configure");
....
}
Вывод:
Чтобы настроить Serilog в приложении asp.net-core, проверьте пакет Serilog.AspNetCore на GitHub.
Вариант 2: Настроить ведение журнала в program.cs как это -
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(s => {
s.AddSingleton<IFormatter, LowercaseFormatter>();
})
.ConfigureLogging(f => f.AddConsole(LogLevel.Debug))
.UseStartup<Startup>()
.Build();
host.Run();
Пользователь loggerFactory при запуске, как это -
public class Startup
{
ILogger _logger;
IFormatter _formatter;
public Startup(ILoggerFactory loggerFactory, IFormatter formatter)
{
_logger = loggerFactory.CreateLogger<Startup>();
_formatter = formatter;
}
public void ConfigureServices(IServiceCollection services)
{
_logger.LogDebug($"Total Services Initially: {services.Count}");
// register services
//services.AddSingleton<IFoo, Foo>();
}
public void Configure(IApplicationBuilder app, IFormatter formatter)
{
// note: can request IFormatter here as well as via constructor
_logger.LogDebug("Configure() started...");
app.Run(async (context) => await context.Response.WriteAsync(_formatter.Format("Hi!")));
_logger.LogDebug("Configure() complete.");
}
}
Подробная информация доступна на этой ссылке
Ответ 3
Мне удалось это сделать, статически создав в нем регистратор с Nlog, а затем используйте его в методах запуска.
private readonly NLog.Logger _logger = new NLog.LogFactory().GetCurrentClassLogger();
Ответ 4
Основной код:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
CreateDefaultBuilder устанавливает консольный логгер по умолчанию.
... настраивает ILoggerFactory для входа в консоль и отладки вывода
Код запуска:
using Microsoft.Extensions.Logging;
...
public class Startup
{
private readonly ILogger _logger;
public Startup(IConfiguration configuration, ILoggerFactory logFactory)
{
_logger = logFactory.CreateLogger<Startup>();
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
_logger.LogInformation("hello stackoverflow");
}
Я не мог заставить работать ILogger, но, возможно, потому, что это не контроллер. Больше информации добро пожаловать!
Refs: