2012-04-10 1 views

Répondre

1

Je ne sais rien à propos de npgsql, mais si vous avez la source et êtes autorisé à le changer, il devrait être plus facile de le modifier pour soutenir log4net.

Si vous n'aviez pas la source, ce ne serait pas facile et ne serait même pas possible. Étant donné que log4net n'intercepte pas la sortie d'autres sources, la seule façon de le faire serait d'avoir un thread d'arrière-plan qui surveille le fichier auquel renvoie npgsql, et lorsque le fichier change, vous devez lire ce fichier et analyser les informations, puis appeler log4net avec cette information.

Vous avez toujours le problème que log4net pensera que tous les appels proviennent de votre routine et non pas npgsql et les traces de la pile sont gâchées. Cela ne fonctionnerait également que si npgsql était en train de verrouiller, ouvrir, écrire et fermer le fichier chaque fois qu'une entrée de journal était faite.

1

d'abord ajouter log4net à votre solution, la plus simple est d'utiliser NuGet: si vous faites ceci: install-Package log4net vous devez installer Npgsql: install-Package Npgsql

dans votre web fichier .config vous ajoutez ces éléments: (vous devez utiliser l'application.configuration pour solution non Web)

À la 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

Voilà comment je l'ai fait et il semble fonctionner raisonnablement bien. Notez que je partage la commande déconnectant à une appender séparée, car il devient assez bavard ...

D'abord, ajoutez avant de faire d'autres appels à Npgsql:

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

Maintenant, vous devez ajouter dans la classe de fournisseur d'enregistrement:

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); 
      } 
     } 
    } 
} 

Et vous avez aussi besoin de la classe enregistreur réelle:

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

Notez également que dans Npgsql 3.2.0: "La journalisation personnalisée de Npgsql a été remplacée par [Microsoft.Extensions.Logging]". Cependant, en 3.2.2 il a été annulé: "En raison des nombreuses plaintes, l'utilisation de Microsoft.Extensions.Logging par Npgsql 3.2 a été abandonnée, et la journalisation fonctionne maintenant comme dans Npgsql 3.1". refs: https://github.com/npgsql/Npgsql/releases –

Questions connexes