Dapatkah Anda mengkonfigurasi log4net dalam kode daripada menggunakan file konfigurasi?

137

Saya mengerti mengapa log4net menggunakan app.configfile untuk mengatur logging - sehingga Anda dapat dengan mudah mengubah cara informasi dicatat tanpa perlu mengkompilasi ulang kode Anda. Tetapi dalam kasus saya, saya tidak ingin mengemas app.configfile dengan file yang dapat dieksekusi. Dan saya tidak ingin mengubah pengaturan logging saya.

Apakah ada cara bagi saya untuk menyiapkan kode masuk daripada menggunakan app.config?

Ini file konfigurasi sederhana saya:

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

EDIT:

Untuk lebih jelasnya: Ini adalah tujuan saya untuk tidak memiliki file XML. Bahkan tidak sebagai sumber daya yang saya ubah menjadi aliran. Tujuan saya adalah untuk mendefinisikan logger sepenuhnya secara terprogram. Hanya ingin tahu apakah itu mungkin dan jika demikian di mana saya dapat menemukan contoh sintaks.

Michael Mankus
sumber

Jawaban:

225

SOLUSI AKHIR: 1

Bagi siapa pun yang mungkin tersandung pada hal ini di masa depan, inilah yang saya lakukan. Saya membuat kelas statis di bawah ini:

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

Dan kemudian yang harus saya lakukan adalah mengganti kode tempat saya memanggil file XML dengan panggilan berikut:

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

1 (jawaban ini diedit menjadi pertanyaan oleh OP, saya mengambil kebebasan untuk menjadikannya jawaban komunitas, lihat di sini mengapa )

Philipp M
sumber
2
Sebagai catatan jika Anda menggunakan variabel dalam string roller.File Anda, Anda dapat menggunakan kelas log4net.Util.PatternString untuk memformatnya sebelum menetapkan hasilnya ke foller.File.
Eric Scherrer
1
Saya akhirnya mendapatkan entri log duplikat menggunakan metode ini. Saya menyelesaikannya dengan menambahkan "hierarchy.Root.RemoveAllAppenders ();" ke awal Setup ().
Philip Bergström
5
Dari semua ini, bagaimana cara mendapatkan ILog?
Mickey Perlstein
3
Tidak berfungsi untuk saya kecuali saya menelepon, BasicConfigurator.Configure(hierarchy);bukan hanya menyetel hierarchy.Configured = true;.
Eivind Gussiås Løkseth
3
Pastikan proses yang Anda harapkan untuk menulis ke file log memiliki izin menulis di folder yang Anda inginkan untuk menulis file log. Untuk mendiagnosis masalah log4net tambahkan log4net.Util.LogLog.InternalDebugging = true;sebelum panggilan log4net lainnya, kemudian jalankan di bawah debugger dan periksa outputnya. log4net akan memberi tahu Anda di mana ada yang salah.
Manfred
12

Anda juga dapat keluar dari XML sepenuhnya, saya menulis contoh dengan konfigurasi program yang minimal di sini .

Singkatnya, inilah yang Anda butuhkan

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;
oleksii
sumber
7
untuk apa kelas Hierarki?
pengguna20358
11

Ya, Anda dapat mengkonfigurasi log4net dengan menelepon:

log4net.Config.XmlConfigurator.Configure(XmlElement element)

Lihat dokumentasi log4net .

Joe
sumber
Tautan sekarang mati
Toby Smith
@TobySmith - diperbaiki.
Joe
4

Atau Anda dapat membuat atribut khusus yang mewarisi dari log4net.Config.ConfiguratorAttribute dan kode keras yang Anda konfigurasikan di sana:

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

Kemudian tambahkan yang berikut ini ke file .cs:

[assembly: ConsoleApplication1.MyConfigurator]
Jas
sumber
1

Bagi mereka yang tidak ingin menambahkan appender ke Root logger, tetapi ke logger saat ini / lainnya:

//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);
Vladislav Kostenko
sumber
0

Jawaban yang diterima berfungsi setelah saya menemukan dua peringatan:

  • Awalnya tidak berhasil bagi saya, tetapi setelah menggunakan jalur absolut penuh untuk roller.Fileproperti itu, properti itu mulai berfungsi.
  • Saya harus menggunakan ini di F # (dalam skrip fsx), jadi mengalami beberapa masalah saat mengonversinya dari C #. Jika Anda tertarik dengan hasil akhirnya (termasuk cara untuk mendownload paket nuget log4net), lihat di bawah ini:

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"))
ympostor
sumber