NLog无法将日志存入数据库:ASP.NET 4.6.2 Web Forms配置问题
问题排查与修复方案
核心问题点
- 自定义属性引用错误:你使用的
${applicationId}、${login}等不是NLog内置渲染器,也未正确引用日志事件中的自定义属性,需改用${event-properties:item=属性名}格式获取传递的属性值。 - LogDate参数未正确配置:日志调用时未传递
LogDate属性,直接引用${event-properties:LogDate}会导致值为空,建议使用NLog内置的${date}渲染器自动生成日志时间。 - 数据库Provider配置不准确:
"mssql"不是标准的Provider名称,需根据使用的SQL驱动指定正确值,比如"System.Data.SqlClient"(旧版驱动)或"Microsoft.Data.SqlClient"(新版驱动)。 - 日志属性传递方式问题:直接在
Logger.Info中传递匿名对象,NLog无法自动识别为事件属性,需用WithProperty链式调用或构造LogEventInfo来传递属性。
修复后的代码示例
Global.asax.cs配置修改
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); void Application_Start(object sender, EventArgs e) { var dbTarget = new DatabaseTarget("DbTarget") { // 根据实际SQL驱动选择Provider DBProvider = "System.Data.SqlClient", CommandText = "INSERT INTO dbo.ApplicationLog (ApplicationId, Login, HostName, VisitedPage, PageURL, ReferrerURL, LogDate) values (@ApplicationId, @Login, @HostName, @VisitedPage, @PageURL, @ReferrerURL, @LogDate);", ConnectionString = "Server=DBSERVER;Database=ApplicationLogging_Test;Trusted_Connection=True;" }; // 正确引用日志事件属性 dbTarget.Parameters.Add(new DatabaseParameterInfo("@ApplicationId", "${event-properties:item=ApplicationId}")); dbTarget.Parameters.Add(new DatabaseParameterInfo("@Login", "${event-properties:item=Login}")); dbTarget.Parameters.Add(new DatabaseParameterInfo("@HostName", "${event-properties:item=HostName}")); dbTarget.Parameters.Add(new DatabaseParameterInfo("@VisitedPage", "${event-properties:item=VisitedPage}")); dbTarget.Parameters.Add(new DatabaseParameterInfo("@PageURL", "${event-properties:item=PageURL}")); dbTarget.Parameters.Add(new DatabaseParameterInfo("@ReferrerURL", "${event-properties:item=ReferrerURL}")); // 使用NLog内置日期渲染器,自动生成日志时间 dbTarget.Parameters.Add(new DatabaseParameterInfo("@LogDate", "${date:format=yyyy-MM-dd HH:mm:ss.fff}")); // 配置日志规则并生效 var config = new LoggingConfiguration(); config.AddRule(LogLevel.Info, LogLevel.Fatal, dbTarget); LogManager.Configuration = config; } void Session_Start(object sender, EventArgs e) { // 假设以下变量已完成赋值 string message = "Session initialized"; string Login = User.Identity.Name; string HostName = Request.UserHostName; string VisitedPage = Request.Path; string PageURL = Request.Url.ToString(); string ReferrerURL = Request.UrlReferrer?.ToString() ?? string.Empty; // 用WithProperty链式传递自定义属性 Logger.Info(message) .WithProperty("ApplicationId", 1049) .WithProperty("Login", Login) .WithProperty("HostName", HostName) .WithProperty("VisitedPage", VisitedPage) .WithProperty("PageURL", PageURL) .WithProperty("ReferrerURL", ReferrerURL); }
额外排查步骤
- 验证数据库权限:确保应用程序池的运行身份(Windows身份验证场景下)拥有数据库连接及
ApplicationLog表的写入权限。 - 开启NLog内部日志:添加以下代码到
Application_Start开头,排查NLog内部错误:InternalLogger.LogFile = @"C:\temp\nlog-internal.log"; InternalLogger.LogLevel = LogLevel.Debug; - 检查表结构匹配:确认
ApplicationLog表的字段类型与传入值兼容,比如ApplicationId为int类型、LogDate为datetime类型等。
内容的提问来源于stack exchange,提问作者tnk479
相关产品推荐
相关产品推荐

