- Python 100%
| .gitignore | ||
| ESIssueAutoFixer.py | ||
| README.md | ||
| requirements-win7.txt | ||
| ui-example-id-redacted.png | ||
| ui-example-redacted.png | ||
ES Issue Auto Fixer
一个用于自动处理 Elasticsearch 日期字段解析异常的 Windows 桌面工具。
程序通过 SSH 持续监听远程应用日志,识别 IssueNo 日期格式异常,从日志中提取 assetId 和错误日期,修正日期后更新 MongoDB 中对应文档的 attr-IssueNo 字段。无法可靠修正的记录会显示在界面中,供人工处理。
Important
本程序不会直接连接或重启 Elasticsearch。它通过修正 MongoDB 中的源数据,避免异常数据继续触发 Elasticsearch 映射解析错误。启动监控后会直接写入 MongoDB,使用前请先在测试环境验证配置和修复规则。
界面示例
Note
示例截图中的服务器地址已经过不可逆像素化脱敏,仅用于展示程序界面和连接成功状态。
自动修复运行示例
Note
示例截图中节目 ID 的前半段已经过不可逆像素化脱敏,后半段仅用于展示日志识别和日期修复效果。
工作流程
-
使用 SSH 连接应用服务器。
-
执行
tail -f <log_path> | grep --line-buffered fail,持续读取包含小写fail的日志。 -
匹配以下形式的异常,并支持同一行包含多条异常:
00000000000000000000000000000001=MapperParsingException[failed to parse [IssueNo]]; nested: IllegalArgumentException[Invalid format: "2025-5-1" is malformed at "-5-1"] -
提取
assetId(示例中的长数字)和错误日期2025-5-1。 -
将日期修正为
YYYY-MM-DD,例如2025-5-1→2025-05-01。 -
在 MongoDB 中执行等价于下面的更新:
db.<collection>.updateOne( { assetId: "00000000000000000000000000000001" }, { $set: { "attr-IssueNo": "2025-05-01" } } ) -
成功修复的
assetId会加入本次运行的缓存,避免重复更新;无法解析的日期会进入“需手动修复的错误”区域。
日期修复规则
程序采用启发式规则修正日期:
| 输入情况 | 处理方式 |
|---|---|
分隔符为 /、. 或 _ |
统一替换为 - |
存在连续的 - |
合并为一个 - |
年份为 1970~2099 |
保留原年份 |
年份类似 20025 或 200025 |
修正为 2025 |
| 年份超出可识别范围或缺失 | 使用程序所在电脑的当前年份 |
月份不在 1~12 |
使用程序所在电脑的当前月份 |
日期为 0 |
修正为当月 1 日 |
| 日期超过当月最大天数 | 截断为当月最后一天 |
| 格式无法解析 | 不修改数据库,转入人工处理列表 |
修复结果最终会用 datetime.strptime(..., "%Y-%m-%d") 再次校验。由于部分规则会使用当前年月,请务必确认运行程序的电脑时间正确,并评估这些规则是否符合业务语义。
环境要求
- 目标系统:Windows 7 SP1(32 位或 64 位)
- 构建环境:优先使用与目标机同架构的 Windows 7 SP1
- Python 3.8.10;不要使用 Python 3.9 或更高版本
- Microsoft Visual C++ 2019 Redistributable 14.29(与 EXE 架构一致),以及完整的 Windows 7 系统更新
- 可访问应用服务器的 SSH 网络
- SSH 账号具有目标日志文件的读取权限
- 远程服务器提供
tail、grep,且grep支持--line-buffered - 可访问 MongoDB,账号至少具有目标集合的查询和更新权限
Python 官方说明 Windows 7 应使用 Python 3.8;Python 3.8.10 是最后一个提供官方 Windows 安装程序的 3.8 版本。Python 3.8 和 Windows 7 均已停止安全维护,因此此方案只用于满足现有 Windows 7 环境的兼容需求。
项目通过 requirements-win7.txt 固定以下构建依赖:
paramiko==3.4.1pymongo==4.3.3python-dateutil==2.8.2cryptography==38.0.4及其固定的二进制依赖pyinstaller==4.10pyinstaller-hooks-contrib==2022.3及其固定的构建依赖
PyInstaller 本体与它的 hooks 必须同步固定。PyInstaller 官方说明,固定 PyInstaller 版本时也应固定 pyinstaller-hooks-contrib;如果让 pip 安装当前最新版 hooks,PyInstaller 4.10 可能在处理 Cryptography 时直接构建失败。
Warning
不要直接安装这些库的“最新版”。新版 Python、PyInstaller、PyMongo 或 Cryptography 可能已经停止支持 Python 3.8 或 Windows 7,虽然可以成功打包,但生成的 EXE 不一定能在 Windows 7 启动。
使用源码运行
如果只是开发或排查问题,可在安装了 Python 3.8.10 的电脑上使用源码运行。打开项目目录中的命令提示符(cmd.exe),执行:
python --version
python -m venv .venv
.venv\Scripts\activate.bat
python -m pip install pip==23.3.2
python -m pip install -r requirements-win7.txt
python ESIssueAutoFixer.py
第一条命令必须显示 Python 3.8.10。第一次启动时,程序会在当前工作目录生成 config.ini 和 logs 目录。此时默认连接信息只是占位值,关闭程序并填写正确配置后再重新启动。
配置说明
config.ini 示例:
[ssh]
host = 192.168.1.10
port = 22
username = app-log-reader
password = change-me
log_path = /opt/app/logs/catalina.out
[mongodb]
host = 192.168.1.20
port = 27017
username = issue-fixer
password = change-me
database = app_db
collection = assets
[settings]
log_retention_days = 30
connection_timeout = 5
| 配置项 | 说明 | 默认值 |
|---|---|---|
ssh.host |
SSH 服务器地址 | 127.0.0.1 |
ssh.port |
SSH 端口 | 22 |
ssh.username |
SSH 用户名 | username |
ssh.password |
SSH 密码 | password |
ssh.log_path |
远程日志文件的绝对路径 | /log_path/catalina.out |
mongodb.host |
MongoDB 地址 | 127.0.0.1 |
mongodb.port |
MongoDB 端口 | 27017 |
mongodb.username |
MongoDB 用户名 | username |
mongodb.password |
MongoDB 密码 | password |
mongodb.database |
认证库及业务数据库名称 | database |
mongodb.collection |
待更新的集合名称 | collection |
settings.connection_timeout |
SSH 和 MongoDB 连接超时,单位为秒 | 5 |
settings.log_retention_days |
预留的日志保留天数 | 30 |
Note
当前版本尚未使用
log_retention_days自动清理日志,旧日志需要手动归档或删除。
config.ini 含有明文密码,且已被 .gitignore 排除。请限制文件访问权限,不要将真实配置提交到版本库、聊天记录或工单附件中。
界面操作
- 测试连接:重新测试 SSH 和 MongoDB 连接。只有两项都显示“已连接”,才具备完整的自动修复条件。
- 开始:启动日志监控;从暂停状态点击时恢复监控。
- 暂停:停止读取当前日志流,但程序和连接仍然保留。
- 清除错误缓存:允许本次运行中已经成功修复或被判定为无法修复的
assetId再次参与处理。 - 退出:停止监控并关闭 SSH、MongoDB 连接。
窗口上半部分显示运行日志,下半部分显示无法自动修复的记录。连接测试会在程序启动后自动执行一次。
运行日志
日志按天写入:
logs/ESIssueAutoFixer_YYYY-MM-DD.log
常见级别包括 INFO、WARNING、ERROR 和 DEBUG。日志目录、运行配置和构建产物均已在 .gitignore 中排除。
编译为 Windows 7 可执行文件
这里的“编译”是指使用 PyInstaller 将 Python 解释器、程序和依赖打包为 EXE。目标电脑运行打包结果时不需要再安装 Python。
1. 准备构建电脑
推荐直接在 Windows 7 SP1 虚拟机或实体机中构建。PyInstaller 不是跨平台编译器;在 Windows 10/11 生成的程序可能引用 Windows 7 不具备的系统组件。PyInstaller 文档也建议面向旧版 Windows 时注意 Universal CRT,并指出在 Windows 7 上构建是可行方案。
安装 Python 3.8.10 时,可直接下载官方64 位离线安装程序或32 位离线安装程序:
- 根据目标机选择
Windows installer (32-bit)或Windows installer (64-bit)。 - 勾选 Add Python 3.8 to PATH。
- 保留
pip、tcl/tk and IDLE、py launcher。 - 安装结束后,在
cmd.exe中执行python --version确认版本。
构建架构由 Python 架构决定:
- 使用 32 位 Python 会生成 32 位 EXE,可运行于 32 位和 64 位 Windows 7,适合目标电脑架构不统一的情况。
- 使用 64 位 Python 会生成 64 位 EXE,只能运行于 64 位 Windows 7。
- 不能使用 64 位 Python 直接生成 32 位程序,需要另装 32 位 Python 后重新构建。
2. 安装固定版本依赖
把整个项目复制到构建电脑,打开项目目录中的 cmd.exe,执行:
python -m venv .venv
.venv\Scripts\activate.bat
python -m pip install pip==23.3.2
python -m pip install -r requirements-win7.txt
python -m pip list
如果构建电脑不能访问互联网,可先在一台同架构、同为 Python 3.8.10 的联网电脑下载离线安装包:
mkdir wheels
python -m pip download --only-binary=:all: --dest wheels -r requirements-win7.txt
将 wheels 目录复制到构建电脑,再执行:
python -m pip install --no-index --find-links=wheels -r requirements-win7.txt
3. 生成程序
优先使用目录模式,启动更快,也更容易在 Windows 7 上排查缺失的 DLL:
python -m PyInstaller --noconfirm --clean --onedir --windowed --name ESIssueAutoFixer ESIssueAutoFixer.py
构建成功后,程序位于:
dist\ESIssueAutoFixer\ESIssueAutoFixer.exe
部署时必须复制整个 dist\ESIssueAutoFixer 目录,不能只复制其中的 EXE。
如果确认目录版已在目标 Windows 7 电脑测试通过,也可以生成单文件版本:
python -m PyInstaller --noconfirm --clean --onefile --windowed --name ESIssueAutoFixer ESIssueAutoFixer.py
单文件版本位于 dist\ESIssueAutoFixer.exe。它每次启动都需要释放依赖到临时目录,启动速度和杀毒软件兼容性通常不如目录版,因此不是 Windows 7 的首选。
如需查看打包后被隐藏的启动错误,可临时去掉 --windowed 重新构建:
python -m PyInstaller --noconfirm --clean --onedir --name ESIssueAutoFixer-debug ESIssueAutoFixer.py
双击 dist\ESIssueAutoFixer-debug\ESIssueAutoFixer-debug.exe 后,错误会保留在命令行窗口中。
4. 部署前验证
至少完成以下检查:
- 在构建电脑运行 EXE,确认窗口可以正常打开。
- 将完整目录复制到一台未安装 Python 的 Windows 7 SP1 电脑。
- 双击 EXE,确认同级目录生成
config.ini和logs。 - 关闭程序,填写
config.ini,然后重新打开。 - 点击“测试连接”,确认 SSH 和 MongoDB 都显示“已连接”。
- 使用测试数据触发一条日期异常,确认日志识别、MongoDB 更新及本地日志均符合预期。
Note
执行上述 PyInstaller 命令时会自动生成适用于当前构建环境的
ESIssueAutoFixer.spec。该文件包含机器和平台相关配置,已被.gitignore排除,不需要随程序分发。
Windows 7 部署与使用
- 确认目标电脑是 Windows 7 SP1,并已安装与程序架构一致的 Microsoft Visual C++ 2019 Redistributable 14.29。不要使用当前最新的 Visual C++ 2026 运行库,因为它只支持 Windows 10 及更高版本。
- 将目录版的整个
ESIssueAutoFixer文件夹复制到本地可写目录,例如D:\Tools\ESIssueAutoFixer;不要直接放在只读共享目录中运行。 - 第一次双击
ESIssueAutoFixer.exe,等待生成config.ini,然后退出。 - 用记事本编辑
config.ini,保存 SSH、MongoDB 和日志路径配置。 - 再次启动程序,点击“测试连接”。
- SSH 和 MongoDB 均显示绿色“已连接”后,点击“开始”。
- 日常运行时可最小化窗口;需要停止读取日志时点击“暂停”,结束时点击“退出”。
如果通过快捷方式启动,请把快捷方式的“起始位置”设置为 EXE 所在目录,否则 config.ini 和 logs 可能生成到其他工作目录。
目标机提示缺少 DLL
如果出现 api-ms-win-crt-*.dll、VCRUNTIME140.dll 或类似缺失提示:
- 确认系统是 Windows 7 SP1,并安装所有可用的系统更新。
- 从 Microsoft 官方渠道安装与 EXE 架构一致的 Visual C++ 2019 14.29 运行库;32 位 EXE 即使运行在 64 位系统上也需要 x86 运行库。
- 重新启动电脑后再运行程序。
- 不要从非官方 DLL 下载站单独复制 DLL 文件。
双击 EXE 没有反应
先使用上面的调试命令生成带控制台版本,从窗口中读取实际错误。同时检查杀毒软件隔离记录、目录写权限和 Visual C++ 运行库。若程序是在 Windows 10/11 上构建的,应改到 Windows 7 SP1 环境重新构建。
常见问题
SSH 显示未连接
检查服务器地址、端口、账号密码和防火墙,并确认 SSH 用户可以读取 ssh.log_path。程序会自动接受服务器主机密钥,生产环境建议在代码层改为校验可信主机密钥。
SSH 已连接,但始终没有发现异常
- 日志必须包含小写
fail,grep匹配区分大小写。 - 异常文本必须与“工作流程”中的格式一致。
assetId必须完全由数字组成。- 远程环境必须支持
grep --line-buffered。 - 确认实际写入日志的文件与
ssh.log_path一致。
MongoDB 显示未连接
检查网络、用户名、密码、数据库名称和账号权限。当前连接使用 SCRAM-SHA-1,并把 mongodb.database 同时作为认证库和目标数据库;服务端认证配置需与此一致。
发现异常但数据库没有变化
- 确认集合中存在字符串类型且值完全一致的
assetId。 - 确认目标字段名称是
attr-IssueNo。 - 如果目标值本来就等于修复后的日期,MongoDB 的
modified_count会是0,程序不会记录“成功修复”。 - 查看当天日志中的“数据库更新失败”或连接错误。
同一个错误需要重新处理
点击“清除错误缓存”,或退出后重新启动程序。缓存只保存在内存中,不会跨进程保留。
已知限制与安全提示
- 自动修复会直接修改生产数据,没有预览、审批或回滚功能;建议先备份并使用最小权限账号。
- Windows 7、Python 3.8 和本文使用的兼容依赖均已停止或接近停止维护,不应把该电脑暴露到不可信网络;建议制定系统升级计划。
- 日志识别依赖固定的英文异常文本,应用或 Elasticsearch 升级后格式变化可能导致无法匹配。
- 监控命令中的日志路径直接来自配置文件,请只允许可信人员修改
config.ini。 - MongoDB 密码被直接拼入连接字符串;密码包含
@、:、/等 URI 保留字符时可能连接失败,当前版本不会自动进行 URL 编码。 - 日志文件会持续累积,当前版本不会按
log_retention_days自动清理。 - 程序没有自动重试数据库更新失败的专门队列;请结合运行日志确认最终结果。
项目结构
ESIssueAutoFixer/
├── ESIssueAutoFixer.py # 主程序、GUI、日志监控与数据修复逻辑
├── requirements-win7.txt # Windows 7 构建依赖及固定版本
├── ui-example-redacted.png # 已脱敏的程序界面示例
├── ui-example-id-redacted.png # 节目 ID 前半段已脱敏的自动修复示例
├── .gitignore
└── README.md

