Come posso ottenere un metodo di supporto in una classe di utilità per utilizzare il logger dei chiamanti in log4net?

StackOverflow https://stackoverflow.com/questions/228578

  •  04-07-2019
  •  | 
  •  

Domanda

Ho un eseguibile che a seconda dell'opzione della riga di comando fornita assomiglia a:

Program.cs -

namespace DiskSpaceReporting
{
    class Program
    {
        static void Main(string[] args)
        {
            if(args.Length == 1)
            {
                switch(args[0])
                {
                    case "-summarytotals":
                        SummaryDiskSpaceReporter.Run();
                        break;

                    case "-detailed":
                        DetailedDiskSpaceReporter.Run();
                        break;
                    //...other reporting types
                }



            }
        }
    }
}

SummaryDiskSpaceReporter.cs

namespace DiskSpaceReporting
{
    public class SummaryDiskSpaceReporter
    {
        private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static void Run()
        {
            log.Info(1234, "Starting");
            //...do work
            string message = Helpers.CreateMessage(messageID);
            //...do work
        }
    }
}

DetailedDiskSpaceReporter.cs

namespace DiskSpaceReporting
{
    public class DetailedDiskSpaceReporter
    {
        private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static void Run()
        {
            log.Info(1234, "Starting");
            //...do work
            string message = Helpers.CreateMessage(messageID);
            //...do work
        }
    }
}

Helpers.cs

namespace DiskSpaceReporting
{
    public class Helpers
    {
        private static IEventIDLog log = ???            
        public static string CreateMessage(Guid messageID)
        {
            log.Info(9876, "Starting");
            //...do work
        }
    }
}

Nella mia configurazione di log4net ho due logger separati, uno per ciascuno dei SummaryDiskSpaceReporter e dettagliateDiskSpaceReporter perché i loro requisiti di registrazione sono diversi:

<root>
    <level value="ALL" />
    <appender-ref ref="ConsoleLogAppender" />
    <appender-ref ref="EventLogAppender" />
</root>

<logger name="DiskSpaceReporting.SummaryDiskSpaceReporter">
    <appender-ref ref="SummaryDiskSpaceReporterRollingFileAppender"/>
</logger>

<logger name="DiskSpaceReporting.DetailedDiskSpaceReporter">
    <appender-ref ref="DetailedDiskSpaceReporterRollingFileAppender"/>
</logger>

Sia SummaryDiskSpaceReporter che DetailDiskSpaceReporter chiamano un metodo helper in una classe chiamata Helpers. Voglio mettere un po 'di registrazione nei metodi della classe helper.

Quindi ... la domanda è: come posso ottenere il metodo Helpers.CreateMessage () per utilizzare lo stesso logger del suo chiamante?

vale a dire.

  

SummaryDiskSpaceReporter.Run () - > uso   DiskSpaceReporting.SummaryDiskSpaceReporter   logger DettagliatoDiskSpaceReporter.Run ()   - > usa DiskSpaceReporting.DetailedDiskSpaceReporter   logger.

Saluti Kev

È stato utile?

Soluzione

Gioco a questa domanda da un po 'di tempo e purtroppo devo rinunciare per un po' e tornare a fare "reale". lavoro. Per il momento quello che ho escogitato è il seguente:

Opzioni 1: passa il logger in

Questa non è un'ottima opzione, ma dovrebbe funzionare bene se non ti dispiace accoppiare il tuo aiutante a un logger. Consenti semplicemente al tuo metodo CreateMessage di acquisire un IEventIDLog. Puoi quindi usarlo per accedere al logger passato correttamente.

public static string CreateMessage(Guid messageID, IEventIDLog log)
{
    log.Info(9876, "Starting");
    //...do work
}

Non esattamente brillante, ma dovrebbe funzionare!

Opzioni 2: utilizza lo stack di chiamate

Usa lo stack di chiamate per trovare il codice chiamante e da questo trova il tipo e ottieni il logger che desideri da quel tipo

public static string CreateMessage(Guid messageID)
{
    StackFrame frame = new StackTrace().GetFrame(1);
    IEventIDLog log = EventIDLogManager.GetLogger(frame.GetMethod().DeclaringType);
    log.Info(9876, "Starting");
    //...do work
}

Ancora non brillante poiché dobbiamo toccare lo stack di chiamate e cosa succede se il codice chiamante non ha un logger.

Opzione 3: usa log4net

Questa è l'opzione che vogliamo usare, diavolo è quello che la domanda vuole come risposta, ma non l'ho ancora capito yet . :) Guardando attraverso log4net troviamo cose interessanti come la classe Hierarchy che ci consente di ottenere il logger di root.

Logger logger1 = ((log4net.Repository.Hierarchy.Hierarchy) log4net.LogManager.GetRepository()).Root;

Quindi sono sicuro che esiste un modo per far salire di livello il logger dal metodo CreateMessage, ora solo per trovarlo. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top