2011-01-13 2 views
3

Раньше сегодня я задал вопрос о настройке log4net из кода и получил ответ очень быстро, что позволило мне настроить его для вывода в текстовый файл. С тех пор мои потребности изменились, и мне нужно использовать SqLite в качестве приложения. Таким образом, я создал следующий класс, чтобы разрешить это: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 –

+0

@ Dillie-O - За исключением того, что этот вопрос использует xml, когда Ричард ищет конфигурацию кода , – jfar

ответ

6

Проблема находится в 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(); 
       } 
      } 
     } 
    } 
} 
+0

Большое спасибо. Мне понадобилось бы много времени, чтобы найти. Upvote и принятое решение. – Richard

+0

@ Рихард, мне потребовалось гораздо больше времени, чтобы понять, чем я думал. Я многократно перебирал код log4net, пытаясь заставить «RawPropertyLayout» работать, но похоже, что он не предназначен для получения определенных свойств. Вышеприведенное является хорошей практикой. Мы также используем SQLite, поэтому мы тоже можем использовать это - это первый раз, когда я использовал log4net с ADO.NET. Это довольно аккуратно. –

1

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

appender.BufferSize = 100; 

в

appender.BufferSize = 1; 

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

Смежные вопросы