我正在将ASP.NET Core与NLog一起使用,并使用NLog.Web.AspNetCore块软件包将其替换为原始ASP.NET Core记录器。
NLog包含有用的Func()委托签名,该签名仅在启用相应的日志记录级别时才允许执行参数评估:
static readonly Logger log = LogManager.GetCurrentClassLogger();
log.Trace(() => request.JsonSerializer.Serialize(body));
我正在将ASP.NET与NLog一起使用,但听起来此功能不可用:
private ILogger<MyController> log;
log.Trace(() => request.JsonSerializer.Serialize(body));
在尝试为自己编写一个方法之前,我想知道是否错过了什么,我还没有发现使用带有NLog的ASP.NET Core的带有委托参数的此类日志记录方法。
答案 0 :(得分:1)
Microsoft.Extensions.Logging抽象及其构建方式中没有这样的东西,做这样的事情并不容易。尽管您可以轻松地向其中添加扩展方法,并且实际上所有日志调用都是 扩展方法,但基本的Log
方法是确定是否记录某些内容的方法,因为它是唯一记录内容的方法实际上有权访问配置的日志级别。
话虽这么说,日志记录抽象使用的东西可能使做类似的事情成为可能。为此,请考虑ILogger.Log
方法的签名:
void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
如您所见,实际上并没有传递字符串,而只是传递了state
和formatter
。在默认的扩展方法中,状态是FormattedLogValues
对象,而格式化程序只是在状态上调用ToString()
的方法,即FormattedLogValues
对象。
FormattedLogValues
是实际构建格式化字符串的地方,也是进行结构化日志记录的地方。因此,序列化日志消息中的某些对象实际上是一个坏主意;您可以直接将其传递给记录器。
但是您可以在这里为Log
提供您自己的重载,该重载采用一个函数代替,然后将其包装到某个状态对象中,该对象在调用ToString()
时执行该函数。
答案 1 :(得分:0)
Asp.net核心2.0的Nlog实现没有太大变化。
设置1:,您需要安装Nuget软件包Click here
设置2:,您需要使用以下配置创建Nlog配置文件。
<nlog>
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target filename="${basedir}/logs/${shortdate}.log" layout="
-----------Time Stamp: ${longdate}----------
Log Level: ${level}${newline}
Logger Name : ${logger}${newline}
Log Message : ${message}${newline}
Exception Message: ${event-context:item=ErrorMessage}${newline}
Browser Detail: ${event-context:item=BrowserDetail}${newline}
Session Id: ${event-context:item=SessionId}" name="file" xsi:type="File">
<target br="" connectionstring="${gdc:item=defaultConnection}" dbprovider="Oracle.ManagedDataAccess.Client.OracleConnection,
Oracle.ManagedDataAccess, Version=2.0.12.0, Culture=neutral, PublicKeyToken=89b483f429c47342" keepconnection="false" name="database" xsi:type="Database">
commandText="INSERT INTO TableName (LOG_LEVEL,LOGGER_NAME,SESSION_ID,BROWSER_DETAIL) values(:LOGLEVEL,:LOGGERNAME,:SESSIONID,:BROWSERDETAIL)">
<parameter layout="${level:uppercase=true}" name="LOGLEVEL">
<parameter layout="${logger}" name="LOGGERNAME">
<parameter layout="${event-context:item=SessionId}" name="SESSIONID">
<parameter layout="${event-context:item=BrowserDetail}" name="BROWSERDETAIL">
</parameter></parameter></parameter></parameter></target>
</target></targets>
<rules>
<!--All logs, including from Microsoft-->
<logger minlevel="Error" name="*" writeto="file">
<logger minlevel="Trace" name="*" writeto="database">
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger final="true" maxlevel="Info" name="Microsoft.*">
<!-- BlackHole -->
</logger></logger></logger></rules>
</nlog>
设置3:需要更新启动文件。
NLog.GlobalDiagnosticsContext.Set("defaultConnection", Connection string); NLog.LogManager.LoadConfiguration(env.ContentRootPath + "\\NLog.config");
设置4:我们已经创建了自定义Nlog管理器。
public static class NLogManager {
public static ILogger _logger = NLog.LogManager.GetCurrentClassLogger();
public static void InfoLog(NLogData nLogData) {
LogEventInfo theEvent = new LogEventInfo(LogLevel.Info, NLogManager._logger.Name, nLogData.Message);
SetLogEventInfo(theEvent, nLogData);
_logger.Log(theEvent);
}
public static void DebugLog(NLogData nLogData) {
LogEventInfo theEvent = new LogEventInfo(LogLevel.Debug, NLogManager._logger.Name, nLogData.Message);
SetLogEventInfo(theEvent, nLogData);
_logger.Log(theEvent);
}
public static void ErrorLog(NLogData nLogData) {
LogEventInfo theEvent = new LogEventInfo(LogLevel.Error, NLogManager._logger.Name, nLogData.Message);
SetLogEventInfo(theEvent, nLogData);
_logger.Log(theEvent);
}
}
用于记录的自定义事件参数:
private static void SetLogEventInfo(LogEventInfo theEvent, NLogData nLogData) {
theEvent.Properties["SessionId"] = nLogData.SessionId;
theEvent.Properties["BrowserDetail"] = nLogData.BrowserDetail;
}
用于NLog日志记录的模型。
public class NLogData {
public string SessionId {
get;
set;
}
public string BrowserDetail {
get;
set;
}
}