2012-04-10 136 views

回答

1

我不知道關於npgsql的任何內容,但是如果你有源代碼並且被允許改變它,那麼應該更容易改變它來支持log4net。

如果你沒有源代碼,那麼它不會很容易,甚至可能不可能。由於log4net不會攔截其他來源的輸出,因此我唯一可以看到的做法是有一個後臺線程監視npgsql輸出到的文件,當文件更改時,您需要讀取該文件並解析信息,然後用該信息調用log4net。

您仍然有這樣的問題,即log4net會認爲每個調用都來自您的例程,而不是npgsql和堆棧跟蹤變得混亂。此外,只有在每次創建日誌條目時,npgsql才鎖定,打開,寫入和關閉文件。

1

首先添加log4net的,以您的解決方案,最簡單的方式是使用的NuGet: 所以你這樣做: 安裝,包裝log4net的 ,那麼你必須安裝Npgsql的: 安裝,包裝Npgsql的

在你的網頁

.config文件添加這個元素:(你必須使用app。配置爲非web解決方案)

在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

這是我如何做它,它似乎很好地工作。請注意,我分裂命令退出到一個單獨的附加器,因爲它得到相當詳細...

首先,添加該你做其他任何調用之前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中一樣。」參考:https://github.com/npgsql/Npgsql/releases – 2017-03-30 01:52:21

相關問題