4

今日の初めに、コードからlog4netを構成することについて質問し、非常に迅速に回答を得て、テキストファイルに出力するように構成することができました。それ以来、私のニーズは変化し、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));

私を正しい方向に向けるための助けをいただければ幸いです。

ありがとう

4

2 に答える 2

6

問題はRawPropertyLayoutインスタンスにあります。私のテストでは、期待どおりにプロパティLevelとプロパティが取り出されず、データベースで null 制約違反が発生します。これらは、次のようLoggerNameに a を使用して修正できます。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();
                }
            }
        }
    }
}
于 2011-01-13T18:52:59.940 に答える
1

バッファ サイズを 100 から 1 に変更してみましたか?

appender.BufferSize = 100;

appender.BufferSize = 1;

現在、ファイルはメッセージを出力する前に 100 個のメッセージを待機しています。

于 2012-11-06T01:54:42.887 に答える