我可以让 NLogViewer 显示整个日志文件吗?

Can I get the NLogViewer to display entire log file?

我有一个 "long-running" WPF 桌面应用程序,它使用 NLog 和 NLogViewer 来显示运行时状态。它用于监视数据库,提取处理请求,然后记录结果。 (是的 - 应该是一项服务,但我们想首先以这种方式开始 - 婴儿步骤。)结果记录到文本日志文件中,NLogViewer 实时显示日志中的当前项目。

应用 运行 几个小时后,我发现我只能查看日志的一部分——从当前条目回溯到一个小时左右。滚动条让我向下滚动到最新的条目,但在第一个条目之前停止。此时,没有进行大量日志记录,即没有调试或跟踪,只有信息、警告和错误,所以我认为日志的大小不会产生影响。

有没有办法让 NLogViewer 让我查看整个日志文件,或者它只会向我显示有限的 window 日志?是否有替代的 NLog 查看器 WPF 控件?我现在并不是真的在看独立的 NLog 查看器。如果您需要更多信息,请告诉我。

谢谢!

编辑:我花了一些时间重新审视这个问题,并从 GitHub 获得了 NLogViewer 源代码。在视图的代码隐藏中,ListView 的项目源中保存的条目数有一个硬编码值 50。对于超过 50 的每个项目,都会从日志的开头删除一个项目。当然,我可以下载源代码并根据自己的喜好进行修改,这可能是最终的解决方案,因为该项目已经 3 年没有更新了。但是,我可能会尝试看看我是否可以围绕原始控件创建一个包装器并允许一些基本扩展,例如要显示的可配置日志条目数,并始终显示最后添加的条目。如果我有任何成功,我会 post 我所做的。

我昨天花了很多时间研究这个,试图用新的行为或属性来扩展现有的 class。最大的问题是我无法访问或覆盖的受保护方法中的硬编码 50 个条目。由于 NLogViewer 控件是用 XAML 定义的,我不能轻易地用 "non-XAML" class 子 class 它(编译错误)。最后,似乎更简单的方法是使用原始源代码并进行一些修改以获得所需的结果。

我做了以下修改:

  • 我向 NLogViewer 添加了 2 个属性 "view":

    [Description("Automatically scroll last entry into view?"), Category("Data")]
    public bool ScrollIntoView { get; set; } = true;
    
    [Description("How many log entries should be kept in memory."), Category("Data")]
    public int VisibleEntryCount { get; set; } = 50;  // Original code default
    

    这些将控制最后一个日志条目是否滚动到视图中以及有多少日志条目可供显示。

  • 我修改了现有的 LogReceived 处理程序以使用 VisibleEntryCount 属性。

    protected void LogReceived(NLog.Common.AsyncLogEventInfo log)
    {
        LogEventViewModel vm = new LogEventViewModel(log.LogEvent);
    
        if (this.VisibleEntryCount == 0)
        {
            this.VisibleEntryCount = 50;  // Original code default.
        }
    
        this.Dispatcher.BeginInvoke(new Action(() =>
        {
            if (this.LogEntries.Count >= this.VisibleEntryCount)
            {
                // We've reached our limit.
                this.LogEntries.RemoveAt(0);
            }
    
            this.LogEntries.Add(vm);
        }));
    }
    
  • 并且我为每当添加新日志条目时添加了一个新的事件处理程序。这将让我确保最后一个条目始终可见(如果用户指定)。

    private void LogEntries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (this.ScrollIntoView)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                if (this.logView != null)
                {
                    int count = this.LogEntries.Count;
                    object selectedItem = (count > 0) ? this.LogEntries[count - 1] : null;
                    if (selectedItem != null)
                    {
                        this.logView.Dispatcher.BeginInvoke((Action)(() =>
                        {
                            this.logView.UpdateLayout();
                            this.logView.ScrollIntoView(selectedItem);
                        }));
                    }
                }
            }
        }
    }
    

它似乎工作正常。一如既往,我愿意接受其他解决方案或建议。谢谢!

我做了一个新版本的NLogViewer。没有任何限制。如果需要,您也可以更改样式

https://www.nuget.org/packages/Sentinel.NLogViewer

https://github.com/dojo90/NLogViewer