So deaktivieren Sie die vom ASP.NET-Kernframework durchgeführte Protokollierung

72

Wie deaktiviere ich die von ASP.NET für jede Anforderung durchgeführte Protokollierung, z

INFO 09:38:41 Benutzerprofil ist verfügbar. Verwenden von 'C: \ Users \ xxxx xxxx \ AppData \ Local \ ASP.NET \ DataProtection-Keys' als Schlüsselrepository und Windows DPAPI zum Verschlüsseln von Schlüsseln im Ruhezustand.
DEBUG 09:38:41 Hosting startet
DEBUG 09:38:41 Hosting gestartet
INFO 09:38:41 Anfrage startet HTTP / 1.1 GET http: // localhost: 23369 /
INFO 09:38:41 Anfrage startet HTTP / 1.1 DEBUG http: // localhost: 23369 / text / html DEBUG 09:38:41 DEBUG-Anforderungen werden nicht unterstützt
DEBUG 09:38:41 Der Anforderungspfad / stimmt nicht mit einem unterstützten Dateityp überein
DEBUG 09:38:41 Die Anforderung hat die Route erfolgreich mit dem Namen 'default' und der Vorlage '{controller = Home} / {action = Index} / {id?}' Abgestimmt. DEBUG 09:38:41 Die Anforderung hat die Route erfolgreich mit dem Namen 'default' und der Vorlage '{controller = Home} / {action = Index} / {id?}' Abgestimmt. DEBUG 09:38:41 Ausführen der Aktion Forums.Controllers.HomeController.Index
DEBUG 09:38:41 Ausführen der Aktion Forums.Controllers.HomeController.Index
INFO 09:38:41 Ausführen der Aktionsmethode Forums.Controllers.HomeController.Index mit Argumenten () - ModelState ist gültig '
INFO 09:38:41 Ausführen der Aktionsmethode Forums.Controllers.HomeController.Index
..

Ich konnte noch nicht finden, wie ich diese Abmeldung ausschalten kann ...

Dies ist meine ConfigureMethode in der StartupKlasse:

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?}");
    });
}

Und das ist meine project.json-Datei:

"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:
Mein log4net Provider wurde von hier übernommen

Gdoron unterstützt Monica
quelle
1
1. Wo genau befinden sich die Protokolle, die Sie deaktivieren möchten? 2. Wie wird Ihre Anwendung gehostet?
haim770
@ haim770, ich habe die erste Frage nicht verstanden. 2. IIS Express.
Gdoron unterstützt Monica
Sie registrieren sich explizit log4netals Ihr Protokollierungsanbieter. Sind es die log4netProtokolle, die Sie deaktivieren möchten? Ist es etwas, das Sie in der Konsole sehen? Möchten Sie einfach die Ablaufverfolgungsstufe ändern?
haim770
@haim, ich glaube nicht, dass es etwas mit log4net zu tun hat. Es ist ein Adapter, den ich geschrieben habe. Es hat keinen Zugriff auf die asp.net-Pipeline, was bedeutet, dass asp.net die Logger-Factory intern aufruft.
Gdoron unterstützt Monica
1
Sie haben nicht angegeben, wo Sie die Protokolle sehen / finden, die Sie deaktivieren möchten, daher musste ich davon ausgehen, dass sie log4netausgegeben werden. Auch hier , wo sehen Sie die DEBUG 09:38:41 Hosting startingLinie?
haim770

Antworten:

83

Ich bin nicht sicher, ob mir etwas fehlt, aber möchten Sie nicht einfach die Protokollstufe für die Microsoft-Protokolle erhöhen?

Bearbeiten appsettings.json(vorausgesetzt .AddJsonFile("appsettings.json", ...))

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "System": "Information",
      "Microsoft": "Information"

Zu

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "System": "Information",
      "Microsoft": "None"

Oder die gleiche Änderung über Umgebungsvariablen (vorausgesetzt .AddEnvironmentVariables())

Logging:LogLevel:Microsoft=None

Sie können auch genauer sein, das Folgende reduziert die meisten Einträge, lässt aber Microsoft.AspNetCore.Hosting.Internal.WebHostbei Information.

"Microsoft": "Information",  
"Microsoft.AspNetCore.Mvc.Internal": "Warning",
"Microsoft.AspNetCore.Authentication":  "Warning"

Entschuldigung, wenn dies nicht funktioniert log4net

