Can you configure log4net in code instead of using a config file?

后端 未结 6 1128
日久生厌
日久生厌 2020-11-28 01:20

I understand why log4net uses app.config files for setting up logging - so you can easily change how information is logged without needing to recompile your cod

相关标签:
6条回答
  • 2020-11-28 01:31

    The accepted answer works after I found two caveats:

    • It was not working for me at first, but after using a full absolue path for the roller.File property, it started work.
    • I had to use this in F# (in a fsx script), so had some issues when converting it from C#. If you're interested in the end result (including a way to download log4net nuget package), see below:

    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 讨论(0)
  • 2020-11-28 01:35

    You can also escape XML completely, I wrote a sample with minimal programmatic configuration here.

    In a nutshell, here is what you need

    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;
    
    0 讨论(0)
  • 2020-11-28 01:38

    For those who don't want to add appender to Root logger, but to current/other 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 讨论(0)
  • 2020-11-28 01:40

    Yes, you can configure log4net by calling:

    log4net.Config.XmlConfigurator.Configure(XmlElement element)
    

    See the log4net documentation.

    0 讨论(0)
  • 2020-11-28 01:47

    Alternatively you could create a custom attribute that inherits from log4net.Config.ConfiguratorAttribute and hard-code you configuration there:

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

    Then add the following to a .cs file:

    [assembly: ConsoleApplication1.MyConfigurator]
    
    0 讨论(0)
  • 2020-11-28 01:50

    FINAL SOLUTION:1

    For anyone who may stumble upon this in the future, here is what I did. I made the static class below:

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

    And then all I had to do was replace the code where I called the XML file with the following call:

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

    1(this answer was edited into the question by the OP, I took the liberty to make it a community answer, see here why)

    0 讨论(0)
提交回复
热议问题