90 votes

Comment configurer log4net de manière programmatique à partir de zéro (pas de configuration)

C'est une mauvaise idée, je sais, mais... Je veux configurer log4net de manière programmatique à partir de zéro, sans fichier de configuration. Je travaille sur une application de journalisation simple pour moi et mon équipe à utiliser pour un groupe d'applications départementales relativement petites dont nous sommes responsables. Je veux qu'elles soient toutes enregistrées dans la même base de données. L'application de journalisation est juste une enveloppe autour de log4net avec le AdoNetAppender préconfiguré.

Toutes les applications sont déployées par ClickOnce, ce qui pose un petit problème pour le déploiement du fichier de configuration. Si le fichier de configuration faisait partie du projet de base, je pourrais définir ses propriétés pour le déployer avec l'assemblage. Mais il fait partie d'une application liée, je n'ai donc pas la possibilité de le déployer avec l'application principale. (Si ce n'est pas vrai, que quelqu'un me le fasse savoir).

Probablement parce que c'est une mauvaise idée, il ne semble pas y avoir beaucoup d'exemples de code disponible pour configurer programmatiquement log4net à partir de zéro. Voici ce que j'ai jusqu'à présent.

Dim apndr As New AdoNetAppender()
apndr.CommandText = "INSERT INTO LOG_ENTRY (LOG_DTM, LOG_LEVEL, LOGGER, MESSAGE, PROGRAM, USER_ID, MACHINE, EXCEPTION) VALUES (@log_date, @log_level, @logger, @message, @program, @user, @machine, @exception)"
apndr.ConnectionString = connectionString
apndr.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
apndr.CommandType = CommandType.Text
Dim logDate As New AdoNetAppenderParameter()
logDate.ParameterName = "@log_date"
logDate.DbType = DbType.DateTime
logDate.Layout = New RawTimeStampLayout()
apndr.AddParameter(logDate)
Dim logLevel As New AdoNetAppenderParameter()
logLevel.ParameterName = "@log_level"
'And so forth...

Après avoir configuré tous les paramètres pour apndr J'ai d'abord essayé ce...

Dim hier As Hierarchy = DirectCast(LogManager.GetRepository(), Hierarchy)
hier.Root.AddAppender(apndr)

Ça n'a pas marché. Alors, comme un coup dans le vide, j'ai essayé ceci à la place.

BasicConfigurator.Configure(apndr)

Cela n'a pas fonctionné non plus. Quelqu'un a-t-il de bonnes références sur la façon de configurer log4net de manière programmatique à partir de zéro, sans fichier de configuration ?

0 votes

125voto

Todd Stout Points 2631

Voici un exemple de classe qui crée la configuration de log4net complètement en code. Je dois mentionner que la création d'un logger via une méthode statique est généralement considérée comme mauvaise, mais dans mon contexte, c'est ce que je voulais. Quoi qu'il en soit, vous pouvez découper le code pour répondre à vos besoins.

using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;

namespace dnservices.logging
{
public class Logger
{
    private PatternLayout _layout = new PatternLayout();
    private const string LOG_PATTERN = "%d [%t] %-5p %m%n";

    public string DefaultPattern
    {
        get { return LOG_PATTERN; }
    }

    public Logger()
    {
        _layout.ConversionPattern = DefaultPattern;
        _layout.ActivateOptions();
    }

    public PatternLayout DefaultLayout
    {
        get { return _layout; }
    }

    public void AddAppender(IAppender appender)
    {
        Hierarchy hierarchy = 
            (Hierarchy)LogManager.GetRepository();

        hierarchy.Root.AddAppender(appender);
    }

