2012-09-08 12 views
7

Estoy tratando de escribir un código C#, que recupera en tiempo de ejecución el patrón de nombre de un archivo de registro log4net a través de la API log4net.¿Cómo obtener un patrón de nombre de archivo de registro log4net programáticamente?

Es decir, si en log4net.config la siguiente appender se define:

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

me gustaría obtener % date {} aaaa fecha \%} {MM fecha \%} {dd \% propiedad {Id} .log en una variable de cadena en el código (sin analizar log4net.config como XML simple).

¿Alguien tiene una idea para sacar este truco?

Gracias de antemano.

Respuesta

2

El valor de este patrón estará en la propiedad File de una instancia FileAppender que forma parte de su repositorio de registro.

Llegar al appender se puede hacer de diferentes maneras.

  1. Si ya tiene una instancia ILogger (por ejemplo, lo que se obtiene a partir LogManager.GetLogger()) entonces hay un Appenders propiedad sobre el mismo. Esto le dará los apéndices asociados con ese nivel específico de la jerarquía de registro.
  2. También puede llamar al LogManager.GetRepository() para obtener un objeto Heirarchy que contenga todo el registrador y la jerarquía de apéndices. El método espera un ensamblaje, así que pase GetCallingAssembly() para obtener el ensamblado predeterminado. Esta clase tiene un método GetAppenders() que devuelve todos los apéndices configurados, aunque no le indicará cuáles están asociados con qué registradores.

A partir de ahí, sólo tiene que buscar a través en busca de una appender del tipo correcto (por ejemplo FileAppender o RollingFileAppender), a continuación, leer es File propiedad.

+2

Creo que eso no funciona. La propiedad del archivo ya está evaluada en ese punto. Por lo tanto, ya no contendrá '% date {aaaa} \% date {MM} \% date {dd} ...' but '2012 \ 09 \ ...'. – Wolfgang

+0

@ Michael Wolfgang tiene toda la razón: cuando se recupera la propiedad _fichero_ ya fue evaluada, y no pude obtener el valor patrón original. – Lev

+0

hrm. tienes razón, siempre he usado esto para obtener el camino (que normalmente no usamos) y nunca lo noté. Esta información debe estar disponible en alguna parte porque el patrón se vuelve a calcular en algún momento, déjame profundizar. –

0

Creo que desea subclasificar RollingFileAppender, y usar su subclase en el archivo de configuración, en lugar de la clase base. Asegúrese de poner un prefijo al nombre de clase con espacio de nombres completo para que log4net pueda encontrarlo.

Tengo solo un UDPAppender subclasificado en mi código. He añadido una anulación de esta manera:

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

Cuando partí antes de la llamada clase base, que examinó 'esto' en la ventana de la gente y vi los valores para el UDPAppender 'miembros'.

+0

Desafortunadamente, una instancia de _RollingFileAppender_ ya está establecida con el nombre de archivo evaluado y no tiene conocimiento del patrón de nombre de archivo. Supongo que el último objeto que ve este patrón es una instancia de _log4net.Repository.Hierarchy.XmlHierarchyConfigurator_ en el _ParseAppender() _ método. En tal caso, la única manera de lograr lo que necesito es de hecho el análisis del archivo de configuración en mi propia (puaj!) ... – Lev

+0

Oh, no he entendido bien. Quieres el patrón en sí mismo. Supongo que alguien podría cambiar el patrón y, por lo tanto, no desea configurarlo por código (¿entonces lo sabría por adelantado)? – chrismead

0

Explicación de Michael Edenfield es bueno. Aquí está la realización.

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

que puede obtener el valor de la <file value> con el siguiente código:

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