如何在NLog中实现类似Log4Net的错误码日志,保留消息与整数错误码
解决方案
问题根源
你的调用logger.Error(3, "消息内容")被C#重载解析匹配到了NLog的Error(object message, params object[] args)方法,导致错误码3被当成了日志消息,第二个参数被当作未使用的格式化参数,最终只输出了3。
无需修改现有代码的解决步骤
1. 全局拦截日志事件,修正内容
在应用启动时添加以下代码,拦截NLog的日志事件,将错误码从消息字段转移到EventId,同时把原参数中的字符串作为日志消息:
using NLog; // 在应用初始化阶段执行(比如Program.Main或Startup.Configure) var config = LogManager.Configuration; foreach (var rule in config.LoggingRules) { foreach (var target in rule.Targets) { target.BeforeLogEvent += (sender, e) => { // 仅处理Error级别的目标调用 if (e.LogEvent.Level != LogLevel.Error) return; // 判断是否是错误码+消息的调用模式 if (int.TryParse(e.LogEvent.Message, out int errorCode) && e.LogEvent.Parameters?.Length == 1 && e.LogEvent.Parameters[0] is string actualMessage) { // 修正日志事件:设置正确的消息和错误码 e.LogEvent.Message = actualMessage; e.LogEvent.EventId = new EventId(errorCode); // 清空参数避免后续格式化干扰 e.LogEvent.Parameters = Array.Empty<object>(); } }; } } // 重新加载配置使生效 LogManager.ReconfigExistingLoggers();
2. 配置NLog目标,分别存储错误码和消息
根据不同的日志目标调整配置,确保错误码以整数类型存储,消息正常输出:
文件日志示例
<target xsi:type="File" name="fileLog" fileName="logs/${shortdate}.log"> <layout>${longdate} [${level}] ErrorId: ${eventid:format=D} - ${message}</layout> </target>
EventLog示例
<target xsi:type="EventLog" name="eventLog" source="YourAppName" log="Application"> <layout>${message}</layout> <eventId>${eventid:format=D}</eventId> </target>
数据库日志示例(适配预留的错误码列)
<target xsi:type="Database" name="dbLog" connectionString="YourDbConnectionString"> <commandText> INSERT INTO Logs (ErrorId, Message, LogLevel, CreateTime) VALUES (@ErrorId, @Message, @LogLevel, @CreateTime) </commandText> <!-- 错误码列指定为整数类型 --> <parameter name="@ErrorId" layout="${eventid:format=D}" dbType="Int32" /> <parameter name="@Message" layout="${message}" /> <parameter name="@LogLevel" layout="${level}" /> <parameter name="@CreateTime" layout="${date:format=yyyy-MM-dd HH:mm:ss}" /> </target>
说明
- 该方案仅处理
Error(int, string)格式的调用,不会影响其他正常日志调用(如logger.Error("普通消息")或带占位符的格式化日志)。 - 数据库配置中
dbType="Int32"确保错误码以整数类型存入预留列,避免字符串转整数的问题。
内容的提问来源于stack exchange,提问作者cr45h0v3rwr173
相关产品推荐
相关产品推荐

