NLOG 数据库目标无法连接

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

我有一个 ASP.NET Core 7 Web api,我试图在其中添加 NLOG 数据库目标。 它绝对不是日志记录,内部日志为我提供了两条不同的消息,具体取决于我到目前为止所尝试的内容。 配置有些不对劲,但我真的不明白是什么。

第一次尝试:

Error DatabaseTarget(Name=DatabaseSiteLog): Error when writing to database. Exception: Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
 ---> System.ComponentModel.Win32Exception (2): The system cannot find the file specified.
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open()
   at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString, LogEventInfo logEventInfo)
   at NLog.Targets.DatabaseTarget.EnsureConnectionOpen(String connectionString, LogEventInfo logEventInfo)
   at NLog.Targets.DatabaseTarget.WriteLogEventSuppressTransactionScope(LogEventInfo logEvent, String connectionString)
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:2,State:0,Class:20

最近的尝试:

Error DatabaseTarget(Name=DatabaseSiteLog): Error when writing to database. Exception: System.InvalidOperationException: The ConnectionString property has not been initialized.
   at Microsoft.Data.SqlClient.SqlConnection.PermissionDemand()
   at Microsoft.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open()
   at NLog.Targets.DatabaseTarget.OpenConnection(String connectionString, LogEventInfo logEventInfo)
   at NLog.Targets.DatabaseTarget.EnsureConnectionOpen(String connectionString, LogEventInfo logEventInfo)
   at NLog.Targets.DatabaseTarget.WriteLogEventSuppressTransactionScope(LogEventInfo logEvent, String connectionString)

应用程序设置.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.EntityFrameworkCore.Database.Comman": "Information"
    }
  },
  "ConnectionStrings": {
    "ApiContext": "Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = SiteDb"
  }
}

NLog.config 目标:

<target xsi:type="Database"
        name="DatabaseSiteLog"
        connectionString="${configsetting:name=ConnectionStrings.ApiContext}">
    <commandText>
        INSERT INTO dbo.Log columns Values values
    </commandText>
    <parameter name="@columns" layout="${values}" />
</target>
database asp.net-core nlog
1个回答
1
投票

我们很难找到您问题的根本原因。所以我创建了一个全新的项目并为您编写了这个教程,您可以按照步骤检查您身边的问题。

在检查步骤之前,我们需要确保已经安装了如下所示的软件包。

enter image description here

第 1 步:在 localdb 或 SQL Server 中创建数据库,我们将其命名为

NLogDB
。并先创建一个存储过程和一个表。

enter image description here

/****** Object: Table [dbo].[NLog] Script Date: 7/20/2023 4:41:17 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[NLog] 
(
    [ID]          INT            IDENTITY (1, 1) NOT NULL,
    [MachineName] NVARCHAR (200) NULL,
    [Logged]      DATETIME       NOT NULL,
    [Level]       VARCHAR (5)    NOT NULL,
    [Message]     NVARCHAR (MAX) NOT NULL,
    [Logger]      NVARCHAR (300) NULL,
    [Properties]  NVARCHAR (MAX) NULL,
    [Callsite]    NVARCHAR (300) NULL,
    [Exception]   NVARCHAR (MAX) NULL
);

/****** Object: SqlProcedure [dbo].[NLog_AddEntry_p] Script Date: 7/20/2023 4:41:48 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

 
CREATE PROCEDURE [dbo].[NLog_AddEntry_p] (
  @machineName nvarchar(200),
  @logged datetime,
  @level varchar(5),
  @message nvarchar(max),
  @logger nvarchar(300),
  @properties nvarchar(max),
  @callsite nvarchar(300),
  @exception nvarchar(max)
) AS
BEGIN
  INSERT INTO [dbo].[NLog] (
    [MachineName],
    [Logged],
    [Level],
    [Message],
    [Logger],
    [Properties],
    [Callsite],
    [Exception]
  ) VALUES (
    @machineName,
    @logged,
    @level,
    @message,
    @logger,
    @properties,
    @callsite,
    @exception
  );
END

第2步:确保可以在VS2022中连接数据库。您可以点击

View
->
SQL Server Object Explorer
。然后找到数据库并右键单击它,然后检查属性。并找到连接字符串。

enter image description here

enter image description here

enter image description here

我这边的连接字符串如下,如果你使用的是SQL Server,你也可以使用这种方式来生成连接字符串。

Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=NLogDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False

第 3 步:在项目中创建一个

nlog.config
文件。

enter image description here

<?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="Info"
      throwConfigExceptions="true"
      internalLogFile="c:\temp\internal-nlog-AspNetCore7.txt">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <!-- File Target for all log messages with basic details -->
    <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-AspNetCore7-all-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />

    <!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="c:\temp\nlog-AspNetCore7-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}" />

    <!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
    <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
  <!-- the targets to write to -->
 
    <target name="db"
            xsi:type="Database"
            connectionString="${configsetting:item=ConnectionStrings.NLog}"
            dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"
            commandType="StoredProcedure"
            commandText="[dbo].[NLog_AddEntry_p]"
            >
      <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="@properties"     layout="${all-event-properties:separator=|}" />
      <parameter name="@callsite"       layout="${callsite}" />
      <parameter name="@exception"      layout="${exception:tostring}" />
    </target>
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="allfile" />

    <!--Output hosting lifetime messages to console target for faster startup detection -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />

    <!--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="ownFile-web" />
   <logger name="*" minlevel="Trace" writeTo="db" />
  </rules>
</nlog>

第 4 步:将其注册到您的

Program.cs
文件中。

using NLog.Web;

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

            // Add NLog for Logging
            builder.Logging.ClearProviders();
            builder.Host.UseNLog();

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            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();
        }
    }
}

第5步:在

appsettings.json
文件中添加连接字符串。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "NLog": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=NLogDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
  },
  "AllowedHosts": "*"
}

第6步:在控制器中注入NLog:

using Microsoft.AspNetCore.Mvc;

namespace Asp.Net.Core7.Nlog.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
            _logger.LogTrace(1, "NLog injected into HomeController");
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            _logger.LogInformation("Hello, this is the index!");
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

第7步:运行应用程序并测试api方法,然后检查文件中的日志:

enter image description here

第8步:检查数据库中的日志:

enter image description here

这就是所有的步骤和代码,如果你能在你身边找到根本原因,比如SQL Server配置相关或其他,你可以在下面添加注释,这可以帮助更多的用户找到本教程。

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