log4net在代码中配置SqLite

时间:2011-01-13 17:05:16

标签: c# log4net log4net-configuration

今天早些时候我问了一个关于从代码配置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));

任何有助于指出我正确方向的帮助都将受到赞赏。

由于

2 个答案:

答案 0 :(得分:6)

问题出在RawPropertyLayout个实例中。在我的测试中,他们没有像预期的那样提取LevelLoggerName属性,这导致数据库上出现空约束违规。可以使用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();
                }
            }
        }
    }
}

答案 1 :(得分:1)

您是否尝试将缓冲区大小从100更改为1?

appender.BufferSize = 100;

appender.BufferSize = 1;

目前,您的文件在输出任何消息之前正在等待100条消息。