Как отключить ведение журнала, выполненное с помощью основной структуры ASP.NET
Как отключить ведение журнала, выполненное ASP.NET для каждого запроса, например.
INFO 09:38:41 Профиль пользователя доступен. Использование "C:\Users\xxxx xxxx\AppData\Local\ASP.NET\DataProtection-Keys" в качестве ключевого репозитория и Windows DPAPI для шифрования ключей в состоянии покоя.
DEBUG 09:38:41 Хостинг начиная с DEBUG 09:38:41 Хостинг начался
INFO 09:38:41 Запрос запуска HTTP/1.1 GET http://localhost:23369/
INFO 09:38:41 Запрос на запуск HTTP/1.1 DEBUG http://localhost:23369/ text/html DEBUG 09:38:41 Запросы DEBUG не поддерживаются
DEBUG 09:38:41 Путь запроса/не соответствует поддерживаемому типу файлов
DEBUG 09:38:41 Запрос успешно сопоставил маршрут с именем 'default' и template '{controller = Home}/{action = Index}/{id?}'. DEBUG 09:38:41 Запрос успешно сопоставил маршрут с именем 'default' и template '{controller = Home}/{action = Index}/{id?}'. DEBUG 09:38:41 Выполнение действий Forums.Controllers.HomeController.Index
DEBUG 09:38:41 Выполнение действий Forums.Controllers.HomeController.Index
INFO 09:38:41 Выполнение метода действий Forums.Controllers.HomeController.Index с аргументами() - ModelState is Valid '
INFO 09:38:41 Выполнение действия метода Forums.Controllers.HomeController.Index
..
Я еще не мог найти, как я могу отключить это отключение...
Это мой метод Configure
в классе Startup
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddProvider(new Log4NetProvider());
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
try
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
.Database.Migrate();
}
}
catch { }
}
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());
app.UseStaticFiles();
app.UseIdentity();
// To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
И это мой файл project.json:
"dependencies": {
"EntityFramework.Commands": "7.0.0-rc1-final",
"EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
"log4net": "2.0.5",
"Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final",
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
"Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel",
"ef": "EntityFramework.Commands"
},
"frameworks": {
"dnx451": { }
},
Update:
Мой провайдер log4net был взят здесь
Ответы
Ответ 1
Поскольку новая инфраструктура ведения журнала используется (по дизайну) самой asp.net(а также другим кодом поставщика), она выполняет реализацию ILoggerProvider
, чтобы решить, хочет ли он регистрировать этот источник или нет.
Здесь приведено исправление для log4net
, которое добавляет базовую фильтрацию источника:
public class Log4NetProvider : ILoggerProvider
{
private static readonly NoopLogger _noopLogger = new NoopLogger();
private readonly Func<string, bool> _sourceFilterFunc;
private readonly ConcurrentDictionary<string, Log4NetLogger> _loggers = new ConcurrentDictionary<string, Log4NetLogger>();
public Log4NetProvider(Func<string, bool> sourceFilterFunc = null)
{
_sourceFilterFunc = sourceFilterFunc != null ? sourceFilterFunc : x => true;
}
public ILogger CreateLogger(string name)
{
if (!_sourceFilterFunc(name))
return _noopLogger;
return _loggers.GetOrAdd(name, x => new Log4NetLogger(name));
}
public void Dispose()
{
_loggers.Clear();
}
private class NoopLogger : ILogger
{
public IDisposable BeginScopeImpl(object state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return false;
}
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
{
}
}
}
И Log4NetAspExtensions
:
public static void ConfigureLog4Net(this IApplicationEnvironment appEnv, string configFileRelativePath)
{
GlobalContext.Properties["appRoot"] = appEnv.ApplicationBasePath;
XmlConfigurator.Configure(new FileInfo(Path.Combine(appEnv.ApplicationBasePath, configFileRelativePath)));
}
public static void AddLog4Net(this ILoggerFactory loggerFactory, Func<string, bool> sourceFilterFunc = null)
{
loggerFactory.AddProvider(new Log4NetProvider(sourceFilterFunc));
}
public static void AddLog4Net(this ILoggerFactory loggerFactory)
{
loggerFactory.AddLog4Net(null);
}
Возможное использование (в Startup.cs
):
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv, ILoggerFactory loggerFactory)
{
appEnv.ConfigureLog4Net("log4net.xml");
loggerFactory.AddLog4Net(x => !x.StartsWith("Microsoft."));
}
Ответ 2
Я не уверен, что у меня что-то не хватает, но разве вы просто не хотите поднимать уровень журнала для журналов Microsoft?
Изменить appsettings.json
(принимает .AddJsonFile("appsettings.json", ...)
)
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "Information"
Для
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Information",
"Microsoft": "None"
Или такая же модификация через переменные среды (предполагается .AddEnvironmentVariables()
)
Logging:LogLevel:Microsoft=None
Вы также можете быть более конкретным, следующее сокращает большинство записей, но оставляет Microsoft.AspNetCore.Hosting.Internal.WebHost
в Information
.
"Microsoft": "Information",
"Microsoft.AspNetCore.Mvc.Internal": "Warning",
"Microsoft.AspNetCore.Authentication": "Warning"
Приложения, если это не работает для log4net
Ответ 3
В и перед ASP.NET 5 RC1 (теперь ASP.NET Core 1.0) вы можете сделать это через регистратор factory, т.е.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// completely disable logging or use one of the other levels, such as Error, Critical, Warning etc.
loggerFactory.MinimumLevel = LogLevel.None;
}
Однако, с текущей ветвью (еще не выпущенной, но доступной через ночные сборки), это было удалено. Теперь вам нужно передать LogLevel
для каждого провайдера. Обычно это делается с помощью метода расширения.
Для встроенного консольного регистратора это будет loggerFactory.AddConsole(minimumLevel: LogLevel.Warning);
, например.
Поскольку ваш поставщик журналов является настраиваемым, вам придется настроить его самостоятельно. Посмотрите, как это делает консольный регистратор. Он передает делегату поставщика, который выполняет фильтрацию.
От Источник GitHub:
public static ILoggerFactory AddConsole(
this ILoggerFactory factory,
LogLevel minLevel,
bool includeScopes)
{
factory.AddConsole((category, logLevel) => logLevel >= minLevel, includeScopes);
return factory;
}
Конечно, вместо передачи делегата вы также можете напрямую установить уровень журнала log4net.
Обновить. Чтобы расширить то, что я указал в комментариях
ILoggerProvider
- это только обертка вокруг реальной структуры ведения журнала. В простом случае ConsoleLoggerProvider
нет рамки, поскольку все позади нее, просто простой вызов Console.WriteLine
.
В случае log4net в примере видно, что ведение журнала может быть включено для каждого уровня. Это невозможно с абстракцией основного регистратора .NET Core, описанной выше, поскольку абстракция не выполняет фильтрацию.
В log4net ILoggerProvider
можно было бы просто маршрутизировать все уровни журнала в библиотеку сети log4net и фильтровать его.
Основываясь на связанной проблеме GitHub @haim770, у вас есть SourceContext для фильтрации, и если у log4net нет концепции SourceContext, вам придется реализовать это в провайдере. Если у него есть концепция SourceContext, поставщик должен перенаправить/перевести его в структуру, которую ожидает log4net.
Как вы можете видеть, сам журнал всегда остается не в курсе внутренних особенностей и деталей реализации ASP.NET. Log4NetProvider
не может и не должен, потому что задача состоит в том, чтобы перевести/обернуть вокруг этого api. Провайдеры - это просто абстракции, поэтому нам не нужно просачивать детали реализации в библиотеку, например.
Ответ 4
Если вы используете Serilog для ведения журнала .Net core, вы можете обновить файл appsettings.json, чтобы установить уровни журналов следующим образом:
"Serilog": {
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Error",
"System": "Error"
}
},
"Properties": {
"Application": "your-app"
}
}
Это позволяет вам регистрировать ошибки только в System/Microsoft при регистрации всего остального, как вам хотелось бы.