Come posso ottenere un metodo di supporto in una classe di utilità per utilizzare il logger dei chiamanti in log4net?
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
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. :)