Как вызвать событие, когда записывается файл журнала Serilog? - PullRequest
1 голос
/ 26 июня 2019

Я пытаюсь отобразить содержимое файла Serilog "logs.txt" в моем приложении UWP. У меня он успешно отображается, но теперь я хочу, чтобы он автоматически обновлялся при создании новых событий журнала.

До сих пор я пытался создать прослушиватель событий ContentsChanged, который подписывался на изменения в файлах .txt на локальном файловом диске.

private async void CreateFileUpdater()
{
    List<string> fileTypeFilter = new List<string>();
    fileTypeFilter.Add(".txt");
    var options = new Windows.Storage.Search.QueryOptions(Windows.Storage.Search.CommonFileQuery.OrderByName, fileTypeFilter);
    var query = ApplicationData.Current.LocalFolder.CreateFileQueryWithOptions(options);
            //subscribe on query's ContentsChanged event
    query.ContentsChanged += Query_ContentsChanged;
    var files = await query.GetFilesAsync();
}

private void Query_ContentsChanged(Windows.Storage.Search.IStorageQueryResultBase sender, object args)
{
    ReadFileAsync(); //This updates the bound variable to display in UI
}

Однако, похоже, что он не запускается должным образом при добавлении новых событий журнала в файл журнала. Поэтому мне было интересно, есть ли в самом Serilog событие, которого я просто не вижу в документации, или есть ли лучший способ обнаружить изменения в файлах или когда что-то добавляется в файлы. Я просто хочу, чтобы вызывалось какое-то событие, чтобы я мог вызвать функцию ReadFilesAsync () для обновления переменной, связанной с моим пользовательским интерфейсом.

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 24 июля 2019

Лучший способ сделать это - создать свой собственный Sink для Serilog. Он будет перехватывать любой сгенерированный журнал, а затем вы сможете фильтровать и выводить эти журналы в любое место. В моем случае я вывожу их на свой пользовательский интерфейс.

Создание класса раковин:

    public class LogsSink : ILogEventSink
    {
        /// <summary>
        /// Format of the output log
        /// </summary>
        readonly string Format = "{0} {1} {2}";

        /// <summary>
        /// Emit the provided log event to the sink.
        /// </summary>
        /// <param name="logEvent">The log event to write</param>
        public void Emit(LogEvent logEvent)
        {
            var t = logEvent.Timestamp;
            LogMsg msg = new LogMsg()
            {
                Text = logEvent.RenderMessage(),
                Lvl = LevelToSeverity(logEvent),
                TimeStamp = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff") + " -" + t.Offset.ToString(@"hh\:mm"),
            };
            if (LogsViewModel.logFile != null)
                LogsViewModel.logFile.AllText.Add(string.Format(Format, msg.TimeStamp, msg.Lvl, msg.Text));
            LogsViewModel.logFile.AppendText();
        }

        static string LevelToSeverity(LogEvent logEvent)
        {
            switch (logEvent.Level)
            {
                case LogEventLevel.Debug:
                    return "[DBG]";
                case LogEventLevel.Error:
                    MainPageViewModel.statusBar.AddError();
                    return "[ERR]";
                case LogEventLevel.Fatal:
                    return "[FTL]";
                case LogEventLevel.Verbose:
                    return "VERBOSE";
                case LogEventLevel.Warning:
                    MainPageViewModel.statusBar.AddWarning();
                    return "WARNING";
                default:
                    return "[INF]";
            }
        }
    }

    struct LogMsg
    {
        public string Lvl;
        public string Text;
        public string TimeStamp;
    }

Зарегистрируйте мойку при создании экземпляра логгера

public LogsSink sink;
sink = new LogsSink();
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug()
                .WriteTo.Sink(sink)
                .CreateLogger();

Дайте мне знать, если у вас есть какие-либо вопросы!

...