![](/img/trans.png)
[英]How to Log Client Ip, Browser Name and User Name using Log4net in asp.net?
[英]How to conditionally capture user name with log4net layout pattern in ASP.NET web api 2?
我有一個Web api 2應用程序,截至目前已配置Windows身份驗證。 該應用程序具有一個專用的應用程序池,稱為FlowManager,它使用ApplicationPoolIdentity運行。
這是web.config文件中的log4net配置,我在其中使用PatternLayout中的%username記錄用戶名。
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\Logs\FlowManager\FlowManager.log" />
<param name="AppendToFile" value="true" />
<datePattern value="yyyyMMdd" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="3" />
<maximumFileSize value="2MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{MM-dd-yyyy HH:mm:ss:fff} %-5level [%property{log4net:HostName}, %username] %m%n" />
</layout>
</appender>
<root>
<level value="TRACE" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
所以在我要登錄的應用程序代碼中,我正在使用
logger.Debug("Request entered"); //in a http module
logger.Debug("Test log entry"); //in the api controller
它正在按預期方式生成日志。
2016年6月8日12:06:07:287調試[1178959001DLP, IIS APPPOOL \\ FlowManager ]輸入的請求
2016年6月8日12:06:09:257調試[1178959001DLP, IIS APPPOOL \\ FlowManager ]測試日志條目
現在,要求我記錄經過身份驗證的用戶名。 我發現這個很好的問題是使用log4net捕獲用戶名,並按照說明進行操作並能夠實現。 這是新的log4net配置的樣子。 為了簡單起見,我僅顯示log4net的PatternLayout部分。
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{MM-dd-yyyy HH:mm:ss:fff} %-5level [%property{log4net:HostName}, %HTTPUser] %m%n" />
<converter>
<name value="HTTPUser" />
<type value="LoggerExtentions.ContextUserPatternConverter" />
</converter>
</layout>
如您所見,我創建了一個自定義模式轉換器來捕獲用戶名。
using System.Threading;
using System.Web;
using log4net.Core;
using log4net.Layout.Pattern;
namespace LoggerExtentions
{
/// <summary>
/// Log4net custom pattern converter to log context user instaed of app pool user
/// </summary>
public class ContextUserPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
var userName = string.Empty;
var context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
userName = context.User.Identity.Name;
}
else
{
var threadPincipal = Thread.CurrentPrincipal;
if (threadPincipal != null && threadPincipal.Identity.IsAuthenticated)
{
userName = threadPincipal.Identity.Name;
}
}
writer.Write(userName);
}
}
}
這給我以下日志消息
06-08-2016 13:06:09:123 DEBUG [1178959001DLP,]請求已輸入
2016年6月8日13:06:09:257調試[1178959001DLP, DOMAIN \\ johnkl ]測試日志條目
如果您發現從http模塊創建的日志條目沒有用戶名,我會得到它,因為尚未使用經過身份驗證的用戶設置上下文。 在這種情況下,我被要求記錄由log4net捕獲的默認用戶名。 我的問題是如何實現? 每當我沒有HttpContext用戶時,如何提供log4net捕獲的默認用戶名? 有沒有辦法在log4net模式布局中提供條件語句? 還是其他替代選項?
看來我能夠找到另一種捕獲它的方法。 由於log4net%username默認為應用程序池標識,因此我將自定義模式轉換器修改為回退為應用程序池標識。
更新:發現loggingEvent參數具有UserName屬性。 我已經修改了代碼以使用該代碼,而不是直接調用System.Security.Principal.WindowsIdentity.GetCurrent()。Name。 LoggingEvent.UserName內部調用相同的方法,但我決定使用loggingEvent.UserName,以防萬一log4net實現將來修改其行為。
public class ContextUserPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
var userName = string.Empty;
var context = HttpContext.Current;
if (context != null && context.User != null && context.User.Identity.IsAuthenticated)
{
userName = context.User.Identity.Name;
}
else
{
var threadPincipal = Thread.CurrentPrincipal;
if (threadPincipal != null && threadPincipal.Identity.IsAuthenticated)
{
userName = threadPincipal.Identity.Name;
}
}
if (string.IsNullOrEmpty(userName))
{
userName = loggingEvent.UserName;
//get app pool identity
//userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
writer.Write(userName);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.