Если информации, доступной в HttpContext, достаточно, то есть, если отправленный вами пример кода дает вам правильный ответ (за исключением проблемы MDC), и вы просто не захотите писать:
HttpContext context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
MDC.Set("user", HttpContext.Current.User.Identity.Name);
}
так часто, что вы можете добавить имя пользователя в свой журнал "автоматически", написав свой собственный шаблон PatternLayoutConverter для log4net.Их довольно легко написать, и вы можете настроить их в своей конфигурации регистрации log4net так же, как встроенные.
См. Этот вопрос для одного примера того, как написать собственный PatternLayoutConverter:
Настраиваемое свойство log4net PatternLayoutConverter (с индексом)
Используя пример по этой ссылке, вы можете сделать что-то вроде этого:
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);
}
}
}
Вы можете настроить это вlog4net примерно так:
//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>
Кроме того, вы можете создать другие конвертеры шаблонов, которые используют параметр Option (см. пример по ссылке выше), чтобы извлечь конкретный элемент из HttpContext.Current.Items илиHttpContext.Current.Session collection.
Что-то вроде:
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);
}
}
}
}
Вы также можете найти эти ссылки полезными:
http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html
Здесь,блоггер предлагает другое решение для регистрации значений из HttpContext, чем то, что я предложил.Прочтите сообщение в блоге, чтобы увидеть его описание проблемы и ее решение.Чтобы подвести итог решения, он сохраняет объект в GlobalDiagnosticContext (более современное название для MDC).Когда log4net регистрирует значение объекта, он использует ToString ().Реализация его объекта извлекает значение из HttpContext:
Итак, вы можете сделать что-то вроде этого:
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 "";
}
}
Вы можете поместить экземпляр этого объекта в GlobalDiagnosticContext (MDC)в начале вашей программы, и она всегда будет возвращать правильное значение, так как она обращается к HttpContext.Current.
MDC.Set("user", new HttpContextUserNameProvider());
Это кажется намного проще, чем я предлагал!
Для полноты, если кто-тохочет знать, как сделать то же самое в NLog, NLog, по-видимому, делает большинство / всю информацию HttpContext доступной через своих aspnet- * LayoutRenderers:
https://github.com/nlog/nlog/wiki/Layout-Renderers