web-dev-qa-db-fra.com

Comment enregistrer les messages de trace avec log4net?

J'utilise log4net pour consigner le message de journal d'écriture dans un fichier journal défilant. 

Maintenant, je voudrais également rediriger tous les messages de trace de System.Diagnostics.Trace vers ce fichier journal. Comment puis-je configurer cela? J'ai essayé de trouver quoi que ce soit à ce sujet dans la documentation de log4net, mais sans succès. Est-ce possible?

La raison pour laquelle je veux le faire est que je suis intéressé par les messages de trace d'une bibliothèque tierce.

<log4net>
    <appender name="R1" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\MyService.log" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <maxSizeRollBackups value="10" />
      <datePattern value="yyyyMMdd" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>
</log4net>
68
Dirk Vollmar

Selon la suggestion de Rune, j'ai implémenté un TraceListener de base qui sortait vers log4net:

public class Log4netTraceListener : System.Diagnostics.TraceListener
{
    private readonly log4net.ILog _log;

    public Log4netTraceListener()
    {
        _log = log4net.LogManager.GetLogger("System.Diagnostics.Redirection");
    }

    public Log4netTraceListener(log4net.ILog log)
    {
        _log = log;
    }

    public override void Write(string message)
    {
        if (_log != null)
        {
            _log.Debug(message);
        }
    }

    public override void WriteLine(string message)
    {
        if (_log != null)
        {
            _log.Debug(message);
        }
    }
}
67
Dirk Vollmar

Je ne sais pas si log4net prend cela en charge, mais vous pouvez implémenter votre propre écouteur de trace qui l’a fait.

TraceListener n'a pas trop de méthodes à implémenter et tout ce que vous feriez est de transmettre les valeurs à log4net afin que cela soit facile à faire.

Pour ajouter un écouteur de trace personnalisé, vous pouvez soit modifier votre application.config/web.config, soit l'ajouter dans le code à l'aide de Trace.Listeners.Add(new Log4NetTraceListener());.

25
Rune Grimstad

Merci,

J'y suis allé avec la réponse de Dirk qui s'est affinée un peu. 

public class Log4netTraceListener : System.Diagnostics.TraceListener
{
    private readonly log4net.ILog _log;

    public Log4netTraceListener()
        : this(log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType))
    {

    }

    public Log4netTraceListener(log4net.ILog log)
    {
        _log = log;
    }

    public override void Write(string message) => _log?.Debug(message);

    public override void WriteLine(string message) => _log?.Debug(message);
}
1
Billy Jake O'Connor

Selon les réponses ci-dessus, il existe une implémentation ici (ce lien est floconneux, mais j'ai trouvé le code source): 

https://code.google.com/archive/p/cavity/

Pour traiter grossièrement le problème (décrit dans les commentaires d'une réponse précédente) de la trace interne log4net issue de la classe LogLog, j'ai vérifié si cette classe était la source de la trace en inspectant le cadre de pile (ce que cette implémentation avait déjà fait) et en ignorant ces messages de trace:

    public override void WriteLine(object o, string category)
    {
        // hack to prevent log4nets own diagnostic trace getting fed back
        var method = GetTracingStackFrame(new StackTrace()).GetMethod();
        var declaringType = method.DeclaringType;
        if (declaringType == typeof(LogLog))
        {
            return;
        }
        /* rest of method writes to log4net */
    }

L'utilisation d'un TraceAppender créera toujours les problèmes décrits dans les commentaires ci-dessus. 

1
Neil Dodson