【问题标题】:How to Trigger Event When Serilog Logs File is Written to?写入 Serilog 日志文件时如何触发事件?
【发布时间】:2019-07-24 23:52:11
【问题描述】:

我正在尝试在我的 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 的变量。

感谢您的帮助!

【问题讨论】:

  • 根据我的测试,ContentsChanged 事件确实对我有用。当我在本地文件夹中创建“.txt”文件时,将触发此事件。如果我在这个 txt 文件中写一些东西,这个事件也会被触发。您是否检查过此日志文件中是否添加了新的日志事件?
  • 您是否使用我的代码进行了测试,还是我的代码有问题?我试图在事件上设置一个断点并查看它何时触发,并且它似乎与我的日志写入文件的时间不一致。但是,日志事件正在传递到文件中。也许我会进一步调查。
  • @XavierXie-MSFT 刚刚再次测试了我的,它在程序启动时触发了几次,但在发生日志事件后不会触发。
  • 请尝试在本地文件夹中手动创建一个txt文件并在其中写入一些内容以查看是否会触发此事件。
  • @XavierXie-MSFT 好的,它会在我创建它以及编辑和保存内容时触发。我不确定为什么当日志向文件中添加内容时它不会触发。

标签: c# xaml uwp serilog


【解决方案1】:

我认为最好的方法是为 Serilog 创建自己的自定义 Sink。它会捕获任何生成的日志,然后您可以在任何您想要的地方过滤和输出这些日志。就我而言,我将它们输出到我的 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();

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

【讨论】:

  • BWhelan,请教一个问题,您可能知道,在 Emit 中,我可以访问文件 pat 和日志名称吗?如何在任何情况下登录多个文件?
猜你喜欢
  • 2020-02-27
  • 2018-02-03
  • 2014-12-21
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多