项目地址:ghostgorge/LogMedic: LogMedic
一个用 Python 写的 Windows 日志分析与系统运维工具。零第三方依赖,单文件 exe,内置 100 条事件 ID 知识库、45 个蓝屏停止码和 23 套处置方案。
一、起因:打开事件查看器,然后呢?
电脑动不动重启、开机越来越慢、某个软件老是崩。老手会说:去看事件查看器。
于是你打开了 eventvwr.msc,展开”Windows 日志 → 系统”,看到密密麻麻一屏红叉。然后呢?
我在一台正常办公用的 Dell OptiPlex 上做了个统计。最近 30 天,”系统”和”应用程序”两个日志里,错误和警告一共 3900 条。按出现次数排序,前五名是这样的:
| 排名 | 事件来源 / ID | 30 天次数 | 实际影响 |
|---|---|---|---|
| 1 | Security-SPP / 8229 | 274 | 无 |
| 2 | FilterManager / 11 | 273 | 无 |
| 3 | DistributedCOM / 10016 | 157 | 无 |
| 4 | DistributedCOM / 10010 | 155 | 无 |
| 5 | Kernel-PnP / 219 | 104 | 无 |
前五名加起来 963 条,全是噪声。
- Security-SPP 8229:”规则引擎未能执行一项或多项计划的操作,错误代码 0x80080005″。只要
slmgr /xpr显示系统已激活,这条就没有任何实际影响。 - DCOM 10016:微软官方文档白纸黑字写着,这类事件在多数情况下可以安全忽略 —— 系统内置组件的默认 DCOM 权限本来就是不完整的。
- Kernel-PnP 219 + WUDFRd + 0xC0000365:蓝牙/传感器类设备的用户模式驱动框架提示,设备都正常就不用管。
而同一份日志里,真正要命的东西是这几条:
| 事件 | 30 天次数 | 说明 |
|---|---|---|
| Kernel-Power 41 | 4 | 系统 4 次没正常关机就重启了 |
| EventLog 6008 | 2 | 上次关机是意外的 |
| volmgr 161 | 4 | 蓝屏转储文件创建失败 |
噪声占了 96%,真问题只有 4%,而且排在列表最底下。
这就是事件查看器最大的问题:它不是看不到数据,是数据太多。一个普通用户按”错误数量”排序去排查,会花一整天折腾 DCOM 权限(改注册表所有者、进组件服务配权限),然后什么也没解决——因为他压根没注意到那 4 次异常重启。
志诊 LogMedic 就是为了解决这一件事:替你做判断,而不是替你翻日志。
二、它是怎么判断的
2.1 按知识库定级,不按日志级别
这是整个工具的地基。举三个例子:
| 事件 | 事件查看器里的级别 | 实际含义 | 工具的定级 |
|---|---|---|---|
Ntfs / 98 | 信息 | “卷运行状况良好,无需执行任何操作” | 忽略(这是好消息) |
DistributedCOM / 10016 | 警告 | 微软说可忽略 | 噪声,不扣分 |
disk / 7 | 错误 | 磁盘有坏块 | 严重,最高优先级 |
这三条在事件查看器里长得差不多,但严重程度天差地别。工具内部给每条知识库条目打了 ig(可忽略)标记——被标记为可忽略的事件,无论刷出多少条都不会升级、不会扣健康分,只在报告末尾单独列一个”可忽略的日志噪声”分区。
这条设计有个很实际的理由:为了消灭日志里的红叉去改系统设置,是运维里最常见的无用功,工具不该带着用户往坑里走。
2.2 必须按”来源 + 事件 ID”两个字段一起匹配
这是开发中最早撞到的坑。同一台机器上:
Hyper-V-Hypervisor / 129 → "虚拟机监控程序已初始化 I/O 重新映射"(信息级,完全正常)
storahci / 129 → "将设备复位"(硬盘即将出问题的强信号)
只按事件 ID 认,会把好事报成故障。 网上很多”事件 ID 大全”就是这么错的。所以知识库的主键是 (来源, 事件ID),来源匹配做了一档放宽(Microsoft-Windows-Ntfs 能匹配 Ntfs),但绝不跨 ID 猜。
2.3 聚合与关联
50 条 7031 不是 50 个问题,是 1 个问题。工具会:
- 把
Service Control Manager 7031/7034按服务名归类,告诉你”哪 3 个服务崩了,各崩了几次” - 把
Application Error 1000按出错模块归类——这才是定位应用崩溃的关键字段 - 把
Kernel-Power 41+BugCheck 1001+EventLog 6008+volmgr 161识别成同一次蓝屏的四个侧面,合并成一条结论
还有一条容易被忽略的细节:7023 事件如果错误文本是”系统正在关机”,那是关机时的正常收尾,工具会直接跳过它,不计入服务异常。
2.4 健康分
100 分制,按严重度扣分,每档有封顶(避免一类问题把分数扣穿)。出现次数少于 5 次的问题按半价扣——否则”一次 SxS 报错”和”两周内 166 次服务启动失败”扣一样的分,分数就失去意义了。但严重级别不打折:一次蓝屏就是一次蓝屏。
那台样本机器最终得分 43 分(问题较多),扣分明细:
-18 检测到 4 次异常重启(无蓝屏转储)
-8 有 7 个服务启动失败或超时(共 166 次)
-8 应用程序崩溃 44 次
-8 有 1 个服务意外终止(共 32 次)
-4 蓝屏转储文件写入失败
...
三、一个真实案例:查出了因果链
样本机器上有 4 条 volmgr 161「转储文件创建失败」。工具去读了转储配置,发现:
转储类型 : 内核内存转储
小转储目录 : D:\Minidump
页面文件 : D:\pagefile.sys 16384MB
系统盘 C: : 没有页面文件
于是给出了这条结论:
页面文件不在系统盘 C: 上。 内核转储必须先写入系统盘的页面文件(崩溃时写进去,重启后再搬成 MEMORY.DMP),否则每次蓝屏都会写失败——对应 System 日志里的 volmgr 161。
因果链完整闭合了:有人把页面文件整个挪到了 D 盘 → 系统盘上一个都不留 → 内核转储物理上无法写出 → 4 次异常重启一份证据都没留下 → 蓝屏原因永远查不出来。
而 Windows 对此没有任何提示。你只会在日志深处看到一条”转储文件创建失败”,如果不知道这个机制,根本联想不到是页面文件位置的问题。
这就是我想做这个工具的原因:这类知识不难,但分散在几十篇英文文档和论坛帖子里,普通人凑不齐。
四、功能
工具有六个页面。
一键体检
点一下,30~40 秒出结果:半环表盘显示健康分,下面按严重度列出所有结论,每条都能展开看”现象 / 可能原因 / 影响 / 建议处置”。
采集范围是 Windows 四大日志 + 26 个精选的”应用程序和服务日志”通道(任务计划、启动性能、NTFS、存储、更新、组策略、无线、打印、远程桌面等)。不是全量扫 1000 多个通道——那样既慢又全是噪声。
另外单独捞一遍”级别不是错误、但对定位问题极其关键”的事件,比如 Kernel-Power 41、User32 1074(谁发起的关机)、EventLog 6005/6006(开关机标记)。这些在按级别筛选时全部会被漏掉。
事件浏览
按事件查看器的习惯做的两级通道树(Windows 日志 / 应用程序和服务日志)。可以按级别、时间范围、关键词筛选,双击看完整描述和原始 XML。
每条事件下面直接挂知识库解读——选中一条 7009,右侧就告诉你这是”等待服务连接超时(30000 毫秒)”,常见原因是什么,要不要管。
支持导入 .evtx 文件离线分析(同事发来的日志、从故障机导出的日志都能直接看),也支持把任意通道导出成 .evtx 归档。
诊断与修复
结论 + 处置方案。每条结论关联对应的一键方案,也可以只看手动步骤自己动手。
蓝屏分析
- 检查并一键修复转储配置
- 不装 WinDbg 直接解析 minidump:Windows 内核转储文件开头是
DUMP_HEADER64结构,固定偏移上就放着停止码和四个参数
0x00 签名 'PAGE'
0x04 'DU64'(64 位)
0x38 BugCheckCode ← 停止码在这
0x40/0x48/0x50/0x58 ← 四个参数
0xF98 DumpType
- 扫描转储体里的
.sys文件名,用一份微软自带驱动白名单过滤,把第三方驱动挑出来并标注归属(klif.sys→ 卡巴斯基,nvlddmkm.sys→ NVIDIA 显卡驱动,vboxdrv.sys→ VirtualBox) - 崩溃时间线:列出每次崩溃前 10 分钟内的所有事件——崩溃前最后写日志的组件,往往就是元凶
这不能替代 WinDbg 的栈回溯,但足够回答用户最关心的两个问题:什么码、哪些第三方驱动在场。
服务与计划任务
服务列表带”可执行文件是否还存在”判断,能一眼找出软件卸载后残留的幽灵服务——那是 7000/7009 报错最常见的来源。可以直接改启动类型、启停服务。
计划任务列表把上次运行结果翻译成中文:
0x80070569 → 登录失败:用户未被授予请求的登录类型
0x8007010B → 目录名称无效(「起始于」没填)
0x80040154 → 类未注册(COM 组件缺失或未注册)
0x41303 → 任务尚未运行过(这是正常状态,不是失败)
还有开机耗时趋势。这里有个坑:官方的 Diagnostics-Performance/Operational 通道在较新的 Windows 11 上已经不存在了(样本机 26220 版本上查不到),所以做了退路——用 Kernel-General 12(系统启动)到该次启动后第一条 Winlogon 通知的时间差做估算,并明确标注”估算”,不冒充精确值。
知识库
可全文搜索。输入 7009 直接跳到对应事件,输入 0x7E 跳到蓝屏停止码,输入”计划任务”列出所有相关条目。
| 内容 | 数量 |
|---|---|
| 事件 ID 条目 | 100 |
| 蓝屏停止码 | 45 |
| 处置方案 | 23 |
| 专题文章 | 10 |
专题包括:看懂 Windows 事件日志(必读基础)、蓝屏完整排查流程、开机慢/关机慢、系统卡顿、服务问题速查、计划任务失败速查、可以放心忽略的日志噪声清单、常见错误码速查、机器可能被入侵的迹象、月度巡检清单。
每个蓝屏停止码给四样东西:这码在说什么、最可能的原因(按实际遇到的概率排序,不按微软文档的顺序)、四个参数怎么读、一步步怎么办。
五、”一键修复”的安全边界
这是我在这个项目上花心思最多的地方。一个能改系统的工具,最怕的不是功能少,是乱动手。
规则是死的:
1. 三级风险,高风险的根本不给一键按钮。
23 套方案里,12 套 safe(只读诊断)、10 套 caution(会改系统状态)、1 套 danger。danger 那套是 DCOM 10016 权限修改——涉及改注册表所有者和 COM 权限,工具只显示手动步骤,绝不代劳,而且开头第一句就是”推荐做法是直接忽略它”。
2. 默认预演。
勾着”预演”时只打印将要执行的完整命令行,不做任何实际改动。用户看明白了再取消勾选执行。
3. 执行前摊开命令。
不存在”点一下,然后不知道它干了什么”。每一步执行前,完整命令行都打在输出区里。
4. 谨慎级建议先建系统还原点。
界面上有勾选框,工具会调 Checkpoint-Computer。建不成(系统保护没开、24 小时内已建过)会如实告诉你,不假装成功。
5. 全程留痕。
所有实际执行过的命令写进 %APPDATA%\LogMedic\actions.log。出了问题能回溯”工具到底动了什么”。
还有一条判断上的克制:工具不会因为”自动启动的服务没在运行”就建议你禁用它——除非它的可执行文件确实已经不存在了。因为触发启动型服务停着是完全正常的。
六、技术实现
6.1 技术栈
| 项 | 选择 |
|---|---|
| 语言 | Python 3.8+ |
| 界面 | tkinter / ttk(标准库) |
| 日志采集 | PowerShell Get-WinEvent |
| 打包 | PyInstaller,单文件 exe |
| 第三方依赖 | 零 |
代码约 10000 行,打包后 exe 约 9.5 MB。
日志采集走 PowerShell 而不是直接调 Windows API,是因为只有 Get-WinEvent 能把事件渲染成本地语言的可读描述。wevtutil 导出的 XML 里只有参数,没有渲染后的文本——而描述文本恰恰是最有价值的部分(错误码、文件名、模块名、服务名都在里面)。
知识库全部是 .py 模块,不是 JSON 数据文件。因为单文件 exe 里读数据文件要走 _MEIPASS 取路径,是打包翻车的经典来源。写成模块,import 就完事了。
6.2 开发中撞出来的三个坑
这三个都是在真机上跑出来才发现的,写在这里给同类项目省点时间。
坑一:Windows 事件日志的 XPath 查询最多只允许 23 个表达式。
# System 通道要查 27 个事件 ID,一次查下去 —— 返回 0 条
# 加了 -ErrorAction SilentlyContinue 之后连报错都看不到,纯静默失败
超限后整条查询作废,而 -ErrorAction SilentlyContinue(为了容忍”没找到事件”这种正常情况,必须加)会把错误吞掉,表现为静默返回 0 条,极难排查。解决办法是主动分块,一块最多 16 项(给 LogName、时间范围留余量),再合并去重。
坑二:PowerShell 里 try/catch 是语句不是表达式。
# 这样写会直接抛「哈希文本不完整」的解析错误,整段脚本作废
[pscustomobject]@{
install = try { $os.InstallDate.ToString('yyyy-MM-dd') } catch { '' }
}
必须先算成变量再引用。这个错误的杀伤力在于它是解析期错误——不是那一个字段取不到值,是整个脚本一行都不执行。
坑三:服务的 PathName 不能按空格切。
"C:\Program Files\App\svc.exe" -k netsvcs ← 带引号
C:\Program Files\App\svc.exe -k netsvcs ← 不带引号但含空格
\SystemRoot\System32\drivers\x.sys ← 驱动
按空格切第二种会得到 C:\Program,于是所有装在 Program Files 下的服务都会被判定为”可执行文件不存在”,工具就会建议用户把一大批正常服务禁用掉。这种误判比不检查更糟。修法是优先按引号取,其次按 .exe/.sys/.dll 结尾的正则取。
顺带一提:中文 Windows 的控制台代码页是 GBK,PowerShell 的 stdout 管道按 GBK 编码出来,中文事件描述会直接乱码。所有需要文本结果的地方,都让脚本 Out-File -Encoding utf8 写临时文件,Python 再用 utf-8-sig 读回来。而 .ps1 脚本文件本身如果不带 BOM,PowerShell 5.1 会按 ANSI 解析,脚本里的中文同样会烂掉——写脚本时必须用 utf-8-sig。
6.3 自检
selftest.py 有 16 项无界面自检,打包前后都会跑。其中有一条比较特别:
喂进 80 条纯噪声事件,健康分必须 ≥ 95。
这条守的是工具的判断力底线——防止哪天改坏了规则,让工具开始拿噪声吓唬用户。
七、用法
图形界面
双击 LogMedic.exe。打包时带了 uac_admin,启动会先弹 UAC——建议用管理员身份运行,否则读安全日志、解析 minidump、执行修复都会受限。
非管理员也能用,标题栏会标注”[非管理员 · 部分功能受限]”,只读诊断类的方案照常可以跑。
命令行
logmedic-cli.exe --report # 直接生成 HTML 巡检报告
logmedic-cli.exe --report out.html # 指定输出路径
logmedic-cli.exe --selftest # 跑一遍自检
--report 这个模式适合塞进计划任务里定期跑,报告存档。巡检最值钱的用法是留痕——出问题时你能翻出”上个月还好好的”那个时间点。
报告
HTML 报告是自包含的:样式内联、不引任何外部资源,双击就能看,也能直接发给同事或打印成 PDF。另有纯文本版,方便贴到工单或聊天里。
八、局限
说清楚它不能做什么,比吹它能做什么重要:
- 不能替代 WinDbg。 蓝屏分析只读转储文件头和驱动名单,没有栈回溯。真正复杂的蓝屏还是得上 WinDbg。
- 知识库覆盖不了长尾。 100 条事件 ID 覆盖的是高频问题。第三方软件写的事件(那台样本机上还有 10 类未收录)工具会老实说”未收录”,并建议你拿”来源 + 事件ID”去搜——而不是编一个看起来很像的解释。
- 规则匹配不是推理。 它给的是经验规则的结论,涉及硬件更换、系统重装这类重大决定前,请再做人工确认。
- 只支持 Windows。 依赖
Get-WinEvent,Windows 10 / 11 / Server 2016+ 上验证过。
九、写在最后
做这个工具的过程中,我越来越确信一件事:运维工具的价值不在于能显示多少信息,而在于敢不敢替用户把信息删掉。
事件查看器什么都给你看,所以它什么都没告诉你。志诊 LogMedic 的 3900 条事件里,最后只呈现十几条结论,剩下的要么被合并,要么被明确标注为”可以忽略,别管它”。
判断力就是敢做减法。
志诊 LogMedic v1.0.0 · Python + tkinter · 单文件 exe,无需安装 · 适用于 Windows 10 / 11 / Server 2016+