Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Log4net scrive un oggetto personalizzato nel database sql utilizzando un appender personalizzato?

Questo sito mi ha indicato la giusta direzione.

Ho dovuto creare un LayoutPattern e PatternConverter personalizzati per scrivere correttamente il mio oggetto nel registro. Si scopre che lo strano testo "12wo" che stavo ricevendo nel database era perché il modello di conversione utilizza la sintassi dello stile printf c. Comunque, ecco un po' di codice.

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

Ecco come ottenere un'istanza del logger per nome:

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

Ecco come scrivere un oggetto Test nel registro.

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

Ecco come definire un parametro in web.config.

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

Un'altra cosa da notare sono le sezioni root e logger di web.config. Nella sezione principale è dove viene definito il logger predefinito con il relativo livello impostato. Posso definire il mio TestLogger personalizzato in una sezione logger che farà riferimento all'appendice come mostrato di seguito. Questo mi permette di accedere al TestLogger per nome come mostrato sopra.

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

Ho anche scoperto che se volevi solo aggiungere alcune proprietà all'ADONEtAppender predefinito (e aggiungere alcuni campi alla tabella), potresti invece usare log4net.ThreadContext per impostare quelle proprietà in questo modo:

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

Quindi nel web.config sotto la sezione parametro puoi accedere a quella proprietà in questo modo:

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