2012-04-10 6 views
0

Можно ли перенаправить выход журнала npgsql для входа в log4net logger? Из исходного кода npgsql он выглядит так, что он регистрируется непосредственно в stdout/stderr или указанном файле (используя статические свойства по NpgsqlEventLog). Есть ли способ маршрутизации этого входа в log4net?Как перенаправить вывод журнала npgsql в журнал log4net?

ответ

1

Я ничего не знаю о npgsql, но если у вас есть источник и им разрешено его изменять, то должно быть легче изменить его для поддержки log4net.

Если у вас не было источника, это было бы нелегко и возможно даже невозможно. Поскольку log4net не перехватывает вывод из других источников, единственный способ, которым я мог это сделать, - это иметь фоновый поток, который контролирует файл, который выводит npgsql, и когда файл изменяется, вам нужно будет прочитать этот файл и проанализировать информацию, а затем вызвать log4net с этой информацией.

У вас все еще есть проблема, что log4net будет считать, что каждый вызов поступает из вашей подпрограммы, а не npgsql, и трассировки стека перепутаны. Также будет работать, только если npgsql блокирует, открывает, записывает и закрывает файл каждый раз, когда записывается запись в журнал.

1

Сначала добавьте log4net к вашему решению, легкий способ заключается в использовании NuGet: так что вы это сделать: установить-пакет log4net , то вы должны установить npgsql: установки-пакет npgsql

в вашей сети .config вы добавляете эти элементы: (вам нужно использовать приложение.config for not web solution)

В configSection printf ("% d \ n", 42);/*

//the most important thing is to ensure that the type on your parameter   //section is correct. otherwise, no error will be returned, and no data will be   inserted. 

//now, at your code you can use this function: 

     protected void LogInfo(string message, params object[] args) 
     { 
      log4net.ILog log =  log4net.LogManager.GetLogger("postgreSqlLogAppender"); 
      log4net.ThreadContext.Properties["UserId"] = args.[0]; 
      log4net.ThreadContext.Properties["EntityId"] = args.[1]; 
      log.Info(string.Format("{0}: {1}",  this.GetType().Name.Replace("Controller", ""), string.Format(message, args))); 
      log4net.ThreadContext.Properties.Remove("UserId"); 
      log4net.ThreadContext.Properties.Remove("EntityId"); 
     } 


//to call your function 
    void test() 
{ 
    LogInfo("My message",15,326) 
} 


//in my case 15 is my current user_id and 326 is the my class_object. 
    */ 
2

Это, как я сделал это, и это, кажется, работает достаточно хорошо. Обратите внимание, что я расколоть команду выхода из системы в отдельный Appender, потому что он получает довольно многословен ...

Во-первых, добавьте это, прежде чем делать какие-либо другие вызовы в Npgsql:

NpgsqlLogManager.Provider = new Log4NetNpgsqlLoggingProvider("NpgsqlDefaultLogger") 
{ 
    CommandLoggerName = "NpgsqlCommandLogger" 
}; 

Теперь нужно добавить в классе поставщика регистрации:

using System; 
using Npgsql.Logging; 

namespace Util.Npgsql 
{ 
    public class Log4NetNpgsqlLoggingProvider : INpgsqlLoggingProvider 
    { 
     public string DefaultLoggerName { get; } 
     public string CommandLoggerName { get; set; } 

     public Log4NetNpgsqlLoggingProvider(string defaultLoggerName) 
     { 
      if (defaultLoggerName == null) throw new ArgumentNullException(nameof(defaultLoggerName)); 
      DefaultLoggerName = defaultLoggerName; 
     } 

     public NpgsqlLogger CreateLogger(string name) 
     { 
      switch (name) 
      { 
       case "Npgsql.NpgsqlCommand": 
        return new Log4NetNpgsqlLogger(CommandLoggerName ?? DefaultLoggerName); 
       default: 
        return new Log4NetNpgsqlLogger(DefaultLoggerName); 
      } 
     } 
    } 
} 

И вы также должны фактический класс регистратора:

using System; 
using log4net; 
using log4net.Core; 
using Npgsql.Logging; 

namespace Util.Npgsql 
{ 
    public class Log4NetNpgsqlLogger : NpgsqlLogger 
    { 
     private readonly ILog _log; 

     public Log4NetNpgsqlLogger(string name) 
     { 
      _log = LogManager.GetLogger(name); 
     } 

     public override bool IsEnabled(NpgsqlLogLevel level) 
     { 
      return _log.Logger.IsEnabledFor(GetLog4NetLevelFromNpgsqlLogLevel(level)); 
     } 

     public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null) 
     { 
      _log.Logger.Log(typeof(NpgsqlLogger), GetLog4NetLevelFromNpgsqlLogLevel(level), connectorId + ": " + msg, exception); 
     } 

     protected Level GetLog4NetLevelFromNpgsqlLogLevel(NpgsqlLogLevel level) 
     { 
      switch (level) 
      { 
       case NpgsqlLogLevel.Trace: 
       case NpgsqlLogLevel.Debug: 
        return Level.Debug; 
       case NpgsqlLogLevel.Info: 
        return Level.Info; 
       case NpgsqlLogLevel.Warn: 
        return Level.Warn; 
       case NpgsqlLogLevel.Error: 
        return Level.Error; 
       case NpgsqlLogLevel.Fatal: 
        return Level.Fatal; 
       default: 
        throw new Exception("Unknown Npgsql Log Level: " + level); 
      } 
     } 
    } 
} 
+0

также обратите внимание что в Npgsql 3.2.0: «Пользовательское ведение журнала Npgsql было заменено на [Microsoft.Extensions.Logging]». Однако в 3.2.2 он был отменен: «Из-за множества жалоб, использование Npgsql 3.2 в Microsoft.Extensions.Logging было отключено, и регистрация теперь работает так же, как и в Npgsql 3.1». refs: https://github.com/npgsql/Npgsql/releases –

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