Конфигурация log4net SqLite в коде

Ранее сегодня я задал вопрос о настройке 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));

любая помощь, чтобы указать мне в правильном направлении, будет оценена по достоинству.

Спасибо


person Richard    schedule 13.01.2011    source источник
comment
Вы можете проверить этот вопрос для решения: stackoverflow.com/ вопросы/382336/   -  person Dillie-O    schedule 13.01.2011
comment
@Dillie-O - За исключением того, что в этом вопросе используется xml, когда Ричард ищет конфигурацию кода.   -  person John Farrell    schedule 13.01.2011


Ответы (2)


Проблема в экземплярах RawPropertyLayout. В моем тестировании они не извлекают свойства Level и 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();
                }
            }
        }
    }
}
person Samuel Neff    schedule 13.01.2011
comment
Спасибо большое. Это заняло бы у меня много времени, чтобы найти. Проголосуйте и примите решение. - person Richard; 14.01.2011
comment
@ Ричард, мне потребовалось намного больше времени, чтобы понять, чем я думал. Я много раз перебирал код log4net, пытаясь заставить RawPropertyLayout работать, но похоже, что он на самом деле не предназначен для получения определенных свойств. Вышеупомянутое является хорошим обходным путем. Мы также используем SQLite, так что в конечном итоге мы тоже можем использовать его — я впервые использовал log4net с ADO.NET. Это довольно аккуратно. - person Samuel Neff; 14.01.2011

Вы пытались изменить размер буфера со 100 до 1?

appender.BufferSize = 100;

to

appender.BufferSize = 1;

В настоящее время ваш файл ожидает 100 сообщений, прежде чем выводить их.

person Ushal Naidoo    schedule 06.11.2012