简体   繁体   English

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

[英]Serilog MSSQL Sink doesn't write logs to database

I have created a .Net class library (4.6.2) and created serilog implementation which is called by other interfaces such as console app.我创建了一个 .Net 类库 (4.6.2) 并创建了由其他接口(如控制台应用程序)调用的 serilog 实现。 Now when I use File sink type, the logs are getting written to the files but with MSSQL sink, its not doing so.现在,当我使用文件接收器类型时,日志被写入文件,但使用 MSSQL 接收器,它没有这样做。 The log tables are getting created with column options as provided with autoCreateTable options使用 autoCreateTable 选项提供的列选项创建日志表

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

I have else enabled selflogging of serilog but no exceptions are displayed.我还启用了 serilog 的自我记录,但没有显示任何异常。 Not found any helpful solution for the same.没有找到任何有用的解决方案。

The log table is however getting generated.然而,日志表正在生成。 I have checked the permissions for the user and that is also having the correct permissions.我已经检查了用户的权限,并且也有正确的权限。

Below is the snap shot of the code.下面是代码的快照。

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

}

Below are some ideas that could help you troubleshoot:以下是一些可以帮助您进行故障排除的想法:


Are you testing with Verbose or Debug events only?您是否仅使用VerboseDebug事件进行测试? That could be the reason.这可能是原因。 You didn't specify a global minimum level for Serilog (you only specified for the minimum level for the sink, which acts as a filter), and the default minimum is Information , which means Verbose and Debug are being ignored... Specify the global MinimumLevel for Serilog:您没有为 Serilog 指定全局最低级别(您只为接收器指定了最低级别,它充当过滤器),并且默认最小值是Information ,这意味着VerboseDebug将被忽略...指定MinimumLevel的全局MinimumLevel级别:

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

Are you disposing your logger?你在处理你的记录器吗? Serilog.Sinks.MSSqlServer is a "periodic batching sink", so you'll need to make sure you dispose the logger at the end to force it to flush the logs to the database. Serilog.Sinks.MSSqlServer是一个“定期批处理接收器”,因此您需要确保在最后处理记录器以强制它将日志刷新到数据库。 See Lifecycle of Loggers .请参阅记录器的生命周期

((IDisposable) logger).Dispose();

Even though you're using 1 for batchPostingLimit , it waits 5 seconds by default before sending the logs to the database .即使您将1用于batchPostingLimit默认情况下它batchPostingLimit 等待5秒,然后才会将日志发送到数据库 If your app closes before that period and you didn't dispose the logger, the messages are lost.如果您的应用程序在该时间段之前关闭并且您没有处理记录器,则消息将丢失。


For the sake of troubleshooting, use AuditTo instead of WriteTo (and remove the batchPostingLimit which is not applicable for auditing).为了排除故障,请使用AuditTo而不是WriteTo (并删除不适用于审计的batchPostingLimit )。 WriteTo is safe and will eat any exceptions, whilst AuditTo will let exceptions bubble up. WriteTo是安全的并且会吃掉任何异常,而AuditTo会让异常冒泡。

ILogger logger = new LoggerConfiguration()
    .AuditTo.MSSqlServer(
        connectionString,
        tableName,
        restrictedToMinimumLevel: LogEventLevel.Verbose,
        autoCreateSqlTable: true)
    .CreateLogger();

Of course, once you figure out what's wrong, go back to WriteTo .当然,一旦你弄清楚出了什么问题,就回到WriteTo


In my case it was because my database user didn't have the necessary permissions to log to the database schema.table.就我而言,这是因为我的数据库用户没有登录数据库 schema.table 的必要权限。

I ended up doing something like the following:我最终做了如下事情:

/* 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

Curiously "WriteTo" needs the SELECT permissions but "AuditTo" does not.奇怪的是,“WriteTo”需要 SELECT 权限,但“AuditTo”不需要。 Both methods need the INSERT permission.这两种方法都需要 INSERT 权限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM