it-swarm.com.de

Können Sie log4net im Code konfigurieren, anstatt eine Konfigurationsdatei zu verwenden?

Ich verstehe, warum log4net app.config-Dateien zum Einrichten der Protokollierung verwendet - Sie können also problemlos ändern, wie Informationen protokolliert werden, ohne Ihren Code neu kompilieren zu müssen. In meinem Fall möchte ich jedoch keine app.config-Datei mit meiner ausführbaren Datei packen. Und ich habe keine Lust, meine Logging-Einstellungen zu ändern.

Gibt es eine Möglichkeit für mich, das Anmelden in Code einzurichten, anstatt den app.config zu verwenden?

Hier ist meine einfache Konfigurationsdatei:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="Logs\EventLog.txt" />
      <appendToFile value="false" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="1GB" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
      </layout>
    </appender>
    <appender name="MemoryAppender" type="log4net.Appender.MemoryAppender">
    </appender>
    <root>
      <level value="Info" />
      <appender-ref ref="RollingLogFileAppender" />
      <appender-ref ref="MemoryAppender" />
    </root>
  </log4net>
</configuration>

BEARBEITEN:

Um es ganz klar zu sagen: Es ist mein Ziel, keine XML-Datei zu haben. Nicht einmal als eingebettete Ressource, die ich in einen Stream verwandeln kann. Mein Ziel war es, den Logger vollständig programmgesteuert zu definieren. Nur neugierig, ob es möglich ist und wenn ja, wo ich ein Beispiel für die Syntax finden könnte.

110
Michael Mankus

ENDGÜLTIGE LÖSUNG:1

Für jeden, der in Zukunft darauf stoßen könnte, habe ich folgendes getan. Ich habe die statische Klasse gemacht:

using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;

namespace Spectrum.Logging
{
    public class Logger
    {
        public static void Setup()
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
            patternLayout.ActivateOptions();

            RollingFileAppender roller = new RollingFileAppender();
            roller.AppendToFile = false;
            roller.File = @"Logs\EventLog.txt";
            roller.Layout = patternLayout;
            roller.MaxSizeRollBackups = 5;
            roller.MaximumFileSize = "1GB";
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.StaticLogFileName = true;            
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            MemoryAppender memory = new MemoryAppender();
            memory.ActivateOptions();
            hierarchy.Root.AddAppender(memory);

            hierarchy.Root.Level = Level.Info;
            hierarchy.Configured = true;
        }
    }
}

Und dann musste ich nur den Code, in dem ich die XML-Datei aufgerufen habe, durch den folgenden Aufruf ersetzen:

//XmlConfigurator.Configure(new FileInfo("app.config")); // Not needed anymore
Logger.Setup();

1(Diese Antwort wurde vom OP in die Frage eingearbeitet, ich habe mir die Freiheit genommen, sie zu einer Community-Antwort zu machen, siehe hier, warum )

196
Philipp M

Sie können XML auch komplett entkommen, ich habe ein Beispiel mit minimaler programmatischer Konfiguration geschrieben hier .

Kurz gesagt, hier ist was Sie brauchen

var tracer = new TraceAppender();
var hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Root.AddAppender(tracer);
var patternLayout = new PatternLayout {ConversionPattern = "%m%n"};
patternLayout.ActivateOptions();
tracer.Layout = patternLayout;
hierarchy.Configured = true;
12
oleksii

Ja, Sie können log4net konfigurieren, indem Sie Folgendes aufrufen:

log4net.Config.XmlConfigurator.Configure(XmlElement element)

Siehe die log4net-Dokumentation .

10
Joe

Alternativ können Sie ein benutzerdefiniertes Attribut erstellen, das von log4net.Config.ConfiguratorAttribute erbt und Ihre Konfiguration dort fest einfügt:

using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
using log4net.Repository;
using log4net.Repository.Hierarchy;
using System;
using System.Reflection;

namespace ConsoleApplication1
{
    [AttributeUsage(AttributeTargets.Assembly)]
    public class MyConfiguratorAttribute : ConfiguratorAttribute
    {
        public MyConfiguratorAttribute()
            : base(0)
        {
        }

