Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Log4net écrit un objet personnalisé dans la base de données SQL à l'aide d'un appender personnalisé ?

Ce site m'a orienté dans la bonne direction.

J'ai dû créer un LayoutPattern et un PatternConverter personnalisés afin d'écrire mon objet dans le journal avec succès. Il s'avère que le texte étrange "12wo" que j'obtenais dans la base de données était dû au fait que le modèle de conversion utilise la syntaxe de style printf c. Quoi qu'il en soit, voici du 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;
            }
        }
    }
}

Voici comment obtenir une instance de l'enregistreur par son nom :

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

Voici comment écrire un objet Test dans le journal.

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

Voici comment un paramètre doit être défini dans le web.config.

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

Une autre chose à noter est les sections root et logger de web.config. Dans la section racine se trouve l'endroit où l'enregistreur par défaut est défini avec son niveau défini. Je peux définir mon TestLogger personnalisé dans une section d'enregistreur qui référencera l'appender comme indiqué ci-dessous. Cela me permet d'accéder au TestLogger par son nom, comme indiqué ci-dessus.

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

J'ai également découvert que si vous vouliez simplement ajouter quelques propriétés à l'ADONetAppender par défaut (et ajouter quelques champs à la table), vous pouvez à la place utiliser le log4net.ThreadContext pour définir ces propriétés comme suit :

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

Ensuite, dans le web.config sous la section des paramètres, vous pouvez accéder à cette propriété comme ceci :

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