Se le informazioni che è disponibile nel HttpContext è sufficiente, cioè, se il codice di esempio che hai postato ti dà la risposta giusta (tranne che per il rilascio MDC) e si sarebbe solo piuttosto semplicemente non scrivere:
HttpContext context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
MDC.Set("user", HttpContext.Current.User.Identity.Name);
}
tanto spesso, allora si potrebbe essere in grado di aggiungere il nome utente per il registro "automaticamente" scrivendo il proprio PatternLayoutConverter personalizzato per log4net. Sono abbastanza facili da scrivere e puoi configurarli nella configurazione di log log4net proprio come quelli incorporati.
Vedere questa domanda per un esempio di come scrivere un PatternLayoutConverter personalizzato:
Custom log4net property PatternLayoutConverter (with index)
Utilizzando l'esempio a quel link, si potrebbe essere in grado di fare qualcosa del genere:
namespace Log4NetTest
{
class HttpContextUserPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
string name = "";
HttpContext context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
name = context.User.Identity.Name;
}
writer.Write(name);
}
}
}
Si configurerebbe questo in log4net qualcosa del genere:
//Log HttpContext.Current.User.Identity.Name
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [User = %HTTPUser] %m%n"/>
<converter>
<name value="HTTPUser" />
<type value="Log4NetTest.HttpContextUserPatternConverter" />
</converter>
</layout>
Inoltre, è possibile creare altri convertitori di pattern che utilizzano il parametro Option (vedere l'esempio nel collegamento sopra riportato) per estrarre un elemento specifico da HttpContext.Current.Items o HttpContext.Current.Collezioni di sessione.
Qualcosa di simile:
namespace Log4NetTest
{
class HttpContextSessionPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Use the value in Option as a key into HttpContext.Current.Session
string setting = "";
HttpContext context = HttpContext.Current;
if (context != null)
{
object sessionItem;
sessionItem = context.Session[Option];
if (sessionItem != null)
{
setting = sessionItem.ToString();
}
writer.Write(setting);
}
}
}
}
namespace Log4NetTest
{
class HttpContextItemPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Use the value in Option as a key into HttpContext.Current.Session
string setting = "";
HttpContext context = HttpContext.Current;
if (context != null)
{
object item;
item = context.Items[Option];
if (item != null)
{
setting = item.ToString();
}
writer.Write(setting);
}
}
}
}
si potrebbe anche trovare questi link utili:
http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html
Qui, il blogger propone una soluzione diversa per i valori di registrazione da HttpContext di quello che ho proposto. Leggi il post del blog per vedere la sua descrizione del problema e per la sua soluzione. Per riassumere la soluzione, memorizza un oggetto in GlobalDiagnosticContext (il nome più moderno per MDC). Quando log4net registra il valore dell'oggetto che utilizza ToString(). l'attuazione del suo oggetto recupera un valore dal HttpContext:
Quindi, si potrebbe fare qualcosa di simile:
public class HttpContextUserNameProvider
{
public override string ToString()
{
HttpContext context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
return context.Identity.Name;
}
return "";
}
}
È possibile inserire un'istanza di questo oggetto nel GlobalDiagnosticContext (MDC) all'inizio del vostro programma e restituirà sempre il valore corretto poiché accede a HttpContext.Current.
MDC.Set("user", new HttpContextUserNameProvider());
Questo sembra molto più semplice di quello che ho proposto!
Per completezza, se qualcuno vuole sapere come fare la stessa cosa in NLog, NLog sembra fare la maggior parte/tutte le informazioni HttpContext disponibile tramite il suo "aspnet- *" LayoutRenderers:
https://github.com/nlog/nlog/wiki/Layout-Renderers
Non si conosce MDC, ma in una clausola else si può impostare "utente" su 'null'? – Amy
D'accordo, ma è per questo che ho aggiunto la nota sopra. Sono piuttosto stanco di impostare "utente" su null quando TUTTI gli estratti di codice appaiono esattamente come quelli che ho incollato. Lo verificherò, ma non è l'ideale se questo codice di registrazione fallisce una volta implementato in produzione con un numero maggiore di clienti rispetto al nostro DB di test. –
A partire da Log4Net versione 1.2.11 è possibile ottenere il nome utente utilizzando un modello di appender. Vedi qui http://stackoverflow.com/a/26277219/203371 –