2011-01-13 16 views
3

Früher heute habe ich eine Frage über die Konfiguration von log4net aus dem Code gestellt und bekam sehr schnell eine Antwort, die es mir ermöglichte, es für die Ausgabe in eine Textdatei zu konfigurieren. Seitdem haben sich meine Bedürfnisse geändert und ich muss SqLite als Appender verwenden. Also habe ich die folgende Klasse dies zu ermöglichen:log4net config SqLite in code

public static class SqLiteAppender 
{ 
    public static IAppender GetSqliteAppender(string dbFilename) 
    { 
     var dbFile = new FileInfo(dbFilename); 

    if (!dbFile.Exists) 
    { 
     CreateLogDb(dbFile); 
    } 

    var appender = new AdoNetAppender 
         { 
          ConnectionType = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite", 
          ConnectionString = String.Format("Data Source={0};Version=3;", dbFilename), 
          CommandText = "INSERT INTO Log (Date, Level, Logger, Message) VALUES (@Date, @Level, @Logger, @Message)" 
         }; 

    appender.AddParameter(new AdoNetAppenderParameter 
           { 
            ParameterName = "@Date", 
            DbType = DbType.DateTime, 
            Layout = new log4net.Layout.RawTimeStampLayout() 

           }); 

    appender.AddParameter(new AdoNetAppenderParameter 
           { 
            ParameterName = "@Level", 
            DbType = DbType.String, 
            Layout = new log4net.Layout.RawPropertyLayout { Key = "Level" } 
           }); 

    appender.AddParameter(new AdoNetAppenderParameter 
           { 
            ParameterName = "@Logger", 
            DbType = DbType.String, 
            Layout = new log4net.Layout.RawPropertyLayout { Key = "LoggerName" } 
           }); 

    appender.AddParameter(new AdoNetAppenderParameter 
           { 
            ParameterName = "@Message", 
            DbType = DbType.String, 
            Layout = new log4net.Layout.RawPropertyLayout { Key = "RenderedMessage" } 
           }); 

    appender.BufferSize = 100; 
    appender.ActivateOptions(); 
    return appender; 
} 

public static void CreateLogDb(FileInfo file) 
{ 
    using (var conn = new SQLiteConnection()) 
    { 
     conn.ConnectionString = string.Format("Data Source={0};New=True;Compress=True;Synchronous=Off", file.FullName); 
     conn.Open(); 
     var cmd = conn.CreateCommand(); 

     cmd.CommandText = 
         @"CREATE TABLE Log(
          LogId  INTEGER PRIMARY KEY, 
          Date  DATETIME NOT NULL, 
          Level  VARCHAR(50) NOT NULL, 
          Logger VARCHAR(255) NOT NULL, 
          Message TEXT DEFAULT NULL 
         );"; 

     cmd.ExecuteNonQuery(); 
     cmd.Dispose(); 
     conn.Close(); 
    } 
} 

}

Das Problem ist, dass, obwohl die Datenbank erstellt wird und die Tabelle hinzugefügt, ich bin keine Protokollierung dieses bekommen.

ist die Klasse wie folgt verwendet:

BasicConfigurator.Configure(SqLiteAppender.GetSqliteAppender(applicationContext.GetLogFile().FullName)); 

jede Hilfe mich in der richtigen Richtung würde geschätzt zeigen.

Dank

+0

Sie können diese Frage für eine Lösung überprüfen: http://StackOverflow.com/Questions/382336/log4net-and-System-Data-Sqlite –

+0

@ Dillie-O - Mit Ausnahme dieser Frage verwendet XML, wenn Richard nach Code-Konfiguration sucht . – jfar

Antwort

6

Das Problem ist in den RawPropertyLayout Instanzen. In meinen Tests ziehen sie die Eigenschaften Level und nicht wie erwartet heraus, was zu Null-Constraint-Verletzungen in der Datenbank führt. Diese können durch die Verwendung eines PatternLayout wie folgt festgesetzt:

Layout = new Layout2RawLayoutAdapter(new PatternLayout("%level")) 

