web-dev-qa-db-fra.com

impossible de faire fonctionner log4net avec le service Windows .net

J'ai un service Windows avec un app.config et un log4net.config.

app.config:

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net configSource="log4net.config" />

log4net.config:

<log4net>
  <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
    <param name="File" value="D:\Projects\Integration\Interface Module\bin\Logs\MyFirstLogger.log"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="2" />
    <maximumFileSize value="1MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
    </layout>
  </appender>

  <root>
    <level value="ALL" />
    <appender-ref ref="LogFileAppender" />
  </root>
</log4net>

J'ai aussi ajouté ceci dans AssemblyInfo.cs:

[Assembly: log4net.Config.XmlConfigurator(Watch = true)]

Et dans un de mes cours, j'ai:

private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

et 

_log.Info(content);

J'ai donné à à tous les utilisateurs des autorisations complètes sur mon dossier Journaux. 

Mon dossier bin (depuis lequel le service est exécuté) a à la fois mon app.config et log4net.config.

Mais aucun fichier de journalisation n'a été généré. Quels paramètres ai-je manqués?

Mis à jour le 4 mars 2014

Si vous utilisez un fichier de configuration distinct, comme je l'ai fait (log4net.config), n'oubliez pas de définir le paramètre Copy to output directory sur Copy always dans l'explorateur de solutions.

31
Null Reference

Par sa conception, Log4Net est 

fail-stop, nous voulons dire que log4net ne lève pas d'exceptions inattendues au moment de l'exécution provoquant potentiellement le blocage de votre application

Il est donc très difficile de comprendre ce qui cause le problème.

Comment activer le débogage interne de log4net?

FROM FAQ - http://logging.Apache.org/log4net/release/faq.html

  • Le débogage interne peut également être activé en définissant une valeur dans le fichier de configuration de l'application .__ (et non dans le fichier de configuration log4net, .__, sauf si les données de configuration log4net sont incorporées dans le fichier Config de l'application). Le paramètre de l'application log4net.Internal.Debug doit être défini sur la valeur true. Par exemple:
<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
            <appSettings>
                <add key="log4net.Internal.Debug" value="true"/>
            </appSettings> 
</configuration>

Ce paramètre est lu immédiatement au démarrage et tous les messages de débogage internes seront émis.

  • . Pour activer le débogage interne de log4net par programme, vous devez définir la propriété log4net.Util.LogLog.InternalDebugging sur true . Évidemment, plus tôt cela est défini, plus le débogage sera produit.

Voici donc une classe personnalisée que j'ai créée pour log4Net - car le fichier de configuration était très déroutant, j'ai créé cette classe d'assistance

  • vous pouvez lancer autant d'appéditeurs que vous le souhaitez dans toutes les applications Donc, si une DLL appelle une autre DLL, les deux peuvent lancer des appenders et les deux les annexes fonctionneront.
  • vous pouvez aussi fermer l’appendeur et (comme dans le cas d’un appender de fichier) puis l'envoyer par email
Log4NetFileHelper log = new Log4NetFileHelper();
        log.Init(); //Initialize
        log.AddConsoleLogging(); //Add Console Logging
        log.AddFileLogging(Path.Combine(AssemblyDirectory, "BatchConsole.log")); 
        log.AddFileLogging(Path.Combine(AssemblyDirectory,"BatchConsole_error.log"),log4net.Core.Level.Error); 

Définissez cette propriété sur True log4net.Util.LogLog.InternalDebugging = true;

public class Log4NetFileHelper
{
    private string  DEFAULT_LOG_FILENAME=string.Format("application_log_{0}.log",DateTime.Now.ToString("yyyyMMMdd_hhmm"));
    Logger root;
    public Log4NetFileHelper()
    {

    }

    public virtual void Init()
    {
        root = ((Hierarchy)LogManager.GetRepository()).Root;
        //root.AddAppender(GetConsoleAppender());
        //root.AddAppender(GetFileAppender(sFileName));
        root.Repository.Configured = true;
    }

    #region Public Helper Methods
    #region Console Logging
    public virtual void AddConsoleLogging()
    {
        ConsoleAppender C = GetConsoleAppender();
        AddConsoleLogging(C);
    }

    public virtual void AddConsoleLogging(ConsoleAppender C)
    {
        root.AddAppender(C);
    }
    #endregion

