web-dev-qa-db-fra.com

Modifier le niveau de journalisation log4net par programme

Ceci est similaire à 650694 mais aucune réponse n'a été acceptée là-bas, je ne peux pas faire fonctionner ces suggestions du tout, et je pense que je peux être dans une situation légèrement différente.

J'appelle log4net.Config.XmlConfigurator.Configure (). Mais après ce point dans le programme, je souhaite modifier le seuil de journalisation à une valeur uniquement connue au moment de l'exécution.

De l'autre question, j'ai essayé:

((log4net.Repository.Hierarchy.Logger)mylogger.Logger).Level = log4net.Core.Level.Error;

et:

var appender = new log4net.Appender.ColoredConsoleAppender();
appender.Layout = new log4net.Layout.PatternLayout(@"%date %-5level %message%newline");
appender.Threshold = log4net.Core.Level.Error;
appender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(appender);

mais aucun ne semble avoir d'effet: je vois toujours des instructions de journalisation DEBUG et INFO sur la console.

Mon intuition est que j'ajoute un nouvel appender, qui n'a aucun effet sur l'appender déclaré dans la configuration XML (qui lui dit d'imprimer les messages de niveau DEBUG), mais je n'ai pas encore de preuve pour cela.

Je fouille l'API log4net depuis un moment maintenant, et je ne le vois tout simplement pas. Y a-t-il quelque chose de simple qui me manque?

57
Ken

Aucune de ces solutions présentées ici n'a fonctionné pour moi. Il ne changeait pas à runtime

Voici ce qui a fonctionné pour moi:

((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Level = Level.Debug;
((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged(EventArgs.Empty);

Vous devez appeler RaiseConfigurationChanged après avoir apporté des modifications à sa configuration.

82
JeanT

Enfin trouvé une solution de travail, ici .

Les gros morceaux étaient:

  • besoin de définir le seuil sur tous les enregistreurs, y compris l'enregistreur racine "ne peut pas être récupéré par son nom"
  • besoin d'obtenir le niveau du LevelMap de la hiérarchie

Un grand merci à Eddie pour avoir posé de bonnes questions pointues, ce qui m'a amené à chercher sur Google les bons mots. Je n'aurais jamais compris ça tout seul.

(À part: Référentiel, Hiérarchie, Logger, RootLogger, LevelMap - je ne savais même pas qu'il était même possible de créer une bibliothèque de journalisation aussi complexe. mais il est presque impossible de faire des choses simples comme "ne pas enregistrer de messages au-dessus du seuil X". Gah!)

22
Ken

Il existe un moyen simple de le faire:

LogManager.GetRepository().Threshold = Level.Info;

Plus d'informations peuvent être trouvées ici .

8
Alex

J'ai essayé toutes ces réponses et aucune n'a fonctionné. Dans le débogueur, je pouvais voir que tous les niveaux d'enregistreur, les niveaux racine, les seuils étaient définis comme indiqué. Malgré cela, je n'ai vu aucun changement de niveau de journal dans le fichier tournant auquel je me connectais.

Ensuite, j'ai trouvé que dans le fichier de configuration, l'élément appender spécifiait également une valeur de seuil. Ainsi, lorsque je voulais changer le niveau en Debug alors que l'appender était réglé sur Warn, par exemple, cet appender n'a pas récupéré de messages supplémentaires car ils étaient en dessous du seuil. J'ai donc supprimé le seuil de la configuration de l'appender et j'ai simplement conservé la configuration de niveau.

  <root>
    <level value="Warn" />
    <appender-ref ref="RollingFile" />
  </root>

Ensuite, j'ai fini par utiliser la solution de Ken pour changer le niveau lors de l'exécution.

1
Mark Meyerovich

Si cela fonctionne pour quelqu'un, voici comment j'ai implémenté dans mon application Web un point de terminaison de niveau bascule exposé via un appel d'API, afin que je puisse changer le niveau de journalisation à la volée.

public HttpResponseMessage Post([FromBody] string logLevel)
{
    var newLevel = ToggleLogging(logLevel);

    // Create your own response here.
    return newLevel;
}

Et l'implémentation réelle

private Level ToggleLogging(string logLevel)
{

    Level level = null;

    if (logLevel != null)
    {
        level = LogManager.GetRepository().LevelMap[logLevel];
    }


    if (level == null)
    {
        level = Level.Warn;
    }

    ILoggerRepository[] repositories = LogManager.GetAllRepositories();

    //Configure all loggers to be at the same level.
    foreach (ILoggerRepository repository in repositories)
    {
        repository.Threshold = level;
        Hierarchy hier = (Hierarchy)repository;
        ILogger[] loggers = hier.GetCurrentLoggers();
        foreach (ILogger logger in loggers)
        {
            ((Logger)logger).Level = level;
        }
    }

    //Configure the root logger.
    Hierarchy h = (Hierarchy)LogManager.GetRepository();
    Logger rootLogger = h.Root;
    rootLogger.Level = level;

    return level;
}
1
agarcian

Je cherchais la même approche et j'ai constaté que la dernière version de NLog 3.2.0.0 donne l'option ci-dessous pour changer le niveau de journalisation lors de l'exécution.

 LogManager.GlobalThreshold = LogLevel.Debug;

Je pense qu'une autre approche pourrait être d'utiliser LogManager.Configuration pour remplacer les paramètres de configuration à l'aide de variables.

0
seUser

Dans mon cas, j'avais différents niveaux par défaut pour différents appenders, définissez la configuration, mais je voulais les ignorer si l'application était en mode verbeux.

J'ai utilisé ce qui suit:

var log4NetHierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
foreach (var appender in log4NetHierarchy.GetAppenders())
{
    if (appender is AppenderSkeleton appenderSkeleton)
    {
        appenderSkeleton.Threshold = Level.All;
    }
}
log4NetHierarchy.RaiseConfigurationChanged(EventArgs.Empty);
0
Jonathan Sayce