und

Layout = new Layout2RawLayoutAdapter(new PatternLayout("%logger")) 

Hier ist ein komplettes Arbeitsbeispiel:

using System; 
using System.Data; 
using System.Data.SQLite; 
using System.IO; 
using log4net; 
using log4net.Appender; 
using log4net.Config; 
using log4net.Layout; 

namespace ConsoleApplication1 
{ 
    class SQLiteLogging 
    { 
     public static void Test() 
     { 
      BasicConfigurator.Configure(SqLiteAppender.GetSqliteAppender("D:/test.dat")); 
      LogManager.GetLogger(typeof (SqLiteAppender)).Info("Hello there"); 
     } 

     public static class SqLiteAppender 
     { 
      public static IAppender GetSqliteAppender(string dbFilename) 
      { 
       var dbFile = new FileInfo(dbFilename); 

       if (!dbFile.Exists) 
       { 
        CreateLogDb(dbFile); 
       } 

       var appender = new AdoNetAppender 
            { 
             ConnectionType = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite", 
             ConnectionString = String.Format("Data Source={0};Version=3;", dbFilename), 
             CommandText = "INSERT INTO Log (Date, Level, Logger, Message) VALUES (@Date, @Level, @Logger, @Message)" 
            }; 

       appender.AddParameter(new AdoNetAppenderParameter 
              { 
               ParameterName = "@Date", 
               DbType = DbType.DateTime, 
               Layout = new RawTimeStampLayout() 

              }); 

       appender.AddParameter(new AdoNetAppenderParameter 
              { 
               ParameterName = "@Level", 
               DbType = DbType.String, 
               Layout = new Layout2RawLayoutAdapter(new PatternLayout("%level")) 
              }); 

       appender.AddParameter(new AdoNetAppenderParameter 
              { 
               ParameterName = "@Logger", 
               DbType = DbType.String, 
               Layout = new Layout2RawLayoutAdapter(new PatternLayout("%logger")) 
              }); 

       appender.AddParameter(new AdoNetAppenderParameter 
              { 
               ParameterName = "@Message", 
               DbType = DbType.String, 
               Layout = new RawPropertyLayout { Key = "RenderedMessage" } 
              }); 

       appender.ActivateOptions(); 
       return appender; 
      } 

      public static void CreateLogDb(FileInfo file) 
      { 
       using (var conn = new SQLiteConnection()) 
       { 
        conn.ConnectionString = string.Format("Data Source={0};New=True;Compress=True;Synchronous=Off", file.FullName); 
        conn.Open(); 
        var cmd = conn.CreateCommand(); 

        cmd.CommandText = 
            @"CREATE TABLE Log(
          LogId  INTEGER PRIMARY KEY, 
          Date  DATETIME NOT NULL, 
          Level  VARCHAR(50) NOT NULL, 
          Logger VARCHAR(255) NOT NULL, 
          Message TEXT DEFAULT NULL 
         );"; 

        cmd.ExecuteNonQuery(); 
        cmd.Dispose(); 
        conn.Close(); 
       } 
      } 
     } 
    } 
} 
+0

Vielen Dank. Das hätte mich lange suchen müssen. Upvote und akzeptierte Lösung. – Richard

+0

@Richard, ich brauchte viel länger um herauszufinden, als ich dachte. Ich bin viel durch den log4net-Code gegangen und habe versucht, 'RawPropertyLayout' zum Laufen zu bringen, aber es scheint, als wäre es nicht dazu gedacht, bestimmte Eigenschaften herauszubekommen. Das oben genannte ist ein guter Work-around. Wir verwenden auch SQLite, so dass wir es möglicherweise auch verwenden - es ist das erste Mal, dass ich log4net mit ADO.NET verwendet habe. Es ist ziemlich ordentlich. –

1

Haben Sie versucht, die Änderung der Puffergröße 100-1 ?

appender.BufferSize = 100; 

zu

appender.BufferSize = 1; 

Aktuell Dateien für eine 100 Nachrichten wartet, bevor es noch gibt.

Verwandte Themen