2012-09-08 15 views
7

Sto provando a scrivere un codice C#, che recupera in runtime il pattern del nome di un file di registro log4net tramite log4net API.Come ottenere un modello di nome del file di log log4net a livello di programmazione?

Cioè, se in log4net.config il seguente appender è definito:

<appender name="MyAppender" type="log4net.Appender.RollingFileAppender"> 
    <file type="log4net.Util.PatternString" value="%date{yyyy}\%date{MM}\%date{dd}\%property{Id}.log" /> 
    <appendToFile value="true" /> 
    <rollingStyle value="Size" /> 
    <maxSizeRollBackups value="16" /> 
    <maximumFileSize value="1MB" /> 
    <staticLogFileName value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%message%newline" /> 
    </layout> 
</appender> 

Vorrei ottenere data% {} aaaa Data \% {MM} data \% {dd} \% property {Id} .log in una variabile stringa in codice (senza analisi log4net.config come un semplice XML).

Qualcuno ha un'idea per fare questo trucco?

Grazie in anticipo.

risposta

2

Il valore per questo modello sarà nella proprietà File di un'istanza FileAppender che fa parte del repository di registrazione.

Ottenere l'appender può essere fatto in un paio di modi diversi.

  1. Se si dispone già di un'istanza ILogger (per esempio quello che si ottiene da LogManager.GetLogger()) poi c'è un Appenders proprietà su di esso. Ciò ti fornirà eventuali appendici associate a quel livello specifico dell'erarchia di registrazione.
  2. È anche possibile chiamare LogManager.GetRepository() per ottenere un oggetto Heirarchy che contenga l'intero logger e l'emirarchia di appender. Il metodo prevede un assembly, quindi passa GetCallingAssembly() per ottenere quello predefinito. Questa classe ha un metodo GetAppenders() che restituisce tutti gli appendici configurati, sebbene non indichi quali sono associati a quali logger.

Da lì, basta guardare attraverso alla ricerca di un appender del tipo corretto (per esempio FileAppender o RollingFileAppender), poi leggere è File proprietà.

+2

penso che non funziona. La proprietà del file è già stata valutata in quel punto. Quindi non conterrà più '% date {yyyy} \% date {MM} \% date {dd} ...' ma '2012 \ 09 \ ...'. – Wolfgang

+0

@Michael Wolfgang ha assolutamente ragione: una volta recuperato, la proprietà _File_ è stata già valutata e non è stato possibile ottenere il valore del pattern originale. – Lev

+0

hrm. hai ragione, l'ho sempre usato per ottenere il percorso (che di solito non modelliamo) e non l'ho mai notato. Questi dati devono essere disponibili da qualche parte perché il modello viene ricalcolato a un certo punto, permettimi di scavare più a fondo. –

0

Penso che si desideri creare sottoclassi di RollingFileAppender e utilizzare la sottoclasse nel file di configurazione, anziché la classe base. Assicurati di prefisso il nome della classe con spazio dei nomi completo in modo che log4net possa trovarlo.

Ho solo un sottoclasse UDPAppender nel mio codice. Ho aggiunto un override del genere:

public override void ActivateOptions() 
    { 
     base.ActivateOptions(); 
    } 

quando ho spezzato prima della chiamata classe base, ho esaminato 'questo' nella finestra di gente del posto e ho visto i valori di 'membri' l'UdpAppender.

+0

Sfortunatamente, un'istanza di _RollingFileAppender_ è già impostata con il nome del file valutato e non conosce il modello del nome del file. Immagino che l'ultimo oggetto che vede questo modello sia un'istanza di _log4net.Repository.Hierarchy.XmlHierarchyConfigurator_ nel metodo _ParseAppender() _. In tal caso, l'unico modo per ottenere ciò di cui ho bisogno è in effetti analizzare il file di configurazione da solo (yuck!) ... – Lev

+0

Oh, ho frainteso. Vuoi il modello stesso. Suppongo che qualcuno possa cambiare lo schema e quindi non vuoi impostarlo via codice (quindi lo sapresti in anticipo)? – chrismead

0

La spiegazione di Michael Edenfield è buona. Ecco la realizzazione.

private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

string fileName = ((RollingFileAppender)log.Logger.Repository.GetCurrentLoggers() 
    .Where(e => e.Name == "Your namespace.class").ToList()[0] 
    .Repository.GetAppenders() 
    .Where(e => e.Name == "MyAppender").ToList()[0]).File.ToString(); 
0

posso ottenere il valore della <file value> con il seguente codice:

((log4net.Appender.FileAppender) ((log4net.Appender.IAppender[]) 
      ((log4net.Repository.Hierarchy.Logger) 
       log.Logger).Appenders.SyncRoot)[0]).File 
Problemi correlati