        public override void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository)
        {
            var hierarchy = (Hierarchy)targetRepository;
            var patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline";
            patternLayout.ActivateOptions();

            var roller = new RollingFileAppender();
            roller.AppendToFile = false;
            roller.File = @"Logs\EventLog.txt";
            roller.Layout = patternLayout;
            roller.MaxSizeRollBackups = 5;
            roller.MaximumFileSize = "1GB";
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.StaticLogFileName = true;
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            hierarchy.Root.Level = Level.Info;
            hierarchy.Configured = true;
        }
    }
}

Fügen Sie dann einer .cs-Datei Folgendes hinzu:

[Assembly: ConsoleApplication1.MyConfigurator]
3
Jas

Die akzeptierte Antwort funktioniert, nachdem ich zwei Vorbehalte gefunden habe:

  • Anfangs funktionierte es nicht für mich, aber nachdem ich einen vollständigen absoluten Pfad für die roller.File-Eigenschaft verwendet hatte, begann die Arbeit.
  • Ich musste dies in F # verwenden (in einem Fsx-Skript), daher gab es einige Probleme beim Konvertieren von C #. Wenn Sie am Endergebnis interessiert sind (einschließlich der Möglichkeit, das Paket log4net nuget herunterzuladen), lesen Sie unten:

nuget_log4net.fsx:

#!/usr/bin/env fsharpi

open System
open System.IO
open System.Net

#r "System.IO.Compression.FileSystem"
open System.IO.Compression

type DummyTypeForLog4Net () =
    do ()

module NetTools =

    let DownloadNuget (packageId: string, packageVersion: string) =
    use webClient = new WebClient()
    let fileName = sprintf "%s.%s.nupkg" packageId packageVersion

    let pathToUncompressTo = Path.Combine("packages", packageId)
    if (Directory.Exists(pathToUncompressTo)) then
        Directory.Delete(pathToUncompressTo, true)
    Directory.CreateDirectory(pathToUncompressTo) |> ignore
    let fileToDownload = Path.Combine(pathToUncompressTo, fileName)

    let nugetDownloadUri = Uri (sprintf "https://www.nuget.org/api/v2/package/%s/%s" packageId packageVersion)
    webClient.DownloadFile (nugetDownloadUri, fileToDownload)

    ZipFile.ExtractToDirectory(fileToDownload, pathToUncompressTo)

let packageId = "log4net"
let packageVersion = "2.0.5"
NetTools.DownloadNuget(packageId, packageVersion)

let currentDirectory = Directory.GetCurrentDirectory()

// https://stackoverflow.com/a/19538654/6503091
#r "packages/log4net/lib/net45-full/log4net"

open log4net
open log4net.Repository.Hierarchy
open log4net.Core
open log4net.Appender
open log4net.Layout
open log4net.Config

let patternLayout = PatternLayout()
patternLayout.ConversionPattern <- "%date [%thread] %-5level %logger - %message%newline";
patternLayout.ActivateOptions()

let roller = RollingFileAppender()
roller.AppendToFile <- true
roller.File <- Path.Combine(currentDirectory, "someLog.txt")
roller.Layout <- patternLayout
roller.MaxSizeRollBackups <- 5
roller.MaximumFileSize <- "1GB"
roller.RollingStyle <- RollingFileAppender.RollingMode.Size
roller.StaticLogFileName <- true
roller.ActivateOptions ()

let hierarchy = box (LogManager.GetRepository()) :?> Hierarchy
hierarchy.Root.AddAppender (roller)

hierarchy.Root.Level <- Level.Info
hierarchy.Configured <- true
BasicConfigurator.Configure(hierarchy)

let aType = typedefof<DummyTypeForLog4Net>
let logger = LogManager.GetLogger(aType)

logger.Error(new Exception("exception test"))
0
ympostor

Für diejenigen, die keinen Appender zum Root-Logger hinzufügen möchten, sondern zum aktuellen/anderen Logger:

//somewhere you've made a logger
var logger = LogManager.GetLogger("MyLogger");

// now add appender to it
var appender = BuildMyAppender();
((log4net.Repository.Hierarchy.Logger)logger).AddAppender(appender);

logger.Debug("MyLogger with MyAppender must work now");

// and remove it later if this code executed multiple times (loggers are cached, so you'll get logger with your appender attached next time "MyLogger")
((log4net.Repository.Hierarchy.Logger)logger).RemoveAppender(sbAppender);
0