    static Logger()
    {
        Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
        TraceAppender tracer = new TraceAppender();
        PatternLayout patternLayout = new PatternLayout();

        patternLayout.ConversionPattern = LOG_PATTERN;
        patternLayout.ActivateOptions();

        tracer.Layout = patternLayout;
        tracer.ActivateOptions();
        hierarchy.Root.AddAppender(tracer);

        RollingFileAppender roller = new RollingFileAppender();
        roller.Layout = patternLayout;
        roller.AppendToFile = true;
        roller.RollingStyle = RollingFileAppender.RollingMode.Size;
        roller.MaxSizeRollBackups = 4;
        roller.MaximumFileSize = "100KB";
        roller.StaticLogFileName = true;
        roller.File = "dnservices.txt";
        roller.ActivateOptions();
        hierarchy.Root.AddAppender(roller);

        hierarchy.Root.Level = Level.All;
        hierarchy.Configured = true;
    }

    public static ILog Create()
    {
        return LogManager.GetLogger("dnservices");
    }
}

}

6 votes

+1 de ma part, il semble que vous ayez trouvé la réponse à la question de savoir comment faire cela de manière purement programmatique, sans fichier de configuration.

0 votes

Eh bien, cela ne fonctionne toujours pas, un fichier texte vide est créé, mais rien n'y est écrit :(

0 votes

@aloneguid Pouvez-vous m'envoyer un petit exemple où rien n'est écrit dans le fichier journal ? Mon profil SO contient une adresse électronique.

38voto

Jonathan Rupp Points 10900

Une façon de procéder que j'ai utilisée dans le passé est d'inclure le fichier de configuration en tant que ressource intégrée, et d'utiliser simplement la méthode suivante log4net.Config.Configure(Stream) .

De cette façon, je pouvais utiliser la syntaxe de configuration qui m'était familière, sans avoir à me soucier du déploiement d'un fichier.

2 votes

Le nom complet de la méthode est log4net.Config.XmlConfigurator.Configure (comme dans le lien).

33voto

Pavel Chuchuva Points 12220

Une solution plus concise :

var layout = new PatternLayout("%-4timestamp [%thread] %-5level %logger %ndc - %message%newline");
var appender = new RollingFileAppender {
    File = "my.log",
    Layout = layout
};
layout.ActivateOptions();
appender.ActivateOptions();
BasicConfigurator.Configure(appender);

N'oubliez pas d'appeler ActivateOptions método:

La méthode ActivateOptions doit être appelée sur cet objet après que les propriétés de configuration ont été définies. Tant que la méthode ActivateOptions n'est pas appelée, cet objet est dans un état indéfini et ne doit pas être utilisé.

0 votes

L'utilisation de la surcharge BasicConfigurator.Configure(IAppender) permet d'éviter beaucoup de manipulations, merci.

1 votes

+1 pour celui-là. Appel à ActivateOptions() est certainement manquante ou du moins pas assez soulignée dans la documentation.

5voto

Joe Points 60749

Comme Jonathan dit, l'utilisation d'une ressource est une bonne solution.

C'est un peu restrictif dans la mesure où le contenu des ressources intégrées sera fixé au moment de la compilation. J'ai un composant de journalisation qui génère un XmlDocument avec une configuration de base de Log4Net, en utilisant des variables définies comme appSettings (par exemple, le nom du fichier pour un RollingFileAppender, le niveau de journalisation par défaut, peut-être le nom de la chaîne de connexion si vous voulez utiliser un AdoNetAppender). Puis j'appelle log4net.Config.XmlConfigurator.Configure pour configurer Log4Net en utilisant l'élément Root du XmlDocument généré.

Ensuite, les administrateurs peuvent personnaliser la configuration "standard" en modifiant quelques appSettings (typiquement niveau, nom de fichier, ...) ou peuvent spécifier un fichier de configuration externe pour avoir plus de contrôle.

3voto

RodKnee Points 81

Je ne peux pas dire dans l'extrait de code de la question si le "'And so forth..." inclut la très importante apndr.ActivateOptions() qui est indiquée dans la réponse de Todd Stout. Sans ActivateOptions(), l'appender est inactif et ne fera rien, ce qui pourrait expliquer pourquoi il échoue.

0 votes

Je ne pense pas que j'avais ça là-dedans. C'est peut-être ça le problème. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X