Serilog MSSQL Sink不会将日志写入数据库

时间:2018-10-23 15:45:32

标签: c# serilog

我创建了一个.Net类库(4.6.2),并创建了serilog实现,该实现由其他接口(例如控制台应用程序)调用。现在,当我使用文件接收器类型时,日志将被写入文件,但是使用MSSQL接收器,日志记录就不会这样做。 正在使用autoCreateTable选项提供的列选项创建日志表

ILogger logger = new LoggerConfiguration()
      .WriteTo.MSSqlServer(connectionString,
                           tableName,
                           autoCreateSqlTable: autoCreateSqlTable,
                           restrictedToMinimumLevel: LogEventLevel.Verbose,
                           columnOptions: GetSQLSinkColumnOptions(),
                           batchPostingLimit: batchPostingLimit)          
      .CreateLogger();

我还启用了serilog的自记录功能,但未显示任何异常。找不到相同的有用解决方案。

但是正在生成日志表。我已经检查了该用户的权限,并且该权限也具有正确的权限。

下面是代码的快照。

public static class GenericLogger
{

    private static ILogger _usageLogger;
    private static ILogger _errorLogger;

    static GenericLogger()
    {
        var logTypes = LogConfigurationHelper.GetLogTypes();
        if (logTypes != null && logTypes.Count > 0)
        {
            foreach (var logType in logTypes)
            {
                ConfigureLogger(logType.Id); // Intitalizes logs based on  
//configuration.


            }
        }

        Serilog.Debugging.SelfLog.Enable(msg =>
        {
            Debug.Print(msg);
            Debugger.Break();
        });

    }

    ///The write log function
    ///
    public static void WriteError(LogDetail infoToLog)
    {
        if (infoToLog.Exception != null)
        {
            infoToLog.Message = GetMessageFromException(infoToLog.Exception);
        }

        _errorLogger.Write(LogEventLevel.Information,
                 "{Timestamp}{Product}{Layer}{Location}{Message}" +
                "{Hostname}{UserId}{UserName}{Exception}{ElapsedMilliseconds}" +
                "{CorrelationId}{CustomException}{AdditionalInfo}",
               infoToLog.TimeStamp, infoToLog.Product, infoToLog.Layer, infoToLog.Location, infoToLog.Message,
               infoToLog.Hostname, infoToLog.UserId, infoToLog.UserName, infoToLog.Exception?.ToCustomString(),
               infoToLog.ElapsedMilliseconds, infoToLog.CorrelationId, infoToLog.CustomException,
               infoToLog.AdditionalInfo);
            // To add ((IDisposable) _errrorLog).Dispose();
    }

}

2 个答案:

答案 0 :(得分:2)

下面是一些可以帮助您进行故障排除的想法:


您是否仅使用VerboseDebug事件进行测试?那可能就是原因。您没有为Serilog指定全局最低级别(仅为接收器指定了最低级别,它充当过滤器),而没有指定default minimum is Information,这意味着Verbose和{{1} }被忽略...为Serilog指定全局Debug

MinimumLevel

您要处置记录仪吗? ILogger logger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.MSSqlServer(connectionString, tableName, autoCreateSqlTable: autoCreateSqlTable, restrictedToMinimumLevel: LogEventLevel.Verbose, columnOptions: GetSQLSinkColumnOptions(), batchPostingLimit: batchPostingLimit) .CreateLogger(); 是一个“定期批处理接收器”,因此您需要确保在最后放置记录器,以强制其将日志刷新到数据库。参见Lifecycle of Loggers

Serilog.Sinks.MSSqlServer

即使您为((IDisposable) logger).Dispose(); it waits 5 seconds by default before sending the logs to the database使用1。如果您的应用在该时间段之前关闭,而您没有处置记录器,则消息将丢失。


为了进行故障排除,请使用batchPostingLimit代替AuditTo(并删除不适用于审核的WriteTo)。 batchPostingLimit是安全的,将吞噬任何异常,而WriteTo将使异常冒出来。

AuditTo

当然,一旦发现问题所在,请返回ILogger logger = new LoggerConfiguration() .AuditTo.MSSqlServer( connectionString, tableName, restrictedToMinimumLevel: LogEventLevel.Verbose, autoCreateSqlTable: true) .CreateLogger();


答案 1 :(得分:0)

在我的情况下,这是因为我的数据库用户没有登录数据库schema.table所需的权限。

我最终做了以下事情:

/* CREATE A NEW ROLE */
CREATE ROLE db_logger

/* GRANT SELECT, INSERT TO THE ROLE */
GRANT SELECT, INSERT ON [Logging].[Logs] TO db_logger --Allows SeriLog to insert

奇怪的是,“ WriteTo”需要SELECT权限,而“ AuditTo”则不需要。这两种方法都需要INSERT权限。