资讯动态

别再只会写文件了!NLog 5.0 实战:5分钟搞定日志同时输出到文件、控制台和MySQL数据库

发布时间:2026/8/23 8:08:46 来源:尧图企业网站定制
NLog 5.0 多目标日志实战从文件到数据库的全链路配置在分布式系统开发中日志就像飞机的黑匣子记录了系统运行的每一个关键时刻。但很多开发者在使用NLog时往往止步于基础的文件日志记录错失了多目标输出的强大能力。本文将带你突破常规用5分钟实现日志同时输出到文件、控制台和MySQL数据库的三重保障方案。1. 环境准备与基础配置1.1 必要的NuGet包安装首先通过NuGet为项目添加必要的支持包Install-Package NLog -Version 5.0 Install-Package NLog.Config Install-Package NLog.Database Install-Package MySql.Data对于ASP.NET Core项目还需要额外添加Install-Package NLog.Web.AspNetCore1.2 配置文件结构设计NLog的强大之处在于其灵活的配置系统。我们创建一个NLog.config文件设置自动复制到输出目录?xml version1.0 encodingutf-8 ? nlog xmlnshttp://www.nlog-project.org/schemas/NLog.xsd xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance autoReloadtrue throwExceptionsfalse !-- 目标定义区 -- targets !-- 各目标配置将在此处添加 -- /targets !-- 路由规则区 -- rules !-- 日志路由规则将在此处定义 -- /rules /nlog2. 三目标并行输出配置2.1 文件目标 - 本地持久化保障文件日志是最基础的存储方式配置时需注意归档策略target namelogfile xsi:typeFile fileName${basedir}/logs/${shortdate}.log layout${longdate}|${level:uppercasetrue}|${logger}|${message}${exception:formatToString} archiveAboveSize10485760 maxArchiveFiles30 concurrentWritestrue/关键参数说明archiveAboveSize: 单个文件最大10MBmaxArchiveFiles: 保留最近30个归档文件concurrentWrites: 启用并发写入2.2 控制台目标 - 实时调试利器开发阶段控制台输出必不可少target nameconsole xsi:typeColoredConsole layout${time}|${level:uppercasetrue}|${logger}|${message} errorStreamtrue highlight-row conditionlevel LogLevel.Error foregroundColorRed/ highlight-row conditionlevel LogLevel.Warn foregroundColorYellow/ /target2.3 数据库目标 - 集中管理方案MySQL存储便于后续日志分析需要先创建日志表CREATE TABLE app_logs ( id BIGINT NOT NULL AUTO_INCREMENT, timestamp DATETIME NOT NULL, level VARCHAR(10) NOT NULL, logger VARCHAR(255) NOT NULL, message TEXT NOT NULL, exception TEXT, machine_name VARCHAR(50), process_id INT, PRIMARY KEY (id), INDEX idx_level (level), INDEX idx_timestamp (timestamp) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;对应的NLog配置target namedatabase xsi:typeDatabase dbProviderMySql.Data.MySqlClient.MySqlConnection, MySql.Data connectionStringServerlocalhost;Databaselogs_db;Uidroot;Pwdyourpassword;SslModeNone commandText INSERT INTO app_logs ( timestamp, level, logger, message, exception, machine_name, process_id ) VALUES ( timestamp, level, logger, message, exception, machine_name, process_id ); /commandText parameter nametimestamp layout${date:formatyyyy-MM-dd HH\:mm\:ss} / parameter namelevel layout${level} / parameter namelogger layout${logger} / parameter namemessage layout${message} / parameter nameexception layout${exception:formatToString} / parameter namemachine_name layout${machinename} / parameter nameprocess_id layout${processid} / /target3. 智能路由与性能优化3.1 分级路由策略不同环境需要不同的日志策略rules !-- 开发环境输出所有级别到控制台 -- logger name* minlevelTrace writeToconsole finaltrue condition${environment:variableASPNETCORE_ENVIRONMENT}Development / !-- 生产环境组合输出 -- logger name* minlevelInfo writeTologfile,database / logger nameMicrosoft.* minlevelWarn writeTologfile,database finaltrue / !-- 特定命名空间的详细日志 -- logger nameMyApp.* minlevelDebug writeTologfile / /rules3.2 性能调优技巧多目标输出时需注意性能影响异步写入配置targets asynctrue !-- 所有target定义 -- /targets缓冲策略target namedatabase xsi:typeBufferingWrapper bufferSize100 flushTimeout2000 target xsi:typeDatabase ... / /target批量插入优化target namedatabase xsi:typeDatabase ... commandText INSERT INTO app_logs (...) VALUES parameter nametimestamp layout${date} / !-- 其他参数 -- parameter namebulk_insert layout${all-event-properties:formattimestamp\${date}\,level\${level}\...} / /commandText /target4. 高级应用场景4.1 结构化日志处理NLog 5.0支持JSON格式输出target namejsonFile xsi:typeFile fileName${basedir}/logs/structured-${shortdate}.json layout xsi:typeJsonLayout attribute nametimestamp layout${date:formato} / attribute namelevel layout${level} / attribute namemessage layout${message} / attribute nameproperties encodefalse layout typeJsonLayout includeAllPropertiestrue / /attribute /layout /target4.2 动态日志路由根据条件动态改变日志目标var config LogManager.Configuration; var dbTarget config.FindTargetByName(database) as DatabaseTarget; if(IsProductionEnvironment) { dbTarget.ConnectionString GetProductionConnectionString(); config.RemoveTarget(console); } else { dbTarget.ConnectionString GetTestConnectionString(); } LogManager.ReconfigExistingLoggers();4.3 自定义日志字段扩展日志上下文信息// 设置全局自定义字段 GlobalDiagnosticsContext.Set(AppVersion, 1.2.0); // 在配置中使用 parameter nameapp_version layout${gdc:itemAppVersion} /5. 故障排查与日常维护5.1 常见问题解决方案问题现象可能原因解决方案数据库无日志连接字符串错误启用内部日志检查错误文件未生成目录权限不足检查运行账户权限性能下降同步写入阻塞启用异步目标日志丢失缓冲区未刷新减小flushTimeout5.2 监控建议定期检查日志文件磁盘空间监控数据库日志表增长情况设置日志文件大小报警阈值对日志数据库建立适当的索引-- 定期维护SQL示例 OPTIMIZE TABLE app_logs; ANALYZE TABLE app_logs;5.3 内部日志启用当配置不生效时启用NLog内部日志nlog internalLogFileC:\temp\nlog-internal.log internalLogLevelTrace throwConfigExceptionstrue /nlog在实际项目中使用这套方案后我们发现数据库写入偶尔会出现延迟。通过分析发现是网络波动导致最终通过增加本地缓存和重试机制解决了问题。对于高并发场景建议采用消息队列作为日志中转而非直接写入数据库。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价