¿Cómo obtengo un método auxiliar en una clase de utilidad para usar su registrador de llamadas en log4net?

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

  •  04-07-2019
  •  | 
  •  

Pregunta

Tengo un archivo ejecutable que, según la línea de comandos, el interruptor suministrado tiene un aspecto similar al siguiente:

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

En mi configuración de log4net tengo dos registradores separados, uno para cada SummaryDiskSpaceReporter y DetailedDiskSpaceReporter porque sus requisitos de registro son diferentes:

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

Tanto SummaryDiskSpaceReporter como DetailedDiskSpaceReporter llaman a un método auxiliar en una clase llamada Ayudantes. Quiero poner algo de inicio de sesión en los métodos de la clase auxiliar.

Entonces ... la pregunta es, ¿cómo obtengo el método Helpers.CreateMessage () para usar el mismo registrador que su llamador?

es decir,

  

SummaryDiskSpaceReporter.Run () - > utilizar   DiskSpaceReporting.SummaryDiskSpaceReporter   logger DetailedDiskSpaceReporter.Run ()   - > use DiskSpaceReporting.DetailedDiskSpaceReporter   registrador.

Saludos Kev

¿Fue útil?

Solución

He estado jugando con esta pregunta durante bastante tiempo y, desafortunadamente, tengo que renunciar por un tiempo y volver a hacer " real " trabajo. Por el momento, lo que he encontrado es el siguiente:

Opciones 1: pasar el registrador en

Esta no es una gran opción, pero debería funcionar bien si no le importa acoplar su ayudante a un registrador. Simplemente permita que su método CreateMessage tome un IEventIDLog. Luego puede usar esto para iniciar sesión en el registrador pasado correcto.

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

No es exactamente brillante, ¡pero debería funcionar!

Opciones 2: usar la pila de llamadas

Utilice la pila de llamadas para encontrar el código de llamada y de ahí encuentre el tipo y obtenga el registrador que desee de ese 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
}

Aún no está brillante porque necesitamos tocar la pila de llamadas y qué sucede si el código de la llamada no tiene un registrador.

Opción 3: usar log4net

Esta es la opción que queremos usar, demonios, es lo que la pregunta quiere como respuesta, pero todavía no la he resuelto yet . :) Mirando a través de log4net encontramos cosas geniales como la clase de Jerarquía que nos permite obtener el registrador raíz.

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

Así que estoy seguro de que hay una manera de hacer que el registrador esté un nivel por encima del método CreateMessage, ahora solo para encontrarlo. :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top