    #region File Logging
    public virtual FileAppender AddFileLogging()
    {
        return AddFileLogging(DEFAULT_LOG_FILENAME);
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath)
    {
        return AddFileLogging(sFileFullPath, log4net.Core.Level.All);
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold)
    {
        return AddFileLogging(sFileFullPath, threshold,true);  
    }

    public virtual FileAppender AddFileLogging(string sFileFullPath, log4net.Core.Level threshold, bool bAppendfile)
    {
        FileAppender appender = GetFileAppender(sFileFullPath, threshold , bAppendfile);
        root.AddAppender(appender);
        return appender;
    }

    public virtual SmtpAppender AddSMTPLogging(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
    {
        SmtpAppender appender = GetSMTPAppender(smtpHost, From, To, CC, subject, threshhold);
         root.AddAppender(appender);
         return appender;
    }

    #endregion


    public log4net.Appender.IAppender GetLogAppender(string AppenderName)
    {
        AppenderCollection ac = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Appenders;

        foreach(log4net.Appender.IAppender appender in ac){
            if (appender.Name == AppenderName)
            {
                return appender;
            }
        }

        return null;
    }

    public void CloseAppender(string AppenderName)
    {
        log4net.Appender.IAppender appender = GetLogAppender(AppenderName);
        CloseAppender(appender);
    }

    private void CloseAppender(log4net.Appender.IAppender appender)
    {
        appender.Close();
    }

    #endregion

    #region Private Methods

    private SmtpAppender GetSMTPAppender(string smtpHost, string From, string To, string CC, string subject, log4net.Core.Level threshhold)
    {
        SmtpAppender lAppender = new SmtpAppender();
        lAppender.Cc = CC;
        lAppender.To = To;
        lAppender.From = From;
        lAppender.SmtpHost = smtpHost;
        lAppender.Subject = subject;
        lAppender.BufferSize = 512;
        lAppender.Lossy = false;
        lAppender.Layout = new
        log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
        lAppender.Threshold = threshhold;
        lAppender.ActivateOptions();
        return lAppender;
    }

    private ConsoleAppender GetConsoleAppender()
    {
        ConsoleAppender lAppender = new ConsoleAppender();
        lAppender.Name = "Console";
        lAppender.Layout = new 
        log4net.Layout.PatternLayout(" %message %n");
        lAppender.Threshold = log4net.Core.Level.All;
        lAppender.ActivateOptions();
        return lAppender;
    } 
    /// <summary>
    /// DETAILED Logging 
    /// log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
    ///  
    /// </summary>
    /// <param name="sFileName"></param>
    /// <param name="threshhold"></param>
    /// <returns></returns>
    private FileAppender GetFileAppender(string sFileName , log4net.Core.Level threshhold ,bool bFileAppend)
    {
        FileAppender lAppender = new FileAppender();
        lAppender.Name = sFileName;
        lAppender.AppendToFile = bFileAppend;
        lAppender.File = sFileName;
        lAppender.Layout = new 
        log4net.Layout.PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %message (%logger{1}:%line)%n");
        lAppender.Threshold = threshhold;
        lAppender.ActivateOptions();
        return lAppender;
    }

    //private FileAppender GetFileAppender(string sFileName)
    //{
    //    return GetFileAppender(sFileName, log4net.Core.Level.All,true);
    //}

    #endregion

    private void  ConfigureLog(string sFileName)
    {


    }
}
22
dekdev

Veuillez noter que lorsque le processus est exécuté en tant que service Windows, Environment.CurrentDirectory sera "C:\Windows\system32".

Donc, si vous mettez le fichier de configuration log4net (log4net.config) à côté de votre * .exe, vous pouvez utiliser le code suivant pour configurer log4net.

var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
XmlConfigurator.Configure(new FileInfo(Path.Combine(assemblyFolder, "log4net.config")));
16
YantingChen

Voici la config qui fonctionne pour moi.

AssemblyInfo.cs

[Assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4net.config", Watch = true)]

Log4net.Config

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
            <param name="File" value="C:\TEMP\Logs.txt"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock,log4net" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="2" />
            <maximumFileSize value="1MB" />
            <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout,log4net">
            <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
        </layout>
    </appender>
    <root>
         <level value="ALL" />
         <appender-ref ref="LogFileAppender" />
    </root>
</log4net>

Code C #

private static readonly log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(class_name));

J'ai cette configuration dans le projet de bibliothèque de classe C # et tous les autres projets utilisent cette référence de projet pour consigner les exceptions.

10
Deeptechtons

Après vérification et revérifier ... :-)

