NLog之记录日志到数据库
NLog之记录日志到数据库
前言
在上节“NLog之封装”介绍了对Nlog封装,使用更方便,而且简单的记录了将NLog日志的信息保存在文件中,不过很多时候,一些重要的Error信息,需要保存在数据库中。所以继续按照这个思路,完善了下上次的Demo。这节讲述将Nlog的记录日志到数据库。
环境
l Win10
l VS2022
l .NET5.0
l SQLServer2012
配置文件
首先需要知道配置文件中的记录等级Level
l Trace - 最常见的记录信息,一般用于普通输出
l Debug - 同样是记录信息,不过出现的频率要比Trace少一些,一般用来调试程序
l Info - 信息类型的消息
l Warn - 警告信息,一般用于比较重要的场合
l Error - 错误信息
l Fatal - 致命异常信息。一般来讲,发生致命异常之后程序将无法继续执行。
接下来就对配置文件里的一些参数做一下说明。这里主要介绍nlog,target,rules,variable,这些常用的。
nlog
l autoReload:配置文件修改后,是否重新自动加载。
targets
主要关心targets下配置的声明目标参数
l xsi:type:记录类型【File,Console,Database,Mail,Network,Debugger 】常用的就是File,Console,Database。
l name:目标名称,在rules里会用到。
l fileName:输出文件名。若类型不是File,则不需要该参数
l layout:输出内容
rules
主要关心logger配置
l name - 日志源/记录者的名字 (允许使用通配符*)
l minlevel - 该规则所匹配日志范围的最低级别
l maxlevel - 该规则所匹配日志范围的最高级别
l level - 该规则所匹配的单一日志级别
l levels - 该规则所匹配的一系列日志级别,由逗号分隔。
l writeTo - 规则匹配时日志应该被写入的一系列目标,由逗号分隔。
l final - 标记当前规则为最后一个规则。其后的规则即时匹配也不会被运行。
如果设置了minlevel,则大于等于当前级别的都会被记录下来。
用来声明变量,键值对的形式
l name- 键
l value- 值
<variable name="logdir" value="/var/log"/>
Nlog自带变量汇总
l ${basedir}:应用程序当前目录
l ${shortdate}:短日期【2022-01-06】
l ${longdate}:长日期【2022-01-06 14:05:20.4023】
l ${logger}: 记录器的名字
l ${level}:记录等级【Trace,Debug,Info,Warn,Error,Fatal】
l ${uppercase}:转大写
l ${message}:调用Nlog时输入的内容
l ${callsite-linenumber}:文件行号
l ${hostname}:主机名
l ${environment} 环境变量
l ${exception} exception信息
l ${machinename} 名称
l ${mdc} 映射诊断
l ${mdlc} 异步映射诊断上下文
l ${ndc} 线程结构
l ${ndlc} 异步线程
l ${newline} 文字换行
l ${nlogdir} nlog.dll目录。
l ${performancecounter} 述性能计数器。
l ${processid} 当前进程标识符
l ${processinfo} 运行信息
l ${processname} 当前进程的名称。
l ${processtime} 该时间过程中格式HH:MM:ss.mmm。
l ${qpc} 高精度定时器,基于返回的值从queryperformancecounter(任选地)转换为秒。
l ${registry} 从注册表中的值。
l ${sequenceid} ID
l ${shortdate} 短时间 格式YYYY-MM-DD。
l ${sl-appinfo} Silverlight应用。
l ${specialfolder} 文件夹路径
l ${stacktrace} - 堆栈跟踪渲染器。
l ${tempdir} 临时目录中。
l ${threadid} 当前线程的标识符。
l ${threadname} 当前线程。
l ${ticks} 当前日期和时间。
l ${time} 24小时格式HH:MM:ss.mmm。
l KaTeX parse error: Expected '}', got 'EOF' at end of input: {var} {var}-提供新的变量(4.1)
l ${windows-identity} indows线程标识信息(用户名)
项目实践
在上节“NLog之封装”项目基础上改造。项目如下:
修改接口项目
修改上节新建的项目“Yak.Nlog.Api”,引用封装的“Yak.Nlog.Framework”程序集。
Step1:引用MSSQL的依赖,“System.Data.SqlClient”。
<ItemGroup> <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.3" /> </ItemGroup> |
Step2: 修改类的ConfigureServices。
public void ConfigureServices(IServiceCollection services) { #region Nlog记日志 //将日志记录到数据库 NLog.LogManager.LoadConfiguration("nlog.config").GetCurrentClassLogger(); NLog.LogManager.Configuration.Variables["connectionString"] = Configuration.GetConnectionString("DefaultConnection"); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); //避免日志中的中文输出乱码 #endregion #region 添加异常处理过滤器 services.AddControllers(options => options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync))); #endregion services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<INLogHelper, NLogHelper>(); services.AddControllers(); } |
Step3:修改WeatherForecast控制器。
public IEnumerable<WeatherForecast> Get() { #region 测试日志 _logger.LogTrace("开发阶段调试,可能包含敏感程序数据", 1); _logger.LogDebug("开发阶段短期内比较有用,对调试有益。"); _logger.LogInformation("跟踪程序的一般流程。"); _logger.LogWarning("警告信息!因程序出现故障或其他不会导致程序停止的流程异常或意外事件。"); _logger.LogError("错误信息。因某些故障停止工作"); _logger.LogCritical("程序或系统崩溃、遇到灾难性故障!!!"); #endregion int.Parse("asd");//抛出异常 var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } |
Step4:修改Program。
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }).ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(LogLevel.Trace); }) .UseNLog();// NLog: Setup NLog for Dependency injection } |
Step5:修改nlog.config。
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="true" internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> <!-- optional, add some variables https://github.com/nlog/NLog/wiki/Configuration-file#variables --> <variable name="myvar" value="myvalue"/> <!-- --> <targets> <target name="console" xsi:type ="Console" /> <target name="debugger" xsi:type="Debugger" layout="${date:format=HH\:mm\:ss.fff}: ${message}" /> <target name="error_file" xsi:type="File" fileName="${basedir}/Logs/Error/${shortdate}/error.txt" maxArchiveFiles="30" layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> <target name="info" xsi:type="File" fileName="${basedir}/Logs/Info/${shortdate}/info.txt" maxArchiveFiles="30" layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" /> <target xsi:type="Null" name="blackhole" /> <target name="database" xsi:type="Database"> <connectionString>${var:connectionString}</connectionString> <commandText> INSERT INTO sys_log (Date,Account,Level,ActionType,Message,Detail) Values(@Date,@Account,@Level,@ActionType,@Message,@Detail) </commandText> <parameter name = "@Account" layout = "${callsite}"/> <parameter name = "@ActionType" layout = "WebApi"/> <parameter name = "@Level" layout = "${level}" /> <parameter name = "@Message" layout = "${message}" /> <parameter name = "@Date" layout = "${date}" /> <parameter name = "@Detail" layout = "${exception:tostring}" /> </target> </targets> <rules> <logger name="*" writeTo="console" /> <logger name="*" minlevel="Debug" writeTo="debugger" /> <logger name="*" minlevel="Error" writeTo="error_file" /> <logger name="*" level="Info" writeTo="info" /> <logger name="*" writeTo="database" /> </rules> </nlog> |
Step6:修改appsettings.json。
增加数据库连接字符串
{ "ConnectionStrings": { "DefaultConnection": "Data Source=.;database=CapDb;uid=sa;pwd=sa123456" }, "Logging": { "LogLevel": { "Default": "Trace", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" } |
在数据库中创建保存日志表
建表语句:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[sys_log]( [Id] [int] IDENTITY(1,1) NOT NULL, [Date] [datetime] NOT NULL, [Account] [nvarchar](100) NULL, [Level] [nvarchar](50) NULL, [ActionType] [nvarchar](50) NULL, [Message] [nvarchar](max) NULL, [Detail] [nvarchar](max) NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO |
运行结果
按Ctrl+F5快速运行。
在数据库中保存的日志如下:
保存的文件:
总结
既然要把日志保存到数据库中,就必须要建表,数据库连接等设置。NLog很好地支持了这些功能,配置方便。
另外一个好消息,上海的阳性病例已经降到1W下了,估计5月中旬要解封了,内心也挺复杂的,都习惯了在家办公了,说不定以后在家办公是一种趋势吧!
鸣谢
https://blog.csdn.net/u012869793/article/details/122341838
https://xguan.blog.csdn.net/article/details/103537555?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_paycolumn_v3&utm_relevant_index=2
源码
本文来自博客园,作者:{春光牛牛,yak},转载请注明原文链接:https://www.cnblogs.com/yakniu/p/16219617.html
欢迎各位大佬们评论指正
QQ讨论群:610129902
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义