日志向导 - 查看 Windows 事件日志也可以很有趣!






4.64/5 (5投票s)
您可以对 Windows 事件日志进行高级搜索。甚至支持正则表达式搜索和过滤。无需专业技能。
目录
- 引言
- 入门:简明版
- 入门:详细版
- 随心所欲地调整
- 在 Windows 事件日志中搜索文本
- 过滤
- 跳转到行/时间
- 实时更新
- 打开日志历史记录
- 调试器视图
- 您想要什么?
- 高级:为什么事件到达需要这么长时间?
- 历史
Log Wizard 系列的其他文章
引言
查看 Windows 事件日志可能相当痛苦。至少可以说,默认的事件查看器界面很奇怪(比如,它浪费了很多空间)。对于现有的替代方案,我在这里要添加一个新的——Log Wizard。
我创建了Log Wizard,以帮助任何人轻松地过滤日志以识别 bug 和/或问题。它支持几种类型的日志,并且从版本1.7开始,它还支持 Windows 事件日志。我在github上托管它,计划大约每 3-4 周发布一个新版本。
查看、过滤和/或搜索的过程必须非常简单。如果不是这样,我显然做错了什么——请告诉我!
入门:简明版
一旦启动 Log Wizard,它会等待您打开日志。只需按 Ctrl-O(等同于 Actions >> Open Log)。
选择 Windows Event Log,然后按 OK。事件将开始传入——随着它们的显示,您将在状态栏中看到进度。根据您的事件日志的大小,这可能需要几秒钟,但 UI 始终保持响应。
我将显示来自 Application
和 System
事件日志的事件,并将它们合并在一起。
请注意,最新的事件在前——因此,在等待旧事件的同时,您可以快速查看最近发生的事情。
作为预览,请尝试 Ctrl-F(查找),输入一些内容(甚至是正则表达式),然后享受预览。或者,尝试 Ctrl-G(跳转到行/时间)并输入类似 -10h
(相对于您选定的行,跳转到 10 小时前)或 -2.5d
(跳转到 2.5 天前)的内容。
或者,只需浏览事件,您就会发现我已经尽我所能利用了每一寸空间来显示相关信息。您可以切换信息以显示/隐藏,直到只看到对您来说重要的内容。
入门:详细版
按 Ctrl-O 并选择 Windows Event Log 后,您可以当然也可以根据自己的喜好调整一些设置。
首先需要注意的是,您可以同时查看多个(Windows 事件)日志。它们将按日期/时间排序。您可以打开 Local Logs
(默认)或 Remote Logs
(稍后详述)。
打开本地日志
在 Event Log(s)
文本框中,您可以输入任何 Windows 事件日志的名称——一旦被识别,就会显示绿色的“OK”(每行一个条目)。
或者,您可以选中/取消选中下方列表中的日志(这显然更容易 :))——文本框将更新以反映您的选择。
文本框下方列表的问题是,您不能保证列表是完整的。枚举所有 Windows 事件日志相当麻烦,几乎不可能。在 .NET 中,我们有 EventLog.GetEventLogs(
[remote_machine_name])
,但这只会返回很少的日志名称。或者简单地说,就是常见的日志。它甚至不会显示 System
日志!
为了解决这个问题,我将访问 C:\Windows\System32\winevt\Logs——并显示最近更新的文件。不幸的是,这是一个非常长的列表,而且大多数日志都是空的。
要了解某个日志是否为空,唯一的方法就是打开它并开始读取。当然,这很耗时。您将看到,当涉及到读取 Windows 事件日志时,一切都是耗时的。
为了帮助您判断哪些日志值得关注,我在事件日志下方的文本框旁边提供了一个 Test
按钮。它将打开一个新窗口,显示您选择的哪些日志包含条目——并且还会显示每个日志的条目数(即使对于远程计算机也有效,前提是您已正确设置密码)。
一旦您对选择满意,只需点击底部的 OK,Log Wizard 就会开始收集并显示日志中的信息。
打开远程日志
您也可以连接到远程日志。我已经使其过程尽可能无缝和轻松。要连接到远程计算机,您需要提供计算机名称、域、用户名和密码。
设置好后,您会看到一个 Test
按钮,显示您是否成功连接到远程计算机。连接成功后,(选中的)事件日志列表会更新。
您可以从列表中选中/取消选中日志,或手动输入远程计算机上 Windows 事件日志的名称。一旦名称正确,您就会看到绿色的“OK”。
选择完要查看的日志后,点击底部的 OK。Log Wizard 现在将收集并显示日志中的信息。
需要注意的是,Log Wizard 会记住您的选择,因此下次打开 Log Wizard 时,它会重新打开您上次选择的内容。如果您连接到远程计算机,它不会在本地存储密码——它会强制您重新输入。一旦密码正确,它将重新读取日志并显示给您。
随心所欲地调整
正如我已经说过的,我不喜欢浪费(UI)空间。任何您不喜欢的东西,都可以将其关闭。我的意思是:
视图窗格
根据您的日志类型,它可能包含很多列。在 View Pane
中,您希望在“摘要/详细信息”之间取得最佳平衡,这样就不会有太多列,但也不会太少。对于 Windows 事件日志,默认情况下,我显示消息、行号、日期、时间、级别(其余部分显示在详细信息窗格中)。
您决定什么对您很重要:首先,您可以调整列的宽度和/或移动它们。要移动列,请右键单击其标题。将出现一个菜单,您可以将该列移到其左侧或右侧(参见底部的操作)。
您还可以显示/隐藏任何列——只需右键单击任何列标题。这里,我只是显示了日志和类别
详细信息窗格
默认情况下,Details Pane
显示除行号、日期、时间、级别列之外的所有内容。它们显示在第一行(固定行),第二行是可移动的,其中显示完整的消息。您当然也可以调整详细信息窗格的大小和/或自定义它。
自定义详细信息窗格时,您可以显示/隐藏列,并指定它们显示在哪里(在哪个行)。右键单击它,然后选择“Edit Description Layout”。
您应该能够轻松地修改它以满足您的需求。例如:
随心所欲地切换!
任何您不想要的内容都可以切换掉。甚至 Details Pane
!只需按 Alt-D 关闭,然后按 Alt-D 重新打开。或者状态栏 - Alt-S 打开/关闭。
您甚至可以切换标题栏(Alt-T)
要查看可以打开/关闭的内容(并立即看到它的含义),您可以按 Actions >> Show/Hide Information(您需要显示状态栏才能使“Actions”按钮可见)。
在 Windows 事件日志中搜索文本
这是 Log Wizard 真正出色的地方之一。无论您在日志的哪个位置,只需键入 Ctrl-F(查找)。
您可以搜索任何内容,并获得即时预览(周围 1000 行)
如您所见,搜索正则表达式非常方便。有几点需要注意:
- 默认情况下,Log Wizard 会搜索所有列。您可以关闭它,在这种情况下,它只会搜索 Message 列。
- Log Wizard 会尝试猜测您的文本是否为正则表达式。您可以覆盖它。
- 您的搜索将被保存,以便下次执行 Ctrl-F 时可以重新选择它。
按下 OK 后,它将带您到第一个结果。
您会发现找到的文本会以粗体和不同的背景显示,以便您可以轻松地在视觉上看到结果。
如果您的搜索将您带到视图中不可见(仅在详细信息窗格中可见)的结果,Log Wizard 将在不同的背景中显示整行(这里,搜索 .net runtime
)。
在上例中,第 55534 行在 Source
列中包含 .net runtime
文本。
您可以轻松地在结果之间导航——只需按 F3(查找下一个)或 Shift-F3(查找上一个)。
F3 / Shift-F3 相对于您当前选定的行。您可以转到任何行,然后按 F3 或 Shift-F3——搜索将从那里继续。或者……
您可以轻松地切换仅查看搜索结果。只需按 Ctrl-Alt-F,您就会看到如下内容:
再次按下它,您将返回查看完整的日志。
要停止搜索(并停止对找到的单词进行着色),只需按 ESCAPE 键。
过滤
在检查 Windows 事件日志时,与任何日志一样,会有很多您不关心的信息。因此,您可以简单地将其过滤掉。Log Wizard 提供 3 种类型的过滤器:
- 排除过滤器(您将从视图中排除行)
- 包含过滤器(您将从视图中包含行——所有
Include
过滤器都将进行OR
操作) - 颜色过滤器(您可以为特定行应用漂亮的颜色)
需要注意的是,您的查找(Ctrl-F)将在您现有的视图上工作。也就是说,Find 命令将忽略您通过过滤排除的每一行。
我在这里深入解释了过滤器。要轻松地为某些单词着色,只需选择它们,右键单击,选择 Set Color of Lines >> Match Color,选择颜色,然后就完成了。在这种情况下,resolution
显示为蓝色,ping
显示为红色。
当您过滤掉一些内容后,如果您想快速将其恢复,只需切换它——Ctrl-Alt-L——这将显示日志中的所有行,而那些被排除的行将显示为灰色。
在上例中,我排除了所有以 Installation Failure
开头的行。
跳转到行/时间
另一种导航日志的方式是跳转到特定行或日期/时间。只需按 Ctrl-G(跳转到)。
Go to
功能有两种方式:
- 跳转到精确的行或日期/时间,或者
- 跳转到偏移的行或日期/时间——只需加上 + 或 - 前缀,这就是一个偏移量。
对话框非常直观,并且可以处理大量的日期/时间格式。它还会实时显示将要跳转到的位置。例如:
-2.5d
将显示一个提示,如“Before 216000 secs”(2.5 天前),11/20
将显示“To Date 2016/11/20 00:00:00.000”11/19 2:4
将显示“To Date 2016/11/19 02:04:00.000”+10h
将显示“After 36000 secs”(10 小时后)
实时更新
您已选择要打开的 Windows 事件日志,并且现在正在愉快地查看它们。
当新事件被记录到您打开的任何日志中时,您将实时看到它们。它会自动刷新。
如果您碰巧在第一行(因为对于 Windows 事件日志,默认显示最新条目),您将自动滚动到新条目。
打开日志历史记录
Log Wizard 很智能,并且会记住一切。您的切换设置、窗口位置、过滤器等。它记住的事情中还包括:上次打开的日志历史记录。
默认情况下,当您启动 Log Wizard 时,它会自动重新打开您上次打开的日志。您可以在 Preferences (Ctrl-P) 中关闭此功能——Automatically Open Last Log On Restart
。
假设您关闭了 Automatically Open Last Log On
,那么每次都不需要调用 Actions >> Open Log 来重新打开上次打开的 Windows 事件日志。只需转到 Actions >> Show History,或按 Ctrl-H,然后选择上次的日志。
默认情况下,Last Log 实际上是已选中的,因此为了更快地操作,您可以将 Ctrl-H, Enter 视为重新打开上次日志的快捷方式。
调试器视图
顺便说一句,Log Wizard 除了 Windows 事件日志和文件之外,还可以监视调试器视图条目——这只是应用程序使用 OutputDebugString 写入的任何内容。或者,对于 C# 用户来说,任何使用 Debug.Write[Line]
或 Trace.Write[Line]
编写的内容。所以,例如,它可以捕获这个:
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Debug.WriteLine("debug - this is the beginning");
Trace.WriteLine("trace - this is the beginning");
Application.Run(new Form1());
Trace.WriteLine("this is the end");
}
打开新日志时——Ctrl-O 或 Actions >> Open Log,选择 Debug Viewer
。您会看到这个:
您可以按应用程序名称过滤事件,或显示所有事件(取决于您运行的应用程序,这可能会变得相当拥挤)。假设您的应用程序名为 Windowsformsapplication1
,只需在此处输入(不区分大小写),然后按 OK。运行您的应用程序。您将看到类似以下内容:
非常酷。 ;)
您想要什么?
创建(并优化)一个 Windows 事件日志查看器,我必须承认,比我最初预期的要困难得多。不过,这还是很有趣的。
您希望从这样的日志查看器中获得什么?您最喜欢的功能是什么?
如果它还没有在这里,我会尽力实现它。
高级:为什么事件到达需要这么长时间?
当您打开事件查看器并打开事件日志时,它很快。但当您从外部应用程序查看同一个日志时,事情就慢多了。为什么呢?
如果您在 Google 上搜索 .NET 中读取事件日志,您会发现人们对此抱怨很多。微软似乎并不在意。所以您实际上只有两个选择:
- 结果快速,但 UI 非常糟糕(事件查看器)
- 结果较慢,但您可以选择如何显示它们,从而拥有一个更好的 UI。
如果您想在事件查看器之外查询 Windows 事件日志,您有两个选择:
- 使用非常底层的 API(Win32 API - Event Log Reference 和 Example)。如果您查看示例,您就会明白我为什么避免它。
- 使用高级且易于使用的 .NET API。它的速度慢了几倍。
所以我选择了后者。为什么它这么慢?我不知道——我可以告诉您瓶颈在哪里,其余的只是我的猜测。
使用 .NET API 之一,您可以查询 Windows 事件日志(使用 XPATH 查询),然后处理每个记录。
遍历查询速度很快。枚举其一些重要属性是瓶颈:
- 获取事件的
Category
(EventRecord.TaskDisplayName
) - 获取
Message
本身(EventRecord.FormatDescription()
)
FormatDescription()
非常慢——在我(非常快的)机器上——每次大约需要 2-3 毫秒。
您应该知道,许多 EventRecord
属性/方法会引发大量异常。我猜测是因为底层代码会检查用户凭据(用户是否允许实际查看事件?)。
例如,如果您的 Windows 帐户不属于“Event Log Readers”用户组,读取日志的速度会**慢得多**。
引发异常的成本非常高——有时是2000 倍甚至更高(参见这里和这里)——并且在读取事件详细信息时,您可能会遇到不止一个异常。
我的个人看法是,EventRecord
类实现得非常糟糕——首先,应该有一种方法可以在不引发任何异常的情况下调用其方法/属性。
但更糟糕的是,在 FormatDescription()
中,似乎有一个全局(互斥锁)——这样就没有两个线程可以访问两个不同 EventRecord
的描述。我尝试使用 Parallel.For
来读取 5000 个事件的详细信息。令我惊讶的是,代码执行的时间与使用单线程读取这些事件的时间相同,唯一的区别是使用 Parallel.For
实际上使用了接近 100% 的 CPU(我的 8 个逻辑 CPU),而在单线程上运行时,CPU 使用率大约为 6-8%。
避免 FormatDescription()
几乎是不可能的——但如果您知道有什么方法,请告诉我。
历史
- 2016 年 1 月 21 日,初始版本(1.7)