Il suffit d’appeler XmlConfigurator.Configure(); avant de créer le consignateur (une seule fois).

Content de vous aider,

Ofir

9
Ofir

Lorsque vous dites "Tous les utilisateurs" ont des autorisations complètes sur le répertoire des journaux, cela inclut-il les comptes de service?

Vérifiez que LocalService, NetworkService, LocalSystem, etc. ont des autorisations (en fonction du contexte dans lequel le service est exécuté).

En outre, en supposant que vous disposiez d'un faisceau pour exécuter le service en tant qu'application, la journalisation fonctionne-t-elle lorsqu'elle est exécutée en tant qu'utilisateur?

Si l'application ne fonctionne pas correctement, vous avez un problème avec la configuration log4net (que d'autres réponses ont tenté de résoudre).

3
l33tmike

Désolé si certaines d'entre elles semblent évidentes, mais voici ce que je vérifierais:

  • Assurez-vous que les propriétés de votre fichier log4net.config Copier vers la sortie sont définies sur Copier toujours, vérifiez en recherchant le fichier dans votre répertoire bin

  • Notez également à partir de la documentation log4net liée aux propriétés de AssemblyInfo.cs:

L’utilisation d’attributs peut être une méthode plus claire pour définir le lieu de chargement de la configuration de l’application. Cependant, cela vaut la peine notant que les attributs sont purement passifs. Ce ne sont que des informations . Par conséquent, si vous utilisez des attributs de configuration, vous devez appeler log4net pour lui permettre de lire les attributs. Un simple appel à LogManager.GetLogger provoquera les attributs sur l'assembly appelant être lu et traité. Par conséquent, il est impératif de faire un enregistrement de l'appel le plus tôt possible lors du démarrage de l'application, et certainement avant que des assemblages externes aient été chargés et invoqué .

  • Pour résoudre ce problème, vous pouvez essayer de passer de la propriété de niveau d'assemblage à un appel de configuration explicite.

    XmlConfigurator.Configure ();

    devrait être suffisant.

  • Je fais toujours de log4net.config un fichier de configuration complet, en commençant par

     <? xml version = "1.0" encoding = "utf-8"?> 
     <configuration> 
     <configSections> 
     <section name = "log4net" 
     type = "log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
     </ configSections> 
     <log4net> 
    ...
     </ log4net> 
     </ configuration> 
    

Dans app.config, vous n'avez besoin d'aucun élément lié à log4net tant que votre fichier de configuration est log4net.config.

3
SteveM

Pourriez-vous s'il vous plaît télécharger votre application afin que je puisse la déboguer moi-même? 

quelques-uns, je recommande de vérifier:

  1. remplace tous les "\" dans votre chemin de fichier par "\"

  2. mettre toute la configuration log4net incorporée dans le fichier de configuration de l'application.

  3. activer le débogage de log4net .__ ( voir ici )

  4. essayez une configuration différente. juste obtenir un exemple de configuration quelque part sur Internet.

  5. juste pour être sûr, je donnerais un maximum d'autorisations pour tous les utilisateurs à votre répertoire de journalisation

  6. essayez de désinstaller le service et réinstallez-le.

1
Uri Abramson

log4net s'exécute sous les privilèges de l'utilisateur actif. Assurez-vous que l'utilisateur actif dispose des droits pour créer/modifier/supprimer le fichier texte spécifié.

1
user2373845

si vous avez un fichier séparé pour log4net.config. Avez-vous défini la propriété suivante:

Copier dans le répertoire de sortie = Copier toujours

0
shawtza

Le service Windows avec connexion système n'a pas accès à tous les répertoires présents . Essayez donc de vous connecter à "C:\Utilisateurs\Public\AppData" . Cela a fonctionné pour moi

0
Vaibhav Revankar

J'ai vu votre code a un problème mineur dans AssemblyInfo.cs.

remplacez votre code par:

où {{folder_path}} est le chemin de votre log4net.config

0
Essie