【问题标题】:Can I get the NLogViewer to display entire log file?我可以让 NLogViewer 显示整个日志文件吗?
【发布时间】:2017-10-28 18:17:00
【问题描述】:

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

应用程序运行几个小时后,我注意到我只能查看日志的一部分——从当前条目回到一个小时左右之前。滚动条让我向下滚动到最新条目,但在第一个条目之前停止。目前,没有太多的日志记录,即没有调试或跟踪,只有 Info、Warnings 和 Errors,所以我认为日志的大小不会有影响。

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

谢谢!

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

【问题讨论】:

    标签: wpf nlog


    【解决方案1】:

    我制作了NLogViewer 的新版本。没有任何限制。如果您愿意,也可以更改样式

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

    https://github.com/dojo90/NLogViewer

    【讨论】:

      【解决方案2】:

      我昨天花了很多时间来解决这个问题,试图用新的行为或属性来扩展现有的类。最大的问题是我无法访问或覆盖的受保护方法中的硬编码 50 个条目。而且由于 NLogViewer 控件是使用 XAML 定义的,因此我无法轻松地将其子类化为“非 XAML”类(编译错误)。最后,似乎只使用原始源代码并制作一些mod以获得所需的结果似乎更简单。

      我做了以下更改:

      • 我在 NLogViewer“视图”中添加了 2 个属性:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-30
        • 2011-09-18
        • 2018-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-05
        相关资源
        最近更新 更多