Asp.Net Core用NLog记录日志操作方法
2020-12-22 18:27
标签:stack required class filename xmlns sharp etl bsp 项目启动 需求 1.日志自动写入到数据库、写入到文件 2.appsettings.json数据库连接更改后,不需要去改NLog中的连接地址,启动网站或项目时自动检测变动然后去更改,以appsettings.json为准,保持同步。 3.写入日志时,除了NLog自带的字段,新增LogType自定义字段记录日志类型,例如网站日志、中间件日志等 4.统一的写日志方法,不用每次get一个logger对象(或依赖注入)来记日志 安装包 在nuget中安装 还需要安装NLog写入数据库的数据库适配器,我这里写入到MySQL数据库,所以安装 如果是写入到SQL server数据库,需要安装 NLog.config 配置文件内容 网站根目录下新建 NLog.config文件内容: 配置文件解读 nlog根节点: autoReload属性,true时,如果NLog.config文件有变动,会自动应用新配置(但是会有延迟,过几秒才会应用起来) internalLogLevel属性,设定后,输出的是NLog内部自己的日志记录,如果遇到NLog异常/配置文件没配好,可以把Off改为Trace或Debug来查看NlogRecords.log里的内容 internalLogFile属性,可以设定路径,例如默认的 这里数据库为TestNLog: 网站配置连接 appsettings.json中增加ConectionStrings节点: 统一日志记录方法 网站下新建CommonUtils文件夹,添加NLogUtil.cs文件(包含LogType定义): 配置NLog依赖注入 网站Program.cs文件中,在CreateHostBuilder方法中添加以下内容: 完成后如下图所示: 启动项目同步连接字符串 修改网站启动Program.cs中的逻辑: 修改完成后,如下图所示: 启动验证 启动项目,可以正常记录日志到数据库和文件: 以上就是本次介绍的全部相关知识点,感谢大家的学习和对脚本之家的支持。 Asp.Net Core用NLog记录日志操作方法 标签:stack required class filename xmlns sharp etl bsp 项目启动 原文地址:https://www.cnblogs.com/zxtceq/p/14149849.htmlNLog
和NLog.Web.AspNetCore
,这两个是NLog相关的包。MySql.Data
Microsoft.Data.SqlClient
NLog.config
配置文件,记得右击该文件“属性”,复制到输出目录:“始终复制”
"1.0"
encoding=
"utf-8"
?>
"http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
autoReload=
"true"
throwExceptions=
"false"
internalLogLevel=
"Off"
internalLogFile=
"NlogRecords.log"
>
"NLog.Web.AspNetCore"
/>
"log_database"
xsi:type=
"Database"
dbProvider=
"MySql.Data.MySqlClient.MySqlConnection, MySql.Data"
connectionString=
"server=192.168.137.10;database=TestNLog;user=root;password=mysql@local"
>
INSERT INTO TblLogrecords
(LogDate,LogLevel,LogType,Logger,Message,MachineName,MachineIp,NetRequestMethod
,NetRequestUrl,NetUserIsauthenticated,NetUserAuthtype,NetUserIdentity,Exception)
VALUES
(@LogDate,@LogLevel,@LogType,@Logger,@Message,@MachineName,@MachineIp,@NetRequestMethod
,@NetRequestUrl,@NetUserIsauthenticated,@NetUserAuthtype,@NetUserIdentity,@Exception);
"@LogDate"
layout=
"${date}"
/>
"@LogLevel"
layout=
"${level}"
/>
"@LogType"
layout=
"${event-properties:item=LogType}"
/>
"@Logger"
layout=
"${logger}"
/>
"@Message"
layout=
"${message}"
/>
"@MachineName"
layout=
"${machinename}"
/>
"@MachineIp"
layout=
"${aspnet-request-ip}"
/>
"@NetRequestMethod"
layout=
"${aspnet-request-method}"
/>
"@NetRequestUrl"
layout=
"${aspnet-request-url}"
/>
"@NetUserIsauthenticated"
layout=
"${aspnet-user-isauthenticated}"
/>
"@NetUserAuthtype"
layout=
"${aspnet-user-authtype}"
/>
"@NetUserIdentity"
layout=
"${aspnet-user-identity}"
/>
"@Exception"
layout=
"${exception:tostring}"
/>
"log_file"
xsi:type=
"File"
fileName=
"${basedir}/logs/${shortdate}.log"
layout=
"${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"
/>
"Microsoft.*"
final=
"true"
/>
"logdb"
writeTo=
"log_database"
/>
"logfile"
writeTo=
"log_file"
/>
c:\temp\nlog-internal.log
新增了extensions节点,因为引用了NLog.Web.AspNetCore
包 targets节点中是各种记录方式的配置第一个target节点,可以看到name是log_database,这里的name和下方logger中writeTo属性对应 xsi:type="Database",就是写入数据库了 dbProvider属性是数据库适配器,MySQL是MySql.Data.MySqlClient.MySqlConnection, MySql.Data
,SQL server是Microsoft.Data.SqlClient
,其他数据库适配器可在官方文档内查看 connectionString即连接字符串了 commandText子节点是插入数据库时insert语句,可以看到我这里是写入到TblLogrecords表,表结构下文会展示出来 parameter子节点是insert语句的各个参数: 有个name="@LogType"
参数,layout="${event-properties:item=LogType}",表示@LogType参数的值从event-properties中的LogType中取,这个后文会写到用法其余参数均是NLog自带的内容,aspnet-
开头的是NLog.Web.AspNetCore包中提供的方法 layout render官方文档 第二个target节点,可以看到name是log_file,这里的name和下方logger中writeTo属性对应 xsi:type="File",即写入到文件 fileName属性是文件名,这里是写入到当前目录下的logs文件夹,并且按日期归档 layout属性是写入日志的格式 rules节点是各个日志记录器logger的配置 第一个logger配置跳过所有Microsoft组件的日志记录,final 标记当前规则为最后一个规则。其后的规则即时匹配也不会被运行。第二个logger name="logdb",该日志记录器名为logdb,是适配log_database规则,即写入数据库,如果要适配多条规则,用逗号隔开其余规则可以参考https://www.jb51.net/article/173004.htm 数据库配置数据表结构
CREATE DATABASE IF NOT EXISTS `TestNLog`;
USE `TestNLog`;
-- Dumping structure
for
table TestNLog.TblLogrecords
CREATE TABLE IF NOT EXISTS `TblLogrecords` (
`Id`
int
(11) NOT NULL AUTO_INCREMENT,
`LogDate` datetime(6) NOT NULL,
`LogLevel` varchar(50) NOT NULL,
`LogType` varchar(50) DEFAULT NULL,
`Logger` varchar(256) NOT NULL,
`Message` longtext,
`MachineName` varchar(50) DEFAULT NULL,
`MachineIp` varchar(50) DEFAULT NULL,
`NetRequestMethod` varchar(10) DEFAULT NULL,
`NetRequestUrl` varchar(500) DEFAULT NULL,
`NetUserIsauthenticated` varchar(10) DEFAULT NULL,
`NetUserAuthtype` varchar(50) DEFAULT NULL,
`NetUserIdentity` varchar(50) DEFAULT NULL,
`Exception` longtext,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
"ConectionStrings"
: {
"MySqlConnection"
:
"server=192.168.137.10;database=TestNLog;user=root;password=mysql@local"
}
using
NLog;
using
NLog.Config;
using
System;
using
System.ComponentModel;
using
System.Linq;
using
System.Xml.Linq;
namespace
NLogUsage.CommonUtils
{
public
enum
LogType
{
[Description(
"网站"
)]
Web,
[Description(
"数据库"
)]
DataBase,
[Description(
"Api接口"
)]
ApiRequest,
[Description(
"中间件"
)]
Middleware
}
public
static
class
NLogUtil
{
public
static
Logger dbLogger = LogManager.GetLogger(
"logdb"
);
public
static
Logger fileLogger = LogManager.GetLogger(
"logfile"
);
///
/// 写日志到数据库
///
/// 日志等级
/// 日志类型
/// 信息
/// 异常
public
static
void
WriteDBLog(LogLevel logLevel, LogType logType,
string
message, Exception exception =
null
)
{
LogEventInfo theEvent =
new
LogEventInfo(logLevel, dbLogger.Name, message);
theEvent.Properties[
"LogType"
] = logType.ToString();
theEvent.Exception = exception;
dbLogger.Log(theEvent);
}
///
/// 写日志到文件
///
/// 日志等级
/// 日志类型
/// 信息
/// 异常
public
static
void
WriteFileLog(LogLevel logLevel, LogType logType,
string
message, Exception exception =
null
)
{
LogEventInfo theEvent =
new
LogEventInfo(logLevel, fileLogger.Name, message);
theEvent.Properties[
"LogType"
] = logType.ToString();
theEvent.Exception = exception;
fileLogger.Log(theEvent);
}
///
/// 确保NLog配置文件sql连接字符串正确
///
///
///
public
static
void
EnsureNlogConfig(
string
nlogPath,
string
sqlConnectionStr)
{
XDocument xd = XDocument.Load(nlogPath);
if
(xd.Root.Elements().FirstOrDefault(a => a.Name.LocalName ==
"targets"
)
is
XElement targetsNode && targetsNode !=
null
&&
targetsNode.Elements().FirstOrDefault(a => a.Name.LocalName ==
"target"
&& a.Attribute(
"name"
).Value ==
"log_database"
)
is
XElement targetNode && targetNode !=
null
)
{
if
(!targetNode.Attribute(
"connectionString"
).Value.Equals(sqlConnectionStr))
//不一致则修改
{
//这里暂时没有考虑dbProvider的变动
targetNode.Attribute(
"connectionString"
).Value = sqlConnectionStr;
xd.Save(nlogPath);
//编辑后重新载入配置文件(不依靠NLog自己的autoReload,有延迟)
LogManager.Configuration =
new
XmlLoggingConfiguration(nlogPath);
}
}
}
}
}
//using NLog.Web;
.ConfigureLogging(logging => {
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
}).UseNLog();
// NLog: 依赖注入Nlog
//using NLogUsage.CommonUtils;
//using Microsoft.Extensions.DependencyInjection;
public
static
void
Main(
string
[] args)
{
//CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
try
{
using
(IServiceScope scope = host.Services.CreateScope())
{
IConfiguration configuration = scope.ServiceProvider.GetRequiredService
//获取到appsettings.json中的连接字符串
string
sqlString = configuration.GetSection(
"ConectionStrings:MySqlConnection"
).Value;
//确保NLog.config中连接字符串与appsettings.json中同步
NLogUtil.EnsureNlogConfig(
"NLog.config"
, sqlString);
}
//throw new Exception("测试异常");//for test
//其他项目启动时需要做的事情
//code
NLogUtil.WriteDBLog(NLog.LogLevel.Trace, LogType.Web,
"网站启动成功"
);
host.Run();
}
catch
(Exception ex)
{
//使用nlog写到本地日志文件(万一数据库没创建/连接成功)
string
errorMessage =
"网站启动初始化数据异常"
;
NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Web, errorMessage,
new
Exception(errorMessage, ex));
NLogUtil.WriteDBLog(NLog.LogLevel.Error, LogType.Web, errorMessage,
new
Exception(errorMessage, ex));
throw
;
}
}
文章标题:Asp.Net Core用NLog记录日志操作方法
文章链接:http://soscw.com/index.php/essay/37629.html