ASP.NET Core - Serilog 未将日志保存到 PostgreSQL

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

我在 ASP.NET Core Web API 中使用 Serilog 时遇到问题。我想通过用列分隔事物来将 API 事件保存到数据库中。

ex.Column | ex.Value = Method | 'GET', URL | Localhost, RequestDate | 01/01/2023.

这是我的

appsetting.json

"ConnectionStrings": {
    "ConnS": "Server=localhost; Port=5432; Database=DB; User ID=postgres; Password=12345678;"
},
"Serilog":{
  "Using":["Serilog.Sinks.PostgreSQL"],
  "MinimumLevel": "Information",
  "WriteTo":[
    {
      "Name": "Console",
      "Args": {
      "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj} 
          {CustomDateTimeColumn}"
      }
    },
    {
      "Name": "PostgreSQL",
      "Args": {
         "connectionString": "", //same as above.
         "sinkOptionsSection": {
            "tableName": "logs",
            "schemaName" :  "public",
            "autoCreateSqlTable": false // because i've already migration this table.
          },
          "columnOptionsSection": {
             "customColumns" : [
                {
                  "ColumnName": "api_requestname",
                  "DataType": "nvarchar(255)",
                  "AllowNull": true,
                  "LogEventColumn": false
                },
                //Orthers
             ]
          }
      }
    }
  ],
  "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
  "Properties": { "Application": "Web_API" }
}

在我的

program.cs
我有:

using Web_API.Models;
using Microsoft.EntityFrameworkCore;
using Serilog;

// Other default build

// Configuration
var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
// Log
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();
Log.CloseAndFlush();

// Register DbContext
builder.Services.AddDbContext<AppDBContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("ConnS"))
);

// Other default builder and run

我创建了一个像这样的

AppDBContext.cs

public class AppDBContext : DbContext
{
    public AppDBContext(DbContextOptions<AppDBContext> options) : base(options) 
    {
    }

    public virtual DbSet<User> User { get; set; }
    public virtual DbSet<LogEvent> LogEvents { get; set; }
}

我的

User.cs
文件夹中有一个
LogEvent.cs
Models
可以正常工作。

让我们进入正题吧——这是我的

APILogger.cs
:

using Serilog;

namespace Web_API.Models
{
    public class APILogger
    {
        private readonly Serilog.ILogger _logger;

        public APILogger()
        {
            string connectionstring = "Server=localhost; Port=5432; Database=DB; User ID=postgres; Password=12345678;";
            _logger = new LoggerConfiguration()
                .WriteTo.PostgreSQL(
                    connectionString: connectionstring,
                    tableName: "Logs")
                .CreateLogger();
        }

        public void LogApiRequest(string Api_requestName, string Api_requestDate, string Api_method, string Api_url, string Api_body, string Api_statusCode, string Api_responseMessage, string Api_responseDate)
        {
            _logger.Information(
                "Api_requestName: {Api_requestName}, " +
                "Api_requestDate: {Api_requestDate}, " +
                "Api_method : {Api_method}," +
                "Api_url : {Api_url}," +
                "Api_body : {Api_body}," +
                "Api_statusCode: {Api_statusCode}, " +
                "Api_responseMessage : {Api_responseMessage}," +
                "Api_responseDate : {Api_responseDate}"
                , 
                Api_requestName,
                Api_requestDate,
                Api_method,
                Api_url,
                Api_body,
                Api_statusCode,
                Api_responseMessage,
                Api_responseDate
                );
        }
    }
}

这是我的 API 函数

GET
,用于从数据库获取数据,效果很好:

[HttpGet]
public IActionResult GetAirlineData()
{
    DateTime reqDT = DateTime.Now;
    string reqMethod = HttpContext.Request.Method;
    string reqPath = HttpContext.Request.Path;
    var reqBody = HttpContext.Request.Body;

    using (LogContext.PushProperty("api_requestname", "Anonymous"))
    using (LogContext.PushProperty("api_requestdate", reqDT))
    using (LogContext.PushProperty("api_method", reqMethod))
    using (LogContext.PushProperty("api_url", reqPath))
    using (LogContext.PushProperty("api_body", reqBody.ToString()))

    try
    {
        var data = _dbContext.Airline;
            
        int statusCode = HttpContext.Response.StatusCode;
        string resMessage = "Success";
        DateTime resDT = DateTime.Now;

        _logger.LogInformation("API request processed successfully - api_status: {@api_status}, api_responsemessage: {@api_responsemessage}, api_responsedate: {@api_responsedate}", statusCode.ToString(), resMessage, resDT);

        return Ok(Newtonsoft.Json.JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented));
    }
    catch (Exception ex)
    {
        int statusCode = HttpContext.Response.StatusCode;
        string resMessage = ex.Message.ToString();
        DateTime resDT = DateTime.Now;
        _logger.LogError("API request error - api_status: {api_status}, api_responsemessage: {api_responsemessage}, api_responsedate: {api_responsedate}", statusCode.ToString(), resMessage, resDT);
        return BadRequest(ex.Message);
    }
}

控制台:

API 请求处理成功 - api_status:200,api_responsemessage:成功,api_responsedate:10/11/2023 15:20:42

控制台显示日志信息,但没有保存到数据库中。那我该怎么办?

c# asp.net postgresql asp.net-web-api serilog
1个回答
0
投票

Log.CloseAndFlush();
可以关闭Serilog日志记录。如果您使用 Serilog.Sinks.Postgresql.Alternative 包,则在版本 4.0.1 中,列顺序发生了重大变化。

https://github.com/serilog-contrib/Serilog.Sinks.Postgresql.Alternative/issues/57

如果数据库中已有表,可以通过添加以下方式对列进行排序:

              "Id": {
                        "Name": "IdAutoIncrement",
                        "Order": 0
                    }

https://github.com/serilog-contrib/Serilog.Sinks.Postgresql.Alternative/blob/master/HowToUse.md#configuration-via-json-file-to-use-ordered-columns

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