Bonjour,
Je fais un site web en asp.net/mvc4/razor.
Je veux que dans chacune de mes logs apparaisse le nom de l'utilisateur qui a fait l'action.
J'avais jusqu'à maintenant ce paramétrage:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<log4net>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="RollingLogFileAppender" />
    </root>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="c:\Logs\\Web.log" />
      <staticLogFileName value="false" />
      <param name="PreserveLogFileNameExtension" value="true" />
      <param name="appendToFile" value="true" />
      <param name="rollingStyle" value="Date" />
      <param name="datePattern" value="yyyyMMdd" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="conversionPattern" value="%date - %level - thread(%thread) - %property{login} - %logger: %message%newline" />
      </layout>
    </appender>
  </log4net>
La première page du site a un formulaire où on demande le login (j'ai omis la partie mot de passe afin que mon exemple soit plus simple). Ce formulaire redirige vers l'action suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
public ActionResult HomeFilter(string login)
        {
            Session["login"] = login;
            GlobalContext.Properties["login"] = login;
 
            log4net.Config.XmlConfigurator.Configure();
 
            log.Info("calls HomeFilter");
...
        }
Et en haut de chacune des classes où je veux fair du log, j'ai ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
public static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log.Info("blablabla");
Et je viens de réaliser que ça marche bien lors de mes tests entre moi et moi-même sur mon unique poste mais qu'en fait ça ne marchera pas avec plusieurs utilisateurs, le nom qui apparaîtra dans les logs sera en fait celui de la dernière personne connectée...
Est-ce que vous pouvez me dire comment setter correctement ma variable %property{login} s'il vous plaît?
J'ai une idée qui serait la suivante :
au lieu d'appeler directement log.Info("blablabla"); , je l'encapsulerais autour d'une méthode du genre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Log
    {
        private readonly object _lock = new object();
 
        void Mylog(ILog l, string msg)
        {
            lock (_lock)
            {
                GlobalContext.Properties["login"] = HttpContext.Current.Session["login"];
                l.Info(msg);
            }
        }
    }
et je supprimerais donc GlobalContext.Properties["login"] = login; de l'action de mon controller initial et l'appel serait Mylog(log, "blablabla");
Je mettrais ILog en paramètre car là je simplifie la fonction, mais il faudra que je gère si je veux du log.Info, du log.Error etc...
Je n'arrive juste pas à me rendre compte si cela est thread-safe et si ça marche? Au lieu de GlobalContext, log4net propose aussi d'autres contexts comme ThreadContext par exemple (cf http://logging.apache.org/log4net/re.../contexts.html).
Merci pour vos retours,
Julien