Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Log4net gravando objeto personalizado no banco de dados sql usando anexador personalizado?


Este site me apontou na direção certa.

Eu tive que criar um LayoutPattern e um PatternConverter personalizados para gravar meu objeto no log com sucesso. Acontece que o estranho texto "12wo" que eu estava recebendo no banco de dados era porque o padrão de conversão usa a sintaxe de estilo printf c. De qualquer forma, aqui está algum 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;
            }
        }
    }
}

Veja como obter uma instância do registrador por nome:
private static readonly ILog TestLogger = LogManager.GetLogger("TestLogger");

Aqui está como gravar um objeto de teste no log.
TestLogger.Info(new Test {One = "field one", Two = "field two"});

Aqui está como um parâmetro deve ser definido no web.config.
<parameter>
  <parameterName value="@one" />
  <dbType value="String" />
  <size value="50" />
  <layout type="MyApp.TestLayoutPattern">
    <conversionPattern value="%test{one}" />
  </layout>
</parameter>

Outra coisa a notar são as seções root e logger do web.config. Na seção raiz é onde o registrador padrão é definido com seu nível definido. Eu posso definir meu TestLogger personalizado em uma seção de logger que fará referência ao appender conforme mostrado abaixo. Isso me permite acessar o TestLogger pelo nome, conforme mostrado acima.
<root>
  <level value="ALL"/>
  <appender-ref ref="ADONetAppender"/>
</root>
<logger additivity="false" name="TestLogger">
  <level value="ALL"/>
  <appender-ref ref="TestAppender" />
</logger>

Eu também descobri que se você quisesse apenas adicionar algumas propriedades ao ADONetAppender padrão (e adicionar alguns campos à tabela), você poderia usar o log4net.ThreadContext para definir essas propriedades assim:
log4net.ThreadContext.Properties["MyCustomPrperty"] = value;

Em seguida, no web.config, na seção de parâmetros, você pode acessar essa propriedade assim:
<parameter>
  <parameterName value="@myCustomProperty"/>
  <dbType value="String"/>
  <layout type="log4net.Layout.RawPropertyLayout">
    <key value="MyCustomProperty" />
  </layout>
</parameter>