2011-01-13 9 views
3

今日、私はコードからlog4netを設定することについて質問し、非常に迅速に答えてくれました。これにより、テキストファイルに出力するよう設定することができました。それ以来私のニーズは変わってきており、SqLiteをアペンダーとして使用する必要があります。だから私は、これを許可するには、以下のクラスを作成しました: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(); 
    } 
} 

}

問題は、データベースの作成、テーブルが追加されているが、私はこれまで何のログを取得していないだということです。

クラスは次のように使用されます。

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

任意の助けいただければ幸い正しい方向に私を指すように。

おかげ

+0

解決方法については、この質問をチェックしてください。http://stackoverflow.com/questions/382336/log4net-and-system-data-sqlite –

+0

@ Dillie-O - リチャードがコード設定を探しているときにxmlを使用する以外は。 – jfar

答えて

6

問題がRawPropertyLayoutのインスタンスです。私のテストでは、期待通りにとLoggerNameのプロパティを引き出すことはありません。その結果、データベースには制約違反が発生します。これらは、次のようにPatternLayoutを用いて固定することができます。ここでは

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

ありがとうございました。それは私に長い時間をかかりました。 Upvoteと受け入れられた解決策。 – Richard

+0

@リチャード、それは私が思っていたよりもはるかに長い時間がかかりました。私はlog4netコードの中で 'RawPropertyLayout'を動作させるために多くのことを試みましたが、実際には特定のプロパティを取得するように設計されていないようです。上記は良い回避策です。私たちもSQLiteを使用していますので、これも使用することになります。これは、ADO.NETでlog4netを使用したのは初めてのことです。それはかなりきれいです。 –

1

あなたは100から1にバッファサイズを変更してみてくださいました?

appender.BufferSize = 1; 

appender.BufferSize = 100; 

それがいずれかを出力する前に、現在お使いのファイルには、100件のメッセージを待っています。