KCD
quelle
8
Ich konnte dies nicht mit Serilog zum Laufen bringen, aber es funktionierte für die Konsolenprotokollierung, wenn die App in der Befehlszeile ausgeführt wurde (dh Dotnet-Ausführung).
Alyce
1
Diese Konfigurationsdatei wird leider nur zur Steuerung der Konsolenprotokollierung verwendet. loggerFactory.AddConsole(Configuration.GetSection("Logging"));
Scott
5
@Alyce Serilog bietet auch Filterung an: new LoggerConfiguration().Filter.ByExcluding(Matching.FromSource("Microsoft"))- Weitere Informationen finden Sie hier: stackoverflow.com/questions/38760381/…
Mani Gandham
3
Sie können auch überschreiben, sodass nur Ereignisse über einer bestimmten Ebene für eine bestimmte Quelle protokolliert werden, indem Sienew LoggerConfiguration().MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
Mani Gandham verwenden
2
Ooooooooh, dafür waren diese seltsamen "LogLevels" für Microsoft und System da ... das habe ich nicht bemerkt. Hervorragender Tipp.
Mike Gledhill
37

Was für mich wirklich funktioniert hat, war das Hinzufügen in die Startup.csDatei des ASP.NET Core 2.0-Projekts :

using Microsoft.Extensions.Logging;
public void ConfigureServices(IServiceCollection services)
{
    .
    .
    .

    services.AddLogging(
    builder =>
    {
        builder.AddFilter("Microsoft", LogLevel.Warning)
               .AddFilter("System", LogLevel.Warning)
               .AddFilter("NToastNotify", LogLevel.Warning)
               .AddConsole();
    });
}

Auf diese Weise erhalten Sie nur Protokolle der Warnstufe für die Protokollierung von Informationen, beginnend mit den an übergebenen Filtern builder.AddFilter .

Meine log4net.log-Datei zeigt jetzt nicht mehr die große Menge an INFOProtokollierungsspucken von Microsoft und anderen.

Weitere Informationen hier @ Microsoft Docs: Protokollfilterung

Leniel Maccaferri
quelle
4
Für Noobs wie mich hinzufügenusing Microsoft.Extensions.Logging;
DharmaTurtle
32

Wenn Sie Serilog für Ihre .NET Core-Protokollierung verwenden, können Sie Ihre Datei appsettings.json aktualisieren, um die Protokollebenen wie folgt festzulegen:

"Serilog": {
  "MinimumLevel": {
    "Default": "Verbose",
    "Override": {
      "Microsoft": "Error",
      "System": "Error"
    }
  },
  "Properties": {
    "Application": "your-app"
  }
}

Auf diese Weise können Sie nur Fehler von System / Microsoft protokollieren, während Sie alles andere nach Ihren Wünschen protokollieren.

Tony Ranieri
quelle
1
Das hat den Job für mich gemacht. Dankeschön.
Sunny Okoro Awa
7

Da die neue Protokollierungsinfrastruktur (von Entwurf) von asp.net selbst (sowie von anderem Herstellercode) verwendet wird, liegt es an der ILoggerProvider Implementierung entscheiden, ob diese Quelle protokolliert werden soll oder nicht.

Hier ist eine überarbeitete Implementierung log4net, die eine grundlegende Quellfilterung hinzufügt:

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)
        {
        }
    }
}

Und die 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);
}

Mögliche Verwendung (in Startup.cs):

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv, ILoggerFactory loggerFactory)
{
    appEnv.ConfigureLog4Net("log4net.xml");

    loggerFactory.AddLog4Net(x => !x.StartsWith("Microsoft."));
}
haim770
quelle
1
Ich kann hier nirgendwo die richtige Antwort finden, die richtige sollte sein: loggerFactory.WithFilter(new FilterLoggerSettings { { "Microsoft", LogLevel.Warning }, { "System", LogLevel.Warning }, { "MyOwnProject", LogLevel.Debug } }) .AddConsole(Configuration.GetSection("Logging")) .AddDebug();
Timeshift
5

In und vor ASP.NET 5 RC1 (jetzt ASP.NET Core 1.0) können Sie dies über die Logger-Factory tun, d. H.

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;
}

Mit dem aktuellen Zweig (noch nicht freigegeben, aber über nächtliche Builds verfügbar) wurde dieser jedoch entfernt. Jetzt müssen Sie die LogLevelpro Anbieter übergeben. In der Regel erfolgt dies über die Erweiterungsmethode.

Für den eingebauten Konsolenlogger wäre dies loggerFactory.AddConsole(minimumLevel: LogLevel.Warning);beispielsweise der Fall .

Da es sich bei Ihrem Logger-Anbieter um einen benutzerdefinierten Anbieter handelt, müssen Sie ihn selbst konfigurieren. Sehen Sie sich an, wie der Konsolenlogger das macht. Es übergibt einen Delegaten an den Anbieter, der die Filterung durchführt.

Aus GitHub Quelle :

public static ILoggerFactory AddConsole(
    this ILoggerFactory factory,
    LogLevel minLevel,
    bool includeScopes)
{
    factory.AddConsole((category, logLevel) => logLevel >= minLevel, includeScopes);
    return factory;
}

Anstatt einen Delegaten zu übergeben, können Sie natürlich auch direkt die Protokollstufe von log4net festlegen.

