Asp.Net Core用NLog记录日志操作方法
需求
1.日志自动写入到数据库、写入到文件
2.appsettings.json数据库连接更改后,不需要去改NLog中的连接地址,启动网站或项目时自动检测变动然后去更改,以appsettings.json为准,保持同步。
3.写入日志时,除了NLog自带的字段,新增LogType自定义字段记录日志类型,例如网站日志、中间件日志等
4.统一的写日志方法,不用每次get一个logger对象(或依赖注入)来记日志
安装包
在nuget中安装NLog和NLog.Web.AspNetCore,这两个是NLog相关的包。
还需要安装NLog写入数据库的数据库适配器,我这里写入到MySQL数据库,所以安装MySql.Data
如果是写入到SQLserver数据库,需要安装Microsoft.Data.SqlClient
NLog.config配置文件内容
网站根目录下新建NLog.config配置文件,记得右击该文件“属性”,复制到输出目录:“始终复制”
NLog.config文件内容:
INSERTINTOTblLogrecords (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);
配置文件解读nlog根节点:autoReload属性,true时,如果NLog.config文件有变动,会自动应用新配置(但是会有延迟,过几秒才会应用起来)internalLogLevel属性,设定后,输出的是NLog内部自己的日志记录,如果遇到NLog异常/配置文件没配好,可以把Off改为Trace或Debug来查看NlogRecords.log里的内容internalLogFile属性,可以设定路径,例如默认的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,SQLserver是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包中提供的方法layoutrender官方文档第二个target节点,可以看到name是log_file,这里的name和下方logger中writeTo属性对应xsi:type="File",即写入到文件fileName属性是文件名,这里是写入到当前目录下的logs文件夹,并且按日期归档layout属性是写入日志的格式rules节点是各个日志记录器logger的配置第一个logger配置跳过所有Microsoft组件的日志记录,final标记当前规则为最后一个规则。其后的规则即时匹配也不会被运行。第二个loggername="logdb",该日志记录器名为logdb,是适配log_database规则,即写入数据库,如果要适配多条规则,用逗号隔开其余规则可以参考https://www.nhooo.com/article/173004.htm 数据库配置数据表结构
这里数据库为TestNLog:
CREATEDATABASEIFNOTEXISTS`TestNLog`; USE`TestNLog`; --DumpingstructurefortableTestNLog.TblLogrecords CREATETABLEIFNOTEXISTS`TblLogrecords`( `Id`int(11)NOTNULLAUTO_INCREMENT, `LogDate`datetime(6)NOTNULL, `LogLevel`varchar(50)NOTNULL, `LogType`varchar(50)DEFAULTNULL, `Logger`varchar(256)NOTNULL, `Message`longtext, `MachineName`varchar(50)DEFAULTNULL, `MachineIp`varchar(50)DEFAULTNULL, `NetRequestMethod`varchar(10)DEFAULTNULL, `NetRequestUrl`varchar(500)DEFAULTNULL, `NetUserIsauthenticated`varchar(10)DEFAULTNULL, `NetUserAuthtype`varchar(50)DEFAULTNULL, `NetUserIdentity`varchar(50)DEFAULTNULL, `Exception`longtext, PRIMARYKEY(`Id`) )ENGINE=InnoDBAUTO_INCREMENT=96DEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_0900_ai_ci;
网站配置连接
appsettings.json中增加ConectionStrings节点:
"ConectionStrings":{ "MySqlConnection":"server=192.168.137.10;database=TestNLog;user=root;password=mysql@local" }
统一日志记录方法
网站下新建CommonUtils文件夹,添加NLogUtil.cs文件(包含LogType定义):
usingNLog; usingNLog.Config; usingSystem; usingSystem.ComponentModel; usingSystem.Linq; usingSystem.Xml.Linq; namespaceNLogUsage.CommonUtils { publicenumLogType { [Description("网站")] Web, [Description("数据库")] DataBase, [Description("Api接口")] ApiRequest, [Description("中间件")] Middleware } publicstaticclassNLogUtil { publicstaticLoggerdbLogger=LogManager.GetLogger("logdb"); publicstaticLoggerfileLogger=LogManager.GetLogger("logfile"); //////写日志到数据库 /// ///日志等级 /// 日志类型 /// 信息 /// 异常 publicstaticvoidWriteDBLog(LogLevellogLevel,LogTypelogType,stringmessage,Exceptionexception=null) { LogEventInfotheEvent=newLogEventInfo(logLevel,dbLogger.Name,message); theEvent.Properties["LogType"]=logType.ToString(); theEvent.Exception=exception; dbLogger.Log(theEvent); } /// ///写日志到文件 /// ///日志等级 /// 日志类型 /// 信息 /// 异常 publicstaticvoidWriteFileLog(LogLevellogLevel,LogTypelogType,stringmessage,Exceptionexception=null) { LogEventInfotheEvent=newLogEventInfo(logLevel,fileLogger.Name,message); theEvent.Properties["LogType"]=logType.ToString(); theEvent.Exception=exception; fileLogger.Log(theEvent); } /// ///确保NLog配置文件sql连接字符串正确 /// ////// publicstaticvoidEnsureNlogConfig(stringnlogPath,stringsqlConnectionStr) { XDocumentxd=XDocument.Load(nlogPath); if(xd.Root.Elements().FirstOrDefault(a=>a.Name.LocalName=="targets") isXElementtargetsNode&&targetsNode!=null&& targetsNode.Elements().FirstOrDefault(a=>a.Name.LocalName=="target"&&a.Attribute("name").Value=="log_database") isXElementtargetNode&&targetNode!=null) { if(!targetNode.Attribute("connectionString").Value.Equals(sqlConnectionStr))//不一致则修改 { //这里暂时没有考虑dbProvider的变动 targetNode.Attribute("connectionString").Value=sqlConnectionStr; xd.Save(nlogPath); //编辑后重新载入配置文件(不依靠NLog自己的autoReload,有延迟) LogManager.Configuration=newXmlLoggingConfiguration(nlogPath); } } } } }
配置NLog依赖注入
网站Program.cs文件中,在CreateHostBuilder方法中添加以下内容:
//usingNLog.Web; .ConfigureLogging(logging=>{ logging.ClearProviders(); logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); }).UseNLog();//NLog:依赖注入Nlog
完成后如下图所示:
启动项目同步连接字符串
修改网站启动Program.cs中的逻辑:
//usingNLogUsage.CommonUtils; //usingMicrosoft.Extensions.DependencyInjection; publicstaticvoidMain(string[]args) { //CreateHostBuilder(args).Build().Run(); varhost=CreateHostBuilder(args).Build(); try { using(IServiceScopescope=host.Services.CreateScope()) { IConfigurationconfiguration=scope.ServiceProvider.GetRequiredService(); //获取到appsettings.json中的连接字符串 stringsqlString=configuration.GetSection("ConectionStrings:MySqlConnection").Value; //确保NLog.config中连接字符串与appsettings.json中同步 NLogUtil.EnsureNlogConfig("NLog.config",sqlString); } //thrownewException("测试异常");//fortest //其他项目启动时需要做的事情 //code NLogUtil.WriteDBLog(NLog.LogLevel.Trace,LogType.Web,"网站启动成功"); host.Run(); } catch(Exceptionex) { //使用nlog写到本地日志文件(万一数据库没创建/连接成功) stringerrorMessage="网站启动初始化数据异常"; NLogUtil.WriteFileLog(NLog.LogLevel.Error,LogType.Web,errorMessage,newException(errorMessage,ex)); NLogUtil.WriteDBLog(NLog.LogLevel.Error,LogType.Web,errorMessage,newException(errorMessage,ex)); throw; } }
修改完成后,如下图所示:
启动验证
启动项目,可以正常记录日志到数据库和文件:
以上就是本次介绍的全部相关知识点,感谢大家的学习和对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。