2012-04-10 62 views
0

npgsqlのログ出力をlog4netロガーにリダイレクトすることはできますか? npgsqlソースコードからは、stdout/stderrまたは指定されたファイルに直接ログするように見えます(NpgsqlEventLogの静的プロパティを使用)。そのログをlog4netにルーティングする方法はありますか?npgsqlログ出力をlog4netロガーにリダイレクトする方法は?

答えて

1

私はnpgsqlについて何も知らないが、ソースがあり、それを変更することが許可されている場合、でlog4netをサポートする方が簡単に変更する必要があります。

ソースがない場合は、簡単ではない可能性があります。 log4netは他のソースからの出力を傍受しないため、npgsqlが出力しているファイルを監視するバックグラウンドスレッドを持つことが唯一の方法であり、ファイルが変更されたらそのファイルを読む必要があります情報を解析し、その情報でlog4netを呼び出します。

log4netは、すべての呼び出しがルーチンから来ていると思っていて、npgsqlとスタックトレースが混乱しているとは考えられないという問題があります。また、ログエントリが作成されるたびにnpgsqlがファイルのロック、オープン、書き込み、およびクローズを行っていた場合にのみ機能します。まず、あなたのソリューションにlog4netのを追加

1

は、簡単な方法はnugetを使用することです: ので、あなたはこれを行う: あなたはNpgsqlのをインストールする必要があり、その後log4netの インストール・パッケージ: インストール・パッケージをNpgsqlのウェブで

.configファイルに次の要素を追加します。(appを使用する必要があります。ウェブソリューションではない設定)

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と同じようにロギングされています。 refs:https://github.com/npgsql/Npgsql/releases –

関連する問題