首页 > 解决方案 > 写入 Serilog 日志文件时如何触发事件?

问题描述

我正在尝试在我的 UWP 应用程序中显示 Serilog“logs.txt”文件的内容。我已成功显示它,但现在我希望它在创建新日志事件时自动刷新。

到目前为止,我尝试制作一个 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() 函数来更新绑定到我的 UI 的变量。

谢谢你的帮助!

标签: c#xamluwpserilog

解决方案


我认为最好的方法是为 Serilog 创建自己的自定义接收器。它将捕获任何生成的日志,然后您可以在任何您想要的地方过滤和输出这些日志。就我而言,我将它们输出到我的 UI。

创建一个接收器类:

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

如果您有任何问题,请告诉我!


推荐阅读