Update : Um das zu erweitern, worauf ich in den Kommentaren hingewiesen habe

Das ILoggerProviderist nur ein Wrapper um das tatsächliche Logging - Framework. Im einfachen Fall ConsoleLoggerProvidergibt es keinen Rahmen wie alles dahinter, nur einen einfachenConsole.WriteLine Aufruf.

Im Fall von log4net ist aus dem Beispiel ersichtlich, dass die Protokollierung pro Ebene aktiviert werden kann. Dies ist mit der oben beschriebenen .NET Core-Logger-Abstraktion nicht möglich, da die Abstraktion keine Filterung durchführt.

In einem log4net ILoggerProviderwürde man einfach alle Protokollebenen an die log4net-Netzbibliothek weiterleiten und sie filtern lassen.

Basierend auf dem verknüpften GitHub-Problem @ haim770, das erstellt wurde, haben Sie den SourceContext zum Filtern. Wenn log4net kein SourceContext-Konzept hat, müssen Sie dies im Anbieter implementieren. Wenn es ein Konzept von SourceContext hat, muss der Anbieter es umleiten / in die Struktur übersetzen, die log4net erwartet.

Wie Sie sehen, kennt der Logger selbst interne Details und Implementierungsdetails von ASP.NET immer nicht. Das Log4NetProviderkann und soll nicht, denn es ist die Aufgabe, diese API zu übersetzen. Anbieter sind nur Abstraktionen, sodass wir beispielsweise keine Implementierungsdetails in eine Bibliothek verlieren müssen.

Tseng
quelle
Das ist nicht was ich will. Ich möchte die Protokollierungsstufe in meiner Anwendung nicht global ändern, sondern nur die ASP.NET-Protokollierung deaktivieren, die über meinen Provider getunnelt wird. Ich habe mich tief in den Quellcode vertieft, es ist keine triviale Aufgabe, ich bin unglücklich :(
Gdoron unterstützt Monica
@gdoron: Alle Protokollierungsanforderungen werden an alle registrierten gesendet ILoggingProvider. Es ist die Aufgabe des Anbieters / Loggers, die Filterung der Protokollebene durchzuführen. Aus diesem Grund MinimumLevelwurde entfernt und das Jetzt kann nur auf Anbieterebene eingestellt werden
Tseng
Ich verstehe, dass alle Logger alle Logging-Anfragen erhalten sollten. Ich verstehe nur nicht, warum es keine Möglichkeit gibt, die ASP.NET-Protokollierung selbst auf eine bestimmte Ebene zu setzen. Warum muss mein Protokollierungsanbieter alle Komponenten kennen, für mich scheint es ein schlechtes Design zu sein.
Gdoron unterstützt Monica
@gdoron: Weil es in der Verantwortung des Anbieters liegt. Eine Anwendung kann mehr als einen Anbieter haben. Eine globale Einstellung ist möglicherweise nicht sinnvoll. Beispielsweise haben Sie möglicherweise eine ConsoleLoggerEntwicklungsversion, in der Sie alle Informationen, einschließlich "Trace" - und "Debug" -Ebene, haben möchten. Auf der anderen Seite möchten Sie möglicherweise eine Dateiprotokollierung, die nur Fehler und kritische Punkte protokolliert. ASP.NET Core ist sehr flexibel und lässt sich aus diesem Grund leicht hinzufügen oder entfernen. Alles, was Sie tun müssen, ist, Ihren Logger auf Warnstufe oder höher einzustellen, dann werden Debug-, Informations- und Trace-Stufe nicht protokolliert
Tseng
Außerdem muss Ihr Logger-Anbieter keine Komponenten kennen, sondern nur die Debug-Ebene, da dies dem Logger mitteilt, welche Art von Nachrichten er protokollieren soll und welche nicht.
Tseng
2

Das Festlegen von Logging.LogLevel appsettings.jsonfür den Schlüssel Microsoftwar nicht ausreichend. Ich musste die folgenden Tasten speziell einstellen, zB:

"Microsoft.Hosting.Lifetime": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning",
"Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware": "Warning"

Aber als Alternative hat die Verwendung eines Schlüssels mit einem Platzhalter zB Microsoft.*funktioniert. Also endete ich mit:

{
  "Logging": {
    "LogLevel": {
      "Default":     "Warning",
      "Microsoft.*": "Warning" 
  }
  ...
}
Isapir
quelle
2

In ASP.NET Core Version 3 können Sie die vorhandenen Protokollanbieter in der Funktion ConfigureServices löschen:

public void ConfigureServices(IServiceCollection services) {
    //Do everything else...
    services.AddLogging(c => c.ClearProviders());
}
Casey
quelle
Das hat bei mir nicht funktioniert. Der ASP.NET-Kern protokollierte immer noch: '(
rdelgado-incinc