2011-01-13 47 views
3

今天早些時候,我問了一個關於從代碼配置log4net的問題,並很快得到了一個答案,它允許我將其配置爲輸出到文本文件。從那時起,我的需求發生了變化,我需要使用SqLite作爲appender。所以,我創建了下面的類,允許這樣的:log4net config代碼中的SqLite

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

}

的問題是,雖然創建數據庫和表增加,我越來越沒有記錄到這一點。

類這樣使用:

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

任何幫助點我在正確的方向,將不勝感激。

感謝

+0

您可能會檢查此問題的解決方案:http://stackoverflow.com/questions/382336/log4net-and-system-data-sqlite – 2011-01-13 17:18:11

+0

@ Dillie-O - 除了該問題使用XML時,理查德尋找代碼配置。 – jfar 2011-01-13 17:48:28

回答

6

的問題是在RawPropertyLayout實例。在我的測試中,他們不會像預期的那樣提取LevelLoggerName屬性,這會導致數據庫中出現空限制違規。

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

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

下面是一個完整的工作示例:

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(); 
       } 
      } 
     } 
    } 
} 
1

你嘗試改變緩衝區大小從100到1這些可以通過使用PatternLayout如下固定?

appender.BufferSize = 100; 

appender.BufferSize = 1; 

目前文件正在等待100個的消息就任何輸出之前。