Serilog MSSQL Sink не записывает журналы в базу данных

Я создал библиотеку классов .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();

Я также включил ведение самоблога серилога, но никаких исключений не отображается. Не нашел никакого полезного решения для того же самого.

Однако создается таблица журнала. Я проверил разрешения для пользователя, и у него также есть правильные разрешения.

Ниже приведен снимок кода.

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

}

person djSmart    schedule 23.10.2018    source источник
comment
batchPostingLimit установлен в 1   -  person djSmart    schedule 23.10.2018
comment
Если бы вы могли опубликовать точные значения каждой из этих переменных (например, connectionString, columnOptions, ...), мы могли бы попытаться воспроизвести поведение ...   -  person C. Augusto Proiete    schedule 24.10.2018


Ответы (2)


Ниже приведены некоторые идеи, которые могут помочь вам в устранении неполадок:


Вы тестируете только Verbose или Debug события? Это могло быть причиной. Вы не указали глобальный минимальный уровень для Serilog (вы указали только минимальный уровень для приемника, который действует как фильтр), а минимум по умолчанию Information, что означает, что Verbose и Debug игнорируются ... Укажите глобальный MinimumLevel для Serilog:

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

Вы утилизируете свой регистратор? Serilog.Sinks.MSSqlServer - это «приемник периодического пакетирования», поэтому вам нужно убедиться, что вы удалили регистратор в конце, чтобы заставить его сбрасывать журналы в базу данных. См. Жизненный цикл регистраторов.

((IDisposable) logger).Dispose();

Даже если вы используете 1 для batchPostingLimit, по умолчанию он ждет 5 секунд перед отправкой журналов в базу данных. Если ваше приложение закрывается до этого периода и вы не утилизировали регистратор, сообщения теряются.


Для устранения неполадок используйте AuditTo вместо WriteTo (и удалите batchPostingLimit, который не применяется для аудита). WriteTo безопасен и поглощает любые исключения, в то время как AuditTo позволяет исключениям всплывать.

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

Конечно, как только вы поймете, что не так, вернитесь к WriteTo.


person C. Augusto Proiete    schedule 24.10.2018
comment
@CaCaio Proiete Большое спасибо за ваш ответ и решение. Dispose выполняет трюк и регистрирует его в базе данных. Я проведу еще несколько тестов и поделюсь кодом для всех, у кого может быть такая же проблема. Спасибо еще раз - person djSmart; 24.10.2018
comment
Единственная проблема заключалась бы в том, чтобы реализовать статический регистратор в этом случае. - person djSmart; 24.10.2018
comment
Если используются методы статического журнала (например, Log.Information()), где / как удалить регистратор? Я думал, что статический Log.Logger настроен в Startup.cs, а затем его можно использовать в любом месте на протяжении жизненного цикла приложения? - person BaltoStar; 06.02.2020
comment
@BaltoStar Это задокументировано в жизненном цикле регистраторов, ссылка на которую есть в моем ответе выше. - person C. Augusto Proiete; 06.02.2020
comment
Да, я прочитал этот документ, но не думаю, что утилизация имеет отношение к статическому регистратору. В Serilog документах описывается простой вызов Log.Information("my log message") из любого места приложения. Нигде в документации не говорится, что необходимо избавиться от статического регистратора для сброса журналов в базу данных. Фактически, это не имело бы никакого смысла, поскольку статический регистратор предназначен для однократной инициализации и последующего использования на протяжении всего жизненного цикла приложения. CloseAndFlush() доступен для завершения работы приложения - но это только для того, чтобы убедиться, что буфер очищен, журналы не остаются болтающимися. - person BaltoStar; 06.02.2020

В моем случае это произошло потому, что у моего пользователя базы данных не было необходимых разрешений для входа в таблицу 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.

person Mikhael Loo    schedule 07.02.2020