NLog 5.3.4 未将日志写入 SQL Server 表

问题描述 投票:0回答:1

使用 ASP.NET Core 8 Web API,我尝试实现对 SQL Server 表的日志记录。

使用的 SQL Server 版本:

Microsoft SQL Server 2019 (RTM-GDR) (KB5046859) - 15.0.2130.3 (X64)
Oct 18 2024 15:25:23   
Copyright (C) 2019 Microsoft Corporation  
Express Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 19045: ) (Hypervisor)

NLog 正在记录到文本文件,但不在 SQL Server 表中创建记录。我不明白为什么。

我使用了以下参考资料:

  1. https://github.com/NLog/NLog.Web/tree/master/examples注意NLOG只有.NET 7的文档,没有.NET 8的文档。
  2. https://www.toshalinfotech.com/Blogs/ID/204/NLog-Writing-Logs-to-SQL-Server-from-Web-API
  3. https://code-maze.com/writing-logs-to-sql-server-using-nlog/

Program.cs

using NLog;
using NLog.Web;

namespace Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            var logger = NLog.LogManager.Setup()
                .LoadConfigurationFromXml("nlog.config")
                .GetCurrentClassLogger();
            try
            {
                builder.Services.AddControllers();
                builder.Services.AddEndpointsApiExplorer();
                builder.Services.AddSwaggerGen();

                builder.Logging.ClearProviders();
                builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information);
                builder.Host.UseNLog();

                var app = builder.Build();

                // Configure the HTTP request pipeline.
                if (app.Environment.IsDevelopment())
                {
                    app.UseSwagger();
                    app.UseSwaggerUI();
                }

                app.UseHttpsRedirection();

                app.UseAuthorization();

                app.MapControllers();

                app.Run();
            }
            catch (Exception exception)
            {
                // NLog: catch setup errors
                logger.Error(exception, "Stopped program because of exception");
                throw;
            }
            finally
            {
                // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
                NLog.LogManager.Shutdown();
            }
        }
    }
}

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"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="C:\Nlog\logs\internalLog.txt">
    <extensions>
        <!--enable NLog.Web for ASP.NET Core-->
        <add assembly="NLog.Web.AspNetCore"/>
    </extensions>
    <targets>
        <target xsi:type="Database"
            name="dbTarget"
            dbProvider="System.Data.SqlClient"
            commandType="TableDirect"
            connectionString="Data Source=localhost\sqlexpress;Initial Catalog=myDatabase;Integrated Security=True;Encrypt=False"
             <!-- Note I removed MachineName from the insert statement and commented out the parameter below. -->
            commandText="insert into dbo.Log (Logged, Level, Message, Logger, Exception)
                                      values (@Logged,@Level,@Message,@Logger,@Exception);">

            <!--<parameter name="@MachineName" layout="${machinename}" />-->
            <parameter name="@Logged" layout="${date}" />
            <parameter name="@Level" layout="${level}" />
            <parameter name="@Message" layout="${message}" />
            <parameter name="@Logger" layout="${logger}" />
            <parameter name="@Exception" layout="${exception:tostring}" />
        </target>
        <target name="file" xsi:type="File"
           layout="${longdate} ${level} ${logger} ${message} ${aspnet-request-url} ${exception:format=ToString}"
           fileName="C:/temp/logs/logfile.txt"
           keepFileOpen="true"
           encoding="utf-8" />
    </targets>

    <rules>
        <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
        <logger name="Microsoft.*" maxlevel="Info" final="true" />
        <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
        
        <logger name="*" minlevel="Trace" writeTo="dbTarget" />
        <logger name="*" minlevel="Trace" writeTo="file" />
    </rules>
</nlog>

HomeController

using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
    {
        private readonly ILogger<HomeController> _logger;
        
        public HomeController(ILogger<HomeController> logger) 
        {
            _logger = logger;
        } 

        [HttpGet(Name = "GetHome")]
        public string Get()
        {
            _logger.LogInformation("GetHome was called");
            return "Success";
        }
    }
}

Logfile.txt
显示创建的日志:

logfile.txt

我的数据库表:

Log Table

用于创建

Logs
表的 T-SQL 代码:

-- Note I allowed nulls in all columns except the identity 
-- to ensure that the non null constraint was not causing the issue.

CREATE TABLE [dbo].[Log]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [MachineName] [nvarchar](50) NULL,
    [Logged] [datetime] NULL,
    [Level] [nvarchar](50) NULL,
    [Message] [nvarchar](max) NULL,
    [Logger] [nvarchar](250) NULL,
    [Exception] [nvarchar](max) NULL,

    CONSTRAINT [PK_dbo.Log] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
                WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                      ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Nuget 包:

Nuget References

c# sql-server nlog .net-8.0
1个回答
0
投票

解决方案如下:

需要添加Nuget:

  1. Microsoft.Data.SQLClient
  2. NLog.数据库
  3. 删除了其他数据库相关的 Nuget 包

nlog.config 更改:

  1. 我不确定是否需要加载 NLog.Database 程序集,但我这样做了。
  2. 我还改变了dbProvider
  3. 不需要“”转义字符
<?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"
      autoReload="true"
      internalLogLevel="Trace"
      internalLogFile="C:\Nlog\logs\internalLog.txt">
    <extensions>
        <!--enable NLog.Web for ASP.NET Core-->
        <add assembly="NLog.Database"/>
        <add assembly="NLog.Web.AspNetCore"/>
    </extensions>
    <targets>
        <target xsi:type="Database"
            name="dbTarget"
            dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"
            connectionString="Data Source=localhost\myDatabase;Initial Catalog=imsLearn;Integrated Security=True;Encrypt=False;"
            commandText="insert into dbo.Log(Logged, Level, Message, Logger, Exception) values (@Logged,@Level,@Message,@Logger,@Exception);">

            <!--<parameter name="@MachineName" layout="${machinename}" />-->
            <parameter name="@Logged" layout="${date}" />
            <parameter name="@Level" layout="${level}" />
            <parameter name="@Message" layout="${message}" />
            <parameter name="@Logger" layout="${logger}" />
            <parameter name="@Exception" layout="${exception:tostring}" />
        </target>
        <target name="file" xsi:type="File"
           layout="${longdate} ${level} ${logger} ${message} ${aspnet-request-url} ${exception:format=ToString}"
           fileName="C:/temp/logs/logfile.txt"
           keepFileOpen="true"
           encoding="utf-8" />
    </targets>

    <rules>
        <!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
        <logger name="Microsoft.*" maxlevel="Info" final="true" />
        <logger name="System.Net.Http.*" maxlevel="Info" final="true" />
        
        <logger name="*" minlevel="Trace" writeTo="dbTarget" />
        <logger name="*" minlevel="Trace" writeTo="file" />
    </rules>
</nlog>

已插入记录

Logs in SQL

© www.soinside.com 2019 - 2024. All rights reserved.