Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Log4net schreibt benutzerdefiniertes Objekt in SQL-Datenbank mit benutzerdefiniertem Appender?

Diese Seite wies mich in die richtige Richtung.

Ich musste ein benutzerdefiniertes LayoutPattern und einen PatternConverter erstellen, um mein Objekt erfolgreich in das Protokoll zu schreiben. Es stellte sich heraus, dass der seltsame „12wo“-Text, den ich in der Datenbank erhielt, darauf zurückzuführen war, dass das Konvertierungsmuster die Syntax im printf c-Stil verwendet. Wie auch immer, hier ist ein Code.

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

So erhalten Sie eine Instanz des Loggers nach Namen:

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

So schreiben Sie ein Testobjekt in das Protokoll.

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

So sollte ein Parameter in der web.config definiert werden.

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

Eine weitere zu beachtende Sache sind die Root- und Logger-Abschnitte der web.config. Im Root-Abschnitt wird der Standard-Logger mit seinem eingestellten Level definiert. Ich kann meinen benutzerdefinierten TestLogger in einem Logger-Abschnitt definieren, der wie unten gezeigt auf den Appender verweist. Dadurch kann ich wie oben gezeigt über den Namen auf den TestLogger zugreifen.

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

Ich habe auch festgestellt, dass Sie, wenn Sie nur ein paar Eigenschaften zum Standard-ADONEtAppender hinzufügen wollten (und ein paar Felder zur Tabelle hinzufügen wollten), stattdessen log4net.ThreadContext verwenden könnten, um diese Eigenschaften wie folgt festzulegen:

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

Dann können Sie in der web.config unter dem Parameterabschnitt wie folgt auf diese Eigenschaft zugreifen:

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