क्या आप कॉन्फ़िगर फ़ाइल का उपयोग करने के बजाय कोड में log4net को कॉन्फ़िगर कर सकते हैं?


136

मैं समझता हूं कि log4net app.configलॉगिंग सेट करने के लिए फ़ाइलों का उपयोग क्यों करता है - ताकि आप आसानी से बदल सकें कि आपके कोड को पुन: व्यवस्थित करने की आवश्यकता के बिना जानकारी कैसे लॉग की जाती है। लेकिन मेरे मामले में मैं app.configअपने निष्पादन योग्य के साथ एक फ़ाइल पैक नहीं करना चाहता । और मुझे अपने लॉगिंग सेटअप को संशोधित करने की कोई इच्छा नहीं है।

क्या मेरे लिए एक तरीका है कोड का उपयोग करने के बजाय लॉगिंग सेट अप करने के लिए app.config?

यहाँ मेरी सरल विन्यास फाइल है:

<?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>

संपादित करें:

पूरी तरह से स्पष्ट होने के लिए: कोई XML फ़ाइल नहीं होना मेरा लक्ष्य है। एक एम्बेडेड संसाधन के रूप में भी नहीं जो मैं एक धारा में बदल जाता हूं। मेरा लक्ष्य लकड़हारे को पूरी तरह से प्रोग्रामेटिक रूप से परिभाषित करना था। बस अगर यह संभव है और अगर मुझे वाक्यविन्यास का एक उदाहरण मिल सकता है तो उत्सुक।

जवाबों:


223

अंतिम समाधान: 1

भविष्य में जो कोई भी इस पर ठोकर खा सकता है, उसके लिए यहां मैंने वही किया है। मैंने नीचे स्थिर वर्ग बनाया:

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

और फिर मुझे केवल उस कोड को बदलना था जहां मैंने निम्नलिखित कॉल के साथ XML फ़ाइल को कॉल किया था:

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

1 (यह उत्तर ओपी द्वारा प्रश्न में संपादित किया गया था, मैंने इसे एक सामुदायिक उत्तर बनाने के लिए स्वतंत्रता ली, यहां देखें क्यों )


2
यदि आप अपने रोलर में वैरिएबल का उपयोग करते हैं तो एक नोट। फ़ाइल स्ट्रिंग आप परिणाम को असाइन करने से पहले इसे लॉग करने के लिए log4net.Util.PatternString क्लास का उपयोग कर सकते हैं।
एरिक स्परर

1
मैंने इस विधि का उपयोग करके डुप्लिकेट लॉग प्रविष्टियों को प्राप्त किया। मैंने इसे "hierarchy.Root.RemoveAllAppenders ();" जोड़कर हल किया सेटअप की शुरुआत () के लिए।
फिलिप बर्गस्ट्रॉम

4
इस सब से, मैं ILog कैसे प्राप्त करूं?
मिकी पेरेलस्टीन

3
मेरे लिए काम नहीं करता जब तक कि मैं BasicConfigurator.Configure(hierarchy);सिर्फ सेटिंग के बजाय कॉल नहीं करता hierarchy.Configured = true;
Eivind Gussiås Løkseth

3
सुनिश्चित करें कि आप लॉग फ़ाइल में लिखने की अपेक्षा करते हैं, उस प्रक्रिया को उस फ़ोल्डर में लिखने की अनुमति है जिसमें आप लॉग फ़ाइल को लिखना चाहते हैं। लॉग 4net समस्याओं का निदान करने के लिए log4net.Util.LogLog.InternalDebugging = true;किसी अन्य लॉग 4 एनटी कॉल से पहले जोड़ें , फिर डिबगर के तहत चलाएं और आउटपुट का निरीक्षण करें। log4net आपको बताएगा कि चीजें कहां गलत हैं।
मैनफ्रेड

12

आप एक्सएमएल से पूरी तरह से बच सकते हैं, मैंने यहां न्यूनतम प्रोग्रामेटिक कॉन्फ़िगरेशन के साथ एक नमूना लिखा ।

संक्षेप में, यहाँ वही है जो आपको चाहिए

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;

6
के लिए पदानुक्रम वर्ग क्या है?
user20358


4

वैकल्पिक रूप से आप एक कस्टम विशेषता बना सकते हैं जो log4net से विरासत में मिलती है। Config.ConfiguratorAttribute और हार्ड-कोड जिससे आप कॉन्फ़िगरेशन करते हैं:

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

फिर .cs फ़ाइल में निम्न जोड़ें:

[assembly: ConsoleApplication1.MyConfigurator]

1

उन लोगों के लिए जो रूट लकड़हारे के लिए परिशिष्ट नहीं जोड़ना चाहते हैं, लेकिन वर्तमान / अन्य लकड़हारा के लिए:

//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

मुझे दो कैविएट मिलने के बाद स्वीकृत उत्तर काम करता है:

  • यह मेरे लिए पहली बार काम नहीं कर रहा था, लेकिन roller.Fileसंपत्ति के लिए एक पूर्ण अनुपस्थित पथ का उपयोग करने के बाद , इसने काम शुरू कर दिया।
  • मुझे इसे F # (एक fsx स्क्रिप्ट में) का उपयोग करना था, इसलिए इसे C # से कनवर्ट करते समय कुछ समस्याएँ थीं। यदि आप अंतिम परिणाम में रुचि रखते हैं (log4net nuget पैकेज डाउनलोड करने का तरीका सहित), तो नीचे देखें:

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"))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.