sql >> Base de Datos >  >> RDS >> Sqlserver

¿Log4net escribe un objeto personalizado en la base de datos sql usando un agregador personalizado?

Este sitio me indicó la dirección correcta.

Tuve que crear un LayoutPattern y PatternConverter personalizados para poder escribir mi objeto en el registro con éxito. Resulta que el extraño texto "12wo" que estaba recibiendo en la base de datos se debía a que el patrón de conversión usa la sintaxis de estilo printf c. De todos modos, aquí hay algo de código.

public class TestLayoutPattern : PatternLayout
{
    public TestLayoutPattern()
    {
        AddConverter(new ConverterInfo
        {
            Name = "test",
            Type = typeof (TestConverter)
        });
    }
}
public class TestConverter : PatternConverter
{
    protected override void Convert(System.IO.TextWriter writer, object state)
    {
        if (state == null)
        {
            writer.Write(SystemInfo.NullText);
            return;
        }

        var loggingEvent = state as LoggingEvent;
        if (loggingEvent == null)
            throw new NullReferenceException("loggingEvent");

        var test = loggingEvent.MessageObject as Test;

        if (test == null)
        {
            writer.Write(SystemInfo.NullText);
        }
        else
        {
            switch (Option.ToLower())
            {
                case "one":
                    writer.Write(test.One);
                    break;
                case "two":
                    writer.Write(test.Two);
                    break;                    
                default:
                    writer.Write(SystemInfo.NullText);
                    break;
            }
        }
    }
}

Aquí se explica cómo obtener una instancia del registrador por nombre:

private static readonly ILog TestLogger = LogManager.GetLogger("TestLogger");

Aquí se explica cómo escribir un objeto de prueba en el registro.

TestLogger.Info(new Test {One = "field one", Two = "field two"});

Así es como se debe definir un parámetro en web.config.

<parameter>
  <parameterName value="@one" />
  <dbType value="String" />
  <size value="50" />
  <layout type="MyApp.TestLayoutPattern">
    <conversionPattern value="%test{one}" />
  </layout>
</parameter>

Otra cosa a tener en cuenta son las secciones raíz y registrador de web.config. En la sección raíz es donde se define el registrador predeterminado con su conjunto de niveles. Puedo definir mi TestLogger personalizado en una sección de registro que hará referencia al appender como se muestra a continuación. Esto me permite acceder al TestLogger por nombre como se muestra arriba.

<root>
  <level value="ALL"/>
  <appender-ref ref="ADONetAppender"/>
</root>
<logger additivity="false" name="TestLogger">
  <level value="ALL"/>
  <appender-ref ref="TestAppender" />
</logger>

También descubrí que si solo deseaba agregar algunas propiedades al ADONetAppender predeterminado (y agregar algunos campos a la tabla), podría usar log4net.ThreadContext para establecer esas propiedades de la siguiente manera:

log4net.ThreadContext.Properties["MyCustomPrperty"] = value;

Luego, en web.config, en la sección de parámetros, puede acceder a esa propiedad de esta manera:

<parameter>
  <parameterName value="@myCustomProperty"/>
  <dbType value="String"/>
  <layout type="log4net.Layout.RawPropertyLayout">
    <key value="MyCustomProperty" />
  </layout>
</parameter>