ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SAP GUI Scripting 与脚本跟踪:用 Scripting Tracker 实现可审计的自动化

SAP GUI Scripting 与脚本跟踪:用 Scripting Tracker 实现可审计的自动化 简介SAP脚本工具Scripting Tracker是一款面向SAP系统管理员与开发人员的专业脚本管理插件聚焦解决大规模脚本变更时的追踪、对比与回滚难题。压缩包共19个文件约2.81MB包含Recorder.exe等主程序、jacob动态库、Interop.SAPFEWSELib.dll依赖组件以及csproj工程文件、cmd部署脚本、ps1自动化脚本、chm帮助文档和PDF说明手册另有Tracker.ini配置文件与Snippets.xml代码片段库清晰覆盖工具运行、二次开发与使用参考各环节。已有1293人学习下载。该工具具备版本控制、版本差异对比、快速回滚、部署管理、依赖关系分析及报告生成六大能力可有效降低人为误操作风险为系统升级和故障排查提供完整历史记录。尤其适合大型企业复杂SAP环境能够帮助用户在严格管控脚本质量的同时显著提升日常运维效率与系统稳定性。1. Scripting Tracker在SAP日常里的位置为什么脚本老是“会跑不会管”SAP 项目实施和运维里真正折磨人的往往不是 ABAP 开发而是那些“每天都要点一遍”的 GUI 操作物料计划员上班先开 MD04 看供需财务同事月末跑清账凭证供应链团队用 LSMW 批量导入采购订单含税价格。很多人录过 VBScript 脚本但录完之后脚本散落在 C 盘桌面谁改过、什么时候跑的、运行结果对不对没人能说清。Scripting Tracker 就是这样一类 SAP 脚本工具它在 SAP GUI Scripting 之上加了一层任务上下文、参数快照、结果标记和日志审计让脚本从“能跑”变成“能追踪”。适合做内部自动化支持的一线顾问、ITBP 和系统管理员也适合正要给团队搭一套脚本管理规范的人读。读完你能知道它解决的是“脚本能不能放心交给业务”的问题。2. 从SAP GUI Scripting到Scripting Tracker原理、选型和最小落地路径2.1 脚本跟踪到底在跟踪什么对象模型、事件和调用链SAP GUI 客户端里的自动化入口是本地 COM 组件 SapGuiAuto。通过它拿到 ScriptingEngine再往下是 Connection 和 Session。Session 里能看到当前用户、客户端、事务码、单个窗口的控件树。Scripting Tracker 要做的不是替你再发明一套操作 SAP 的方式而是把这棵控件树上的动作记录下来一开始是什么事务中间打开过哪些窗口最后停在哪个消息上。这套机制是 SAP 官方给客户端的控制通道不碰后台表也不碰 BAPI所以它适合做“把屏幕操作变成可审计动作”的任务。我一般会在脚本壳里维护一个current_session对象所有事务跳转和数据读取都通过它。下面这段是连接并定位目标会话的最小代码import win32com.client def get_tracker_session(user_keyword: str TRACKER_USER) - object: gui win32com.client.Dispatch(SapGuiAuto).GetScriptingEngine for conn in gui.Children: for session in conn.Children: info session.Info if user_keyword in info.User or user_keyword in info.Client: return session raise RuntimeError(未找到可跟踪的SAP GUI会话)这段代码的逻辑是先拿到 SAP GUI 的脚本引擎再遍历所有连接和会话返回当前登录用户或客户端里带有关键字的那个会话。参数说明user_keyword一般是登录账号前缀比如要盯一组财务账号就传FICO。不建议按连接字符串硬编码因为不同跳板机的连接名经常变按用户和客户端去匹配最稳。如果同事开了多个 SAP 窗口循环里能直接区分业务账号和测试账号避免把自动化任务挂到不对的会话上。有了 session 之后跟踪器就能读到session.Info.Transaction得到当前事务码读session.findById(wnd[0]/sbar).Text拿到状态栏文本。所有想追踪的信息本质上是这些对象属性在时间轴上的快照。所谓“脚本跟踪”就是把这些快照按任务维度写下来而不是零散地打印在控制台里。还有一个关键点SAP GUI Scripting 没有真正意义上的全局事件钩子你没法监听“用户下一步点了哪里”。常见做法是在你封装的每一个动作函数前后各写一次日志让动作序列变成可回放的调用链。这样出了问题日志里能看到它到底卡在哪一步。2.2 为什么不用“录一段VBS”就打天下Scripting Tracker的选型边界SAP GUI 自带录制功能生成 VBScript 只需要几分钟。但它有个问题录出来的脚本只覆盖“录制者本人当时那一条点击路径”一旦物料号变了、日期格式变了、用户主题从蓝变高对比度脚本立刻翻车。更麻烦的是录脚本没有审计谁跑了哪一版、改了哪些参数完全无据可查。Scripting Tracker 不是把录屏丢了而是在录屏外套一层“能管理”的结构。我在选型时通常看四件事能不能参数化、有没有错误恢复位置、执行结果是不是结构化存储、能不能被外部调度器调用。原生 VBScript 几乎没有答案Scripting Tracker 的定位就是补这四块。它不适合的场景也要说清楚它只跑在安装着 SAP GUI 的 Windows 机器上不能替代后台接口它操作的是屏幕元素不是 BAPI所以性能一定不如直连后台。若你的自动化是高并发的数据修正正确的方向是接口化而不是继续给 GUI 加壳。对比维度原生VBScript录屏Scripting Tracker参数化每次改脚本任务模板外置参数失败恢复无失败即停超时重试加结果标记审计日志基本无按任务写快照和状态外部调度需要手工包一层自带命令行入口这个表不是否定 VBScript而是说明在“脚本要交出去用”的场景里多出来的这层管理成本是值得的。尤其当业务方开始问“刚才那次导入是谁跑的”你就知道原生录屏完全答不上来。2.3 最小落地路径先跑通一个会写日志的脚本壳把上面两层思路合一我建议第一天只做一个壳能拿到 session能跑事务能在每个步骤前后写一条日志。下面这段是我最常用的最小实现import time from pathlib import Path class TrackerShell: def __init__(self, session): self.session session self.log_file Path(logs) / f{time.strftime(%Y%m%d_%H%M%S)}.log self.log_file.parent.mkdir(exist_okTrue) def log(self, level: str, event: str, detail: str ): line f{time.strftime(%Y-%m-%d %H:%M:%S)} {level} {event} {detail} with self.log_file.open(a, encodingutf-8) as f: f.write(line \n) print(line) def run_tcode(self, tcode: str, wait_seconds: float 1.0): self.log(INFO, enter_tcode, tcode) ok self.session.findById(wnd[0]/tbar[0]/okcd) ok.text tcode self.session.findById(wnd[0]/tbar[0]/btn[0]).press() time.sleep(wait_seconds) self.log(INFO, tcode_ready, self.session.Info.Transaction)逻辑说明run_tcode做的是往 SAP 的命令框里写事务码再按回车。真正值得关注的是log方法它把每个关键动作都写到带日期的日志文件里。参数说明wait_seconds不能给太大否则任务排队时间被拉长也不能给太小否则事务还没打开就开始下一步。先给 1 秒起步遇到已知慢事务再单独加长。从这一天开始你的脚本就不再是黑匣子至少你知道它停在哪一步能不能复盘已经有了交代。2.4 边界意识什么时候不该让脚本去碰屏幕Scripting Tracker 解决了“屏幕操作可追踪”但也容易让人贪多。比如大批量跑 MRP 运算、月度重估、海量主数据迁移这些操作一旦放到 GUI 脚本层面不仅慢而且会因为用户会话被占用而影响正常办公。我的判断标准是单次操作如果超过 20 分钟或者需要跑的数据量超过几千行优先评估 RFC、BAPI、中间件批处理而不是继续用脚本去点屏幕。Scripting Tracker 的最佳位置是“小步快跑、需要人来参与确认”的任务比如查询后核对、导入前检查、界面字段联动校验。把它的边界划清楚反而能让这套工具用得长久。3. 搭一个能用的Scripting Tracker核心配置、任务模板与运行目录3.1 打开SAP GUI Scripting开关从勾选项到脚本验证的三步很多脚本“连不上”第一步不是代码问题而是 SAP GUI 设置里把脚本功能关了。SAP GUI 安装后默认并不允许外部脚本控制界面需要在“SAP GUI 选项”的“脚本”或“Scripting”页面里勾选“激活脚本”。我这里说的不是某个具体版本的截图而是这类客户端的通用设置你打开选项窗口后搜索“script”一定能看到相关开关。对要交付给多个用户的场景管理员应该用统一的配置下发而不是让每个用户自己去勾。SAP GUI Scripting 的开关之外还有一个容易被忽略的点很多企业网络侧会拦截本地 COM 自动化。常见做法是先在客户端本机验证确认脚本能读当前会话信息。验证脚本很简单def verify_scripting(session): info session.Info print(fUser{info.User}, Client{info.Client}, Transaction{info.Transaction}) if info.Transaction : raise RuntimeError(当前会话没有打开任何事务请先在SAP GUI里执行一个事务)参数说明Info.User是当前登录账号Info.Client是客户端编号Info.Transaction是当前事务码。如果脚本能打出这三项说明 SAP GUI 已经把控制权交给了本地脚本如果第一行就超时直接去查客户端设置。见过不少新同事上来就写 findById结果连事务码都读不到还以为是代码问题实际是设置没开。3.2 任务模板与运行目录让每一条自动化都有可追溯上下文Scripting Tracker 能不能落地看你能不能坚持“一个任务一个目录”。我习惯把这套工具的工作目录固定成tracker/ tasks/ # 任务模板JSON文件 work/ # 每次运行的参数快照、导入文件副本 logs/ # 运行日志 results/ # 结构化结果标记tasks目录里放的不是脚本文件而是任务定义。以下面的 MD04 查询为例{ task_id: md04_supply_demand, sap_tcode: MD04, auth_user_pattern: PLANNER, timeout_seconds: 120, params: { material: 000000000100000001, plant: 1000 }, track: { on_entry: [tcode, params.material], on_exit: [status_text, grid_row_count] } }这个模板解决的是“脚本参数写死在代码里”的坏习惯。sap_tcode是事务码params.material是外部传入的物料号track.on_exit告诉执行器在任务结束后抓哪些状态。执行器读到 JSON按模板生成运行目录而不是让每个脚本各自为政。读取模板的代码可以很薄import json import time from pathlib import Path def load_task(config_path): with open(config_path, encodingutf-8) as f: config json.load(f) run_id time.strftime(%Y%m%d_%H%M%S) run_dir Path(work) / f{config[task_id]}_{run_id} run_dir.mkdir(parentsTrue, exist_okTrue) return config, run_dir逻辑说明这段代码把 JSON 模板读进来再按任务 ID 加时间戳生成运行目录。参数说明run_id到秒级已经够用同一个任务如果一秒内跑两次可以把秒换成毫秒但没必要为此牺牲可读性。目录一旦生成本次运行的所有参数快照、导入文件、网格数据都该放进这个目录避免日志文件满天飞。3.3 跑通第一个可追踪任务从 MD04 事务到状态栏捕获光有模板还不够要有一个能真正执行它的入口。我比较常用的命令行入口长这样python tracker_cli.py \ --task tasks/md04_supply_demand.json \ --param material000000000100000001 \ --run-dir work/20240520_md04 \ logs/out.log 21 echo $?--param覆盖模板里的默认参数--run-dir指定本次运行目录echo $?拿到 Python 进程退出码。这样脚本就能被 Windows 任务计划程序或 Jenkins 挂起来不再依赖人肉双击。任务计划程序里要注意SAP GUI 必须在同一个桌面会话里能打开用“不管用户是否登录都要运行”的方式会导致脚本找不到 GUI 窗口。对应的执行代码里最关键的是“跑完事务后抓状态栏”def capture_status(session): statusbar session.findById(wnd[0]/sbar) return { status_text: statusbar.Text, status_type: statusbar.MessageType }逻辑说明SAP GUI 的状态栏sbar会显示当前事务的最后一条消息。MessageType的常见取值里S代表成功E代表错误A代表终止W代表警告。Scripting Tracker 应该把MessageType作为结果标记的一部分而不是只记录“脚本跑完了”。如果任务要求查 MD04 但最终状态是 E说明这次追踪是失败的。这个字段也是后面回归基线的主要比较对象。3.4 运行目录轮转别让日志把 C 盘占满脚本一旦挂上任务计划程序日志的增长速度比你想象得快。一个每天跑十条任务的脚本日志文件按天拆分一个月下来也没多少怕的是每次运行都往同一个文件追加又不做清理半年后 C 盘塞满。常见做法是只保留最近 30 天运行目录def cleanup_old_runs(run_root: Path, keep_days: int 30): cutoff time.time() - keep_days * 86400 for child in run_root.iterdir(): if child.is_dir() and child.stat().st_mtime cutoff: shutil.rmtree(child)逻辑说明遍历运行目录根节点删除修改时间早于保留期的子目录。参数说明keep_days设 30 适合日常审计如果公司有财务数据保留要求清账凭证相关任务可以单独放到另一个目录保留周期改到 180 天。清理动作建议放在任务调度的最后一步不要放在任务开始前不然还没跑完就删掉之前的证据。4. 把日常事务变成可跟踪任务MD04/MD07查询与LSMW导入的写法4.1 把“看物料供需”变成可复现命令MD04/MD07任务模板改造在 SAP 的物料计划岗位每天上班第一件事基本就是看 MD04 的物料供需情况再切到 MD07 看库存/需求清单。这两件事特别适合做成 Scripting Tracker 任务原因很简单步骤固定、参数少、结果需要留痕。把上一节 JSON 模板从md04_supply_demand复制一份改名md07_inventory_demand事务码改成MD07即可。同一个执行器不需要改代码这就是参数化的意义。比较容易被忽略的是“物料号前导零”问题。SAP 内部看到 18 位物料号但用户在查询框里往往只输最后几位。脚本参数如果直接透传十个用户里会有三个把物料号写错。我一般会在执行器里统一补零def normalize_material(material: str, length: int 18) - str: material material.strip() if material.isdigit(): return material.zfill(length) raise ValueError(f物料号必须为数字, 收到: {material})参数说明length默认 18适用于内部 18 位数值物料号如果客户启用了字母数字物料号就不能补零要按主数据规则走。脚本里做这一步比让业务用户手工补零可靠得多。物料号不对后面所有供需结果都是错的而脚本日志里只会留下一个“查不到”的谎言。MD04 查询的结果通常是 ALV 网格。读取网格时要养成“先看行数再取数”的习惯def read_alv_grid(session, grid_idwnd[0]/usr/cntlGRID1/shellcont/shell/shellcont[0]/shell): grid session.findById(grid_id) row_count grid.RowCount if row_count 0: return {row_count: 0, rows: []} columns [grid.GetColumnName(i) for i in range(grid.ColumnCount)] rows [] for r in range(min(row_count, 100)): rows.append({col: grid.GetCellValue(r, c) for c, col in enumerate(columns)}) return {row_count: row_count, rows: rows, columns: columns}逻辑说明GetColumnName拿到列名GetCellValue逐格取值。限制最多取 100 行是为了避免把大量数据一次性拖进内存若日志需要全量快照可以改成流式写文件。参数说明grid_id在标准布局里基本一致但客户做过增强以后经常变化所以我把 grid_id 留在任务模板里而不是写死在代码中。这就是为什么track.on_exit里要有grid_row_count先看行数对不对再决定要不要把网格内容归档。查询结果可以顺手导出 CSV 放进运行目录满足 SAP 数据追溯的要求。4.2 给LSMW导入加“后悔药”参数快照和导入文件备份LSMW 是 SAP 老牌的数据迁移工具用来导物料主数据、采购订单含税价格、清账凭证这类批量数据。Scripting Tracker 在 LSMW 场景里最该做的不是替用户把整条批输入路径录完而是把“导入前”和“导入后”的关键状态固定下来。常见做法是由业务顾问手工创建一个 LSMW 项目脚本只负责打开 LSMW、选择已录好的批输入会话、执行导入并把源文件按校验码备份到本次运行目录。导入前一定要做源文件快照。别信“这个文件反正放在共享盘”这种话批输入一旦执行源文件被覆盖是常有的事。import hashlib, shutil from pathlib import Path def snapshot_input_file(src: Path, run_dir: Path) - str: raw src.read_bytes() checksum hashlib.sha256(raw).hexdigest()[:12] dst run_dir / f{src.stem}.{checksum}{src.suffix} shutil.copy2(src, dst) return checksum逻辑说明这段代码把源文件复制到本次运行的run_dir下并用 SHA-256 的前 12 位作为校验码藏进文件名。之后无论谁改了共享盘文件日志里都能指出“当时跑批用的是哪一个文件”。参数说明checksum长度 12 足够日常去重如果你所在行业有合规要求用完整哈希不要截断。这一步的成本很低但发生数据问题后你会庆幸自己留了这一手。LSMW 执行完成后脚本还要去批输入监控里收结果。SAP 的批输入会话在 SM35 事务里能看到。对脚本化来说比较省事的方式不是逐行解析 SM35 的网格而是把 LSMW 输出里的总记录数、错误记录数抓到结果文件里。任务一旦检测到错误数不为 0就暂停后续动作而不是继续往下跑。这就是“后悔药”的关键错误发生时源文件和执行日志都在才有回滚和对账的资本。4.3 清账凭证与含税价格字段哪些界面值必须写进跟踪日志财务和采购场景里清账凭证、PO 含税价格这类界面有很多动态容器把值读出来还不够还要知道它“属于哪一单”。脚本跟踪器在记录时至少要包含四类信息当前事务码、屏幕关键字段的值、状态栏消息、源文件或单据号。很多脚本只记“OK”结果出了问题连是哪张凭单都不知道这种日志基本没有用。对于 ALV 表格里的字段不要直接记录表头的显示文本而要记录底层字段名。显示文本会随语言、布局、增强而变化字段名稳定得多。比如采购订单里的含税价格相关字段不同客户增强出来的 Z 字段千差万别但它在数据字典里的名称是固定的。所以 Scripting Tracker 的字段映射应该做成一个字典文件{ field_alias: { purchase_order: EBELN, net_price: NETWR, with_tax_price: ZTAXPRICE } }逻辑说明脚本从网格里取数以后先按field_alias把显示名映射成数据字典字段名再写入 JSON 结果。参数说明ZTAXPRICE是示例性的自增强字段名不一定存在你的系统里看到这个文件时你应该改成自己系统的真实增强字段。这么做的原因是业务用户问“这批含税价格为什么变了”时你能直接回答是哪个字段在哪个屏幕被改的而不是回一句“脚本跑完了”。4.4 把校验做到数据表层面生产版本与Query报表的自动化MD04、LSMW 这些任务都盯着屏幕但很多主数据维护任务更适合“跑完屏幕再查表”。比如 PP 模块里的生产版本创建和修改事务码 C223 对应后台表 MKAL脚本在 C223 界面上填入版本和物料后只读状态栏消息不一定可靠因为业务校验可能通过了但版本行没有真正写进表里。常见做法是脚本跑完 C223 后用同一个会话打开 SE16N 或 SE11 查 MKAL 的对应记录把版本号、物料号、有效日期抓出来存进结果文件。这个动作能直接把“界面操作”和“后台落库”对上。SAP Query 报表也是类似。事务码 SQ01 建的查询脚本只需要知道查询名和参数就能从 GUI 上反复执行并把结果网格内容保存下来。查询报表的 TCode 不同但取数逻辑和之前read_alv_grid完全一样。只要你把“报表名 参数 结果行数 结果文件”四件套记录全业务部门就不再需要每周手工导一次 Excel。工具本身没有多玄关键是让每一次执行都有据可查。5. Scripting Tracker避坑指南5条常见故障与排查路径5.1 现象脚本能连上SAP GUI但findById找不到控件SAP GUI 脚本化最常翻车的就是findById抛“Control not found”。现象是脚本在某个wnd[0]/usr/...上卡住崩溃日志里只有异常堆栈没有上下文。原因通常有两个一是被查控件还没画出来脚本抢跑二是控件技术名称在当前窗体里确实变了。解决办法不是加大 sleep而是轮询等待加超时。def wait_for(session, control_id, timeout15.0, interval0.5): deadline time.time() timeout while time.time() deadline: try: return session.findById(control_id) except Exception: time.sleep(interval) raise TimeoutError(f控件超时未出现: {control_id})参数说明interval设 0.5 秒已经够用太快会占用 GUI 线程timeout根据事务复杂度调整普通事务 15 秒足够LSMW 批输入执行建议单独放宽。把wait_for封装成所有控件访问的必经函数很多偶发问题会从“玄学”变成“能看到在等哪个控件”。5.2 现象MD04/MD07查询脚本偶发返回0行日志却是成功这个坑我踩过好几次。现象是脚本去读 ALV 网格行数为 0但脚本继续往后走最后把结果写成“成功”。原因往往是查询已经触发但 ALV 内容还没刷新完读取动作发生在数据落盘之前。另一个常见原因是没有做物料号前导零规范化查询条件本身不符合 SAP 内部存储格式。解决方法是把“行数不为 0”作为成功标记的必要条件if result[row_count] 0: marker grid_empty_unknown log(WARN, grid_empty, result) else: marker grid_data_ok log(INFO, grid_data_ok, frows{result[row_count]})逻辑说明grid_empty_unknown不是失败也不该算成功而是“结果不确定”。在回归报告里这种未知状态要比错误状态更显眼因为它意味着脚本可能没等到数据而不是业务上没有数据。参数说明如果你确认业务上允许 0 行结果再把这个标记命名为grid_empty_expected不要在默认情况下把它当成功。特别是 MD04 这种供需查询0 行往往意味着物料号输错了。5.3 现象LSMW批输入跑了但只有部分记录成功LSMW 执行批输入时SAP 会跳过不符合业务规则的行任务不会因为某几行失败而整体报错。现象是脚本日志显示“执行完成”业务对账却发现 50 条里只有 40 条进去了另外 10 条被拒。原因也很简单批输入监控里的失败明细还在脚本没有去收。解决方法是脚本必须在执行完成后打开批输入会话的消息列表统计成功/失败/错误数量并把失败行号写入结果文件。可以选择用 SM35 事务进入会话日志再抓取里面的错误明细也可以让 LSMW 项目配置成“前台显示错误”但那样自动化程度会降低。我一般倾向于保留批输入会话的日志不做“全部成功”的假设。脚本里加一个断言if error_count 0 or warning_count 0: raise RuntimeError(fLSMW批输入存在非成功记录: errors{error_count}, warnings{warning_count})参数说明这个断言要放在所有结果写完之后不要放在刚刚开始时。原因是你需要把错误明细留档而不是让脚本第一时间中断。只报“有错误”没有明细等于把用户推向另一个黑匣子。5.4 现象同一条清账任务被重复执行SAP 清账凭证这类操作业务上最怕的是重复过账。现象是脚本被调度系统重跑了一次结果在总账里产生了两笔相同金额的凭证。原因是脚本本身没有幂等检查只判断“上次是不是执行成功”没有判断“这批数据是不是已经入账”。解决方法是给任务定义一个幂等键并把幂等键写进结果标记completed_keys load_completed_keys(run_dir) if item_key in completed_keys: print(fskip: {item_key} already processed) return 0逻辑说明item_key可以组合来源文件名、批次号、入账日期和唯一行号。只要检测到同一个 key 已有成功标记就跳过或只出报告不再执行写操作。参数说明这个幂等检查必须在执行任何写动作前完成如果失败结果文件里要留下“重复跳过”的记录方便后续对账。别把幂等逻辑写在界面成功后因为界面成功和入账成功之间还隔着一次后台提交。5.5 现象同一个脚本在部分用户机器上失败这里有真实的血泪经验脚本在我自己的高分辨率笔记本上天天跑得好好的交付到同事的低分辨率屏幕上就开始找不到按钮。原因不是 SAP 系统不同而是用户界面缩放、字体、窗口布局把控件技术名里的容器编号搞变了。解决方法是两个原则不用坐标点击能躲就躲脚本里所有的控件 ID 都从任务模板读而不是从录制时的固定路径写死。如果团队统一了 SAP GUI 主题和显示缩放这种问题会少一半。脚本上线前至少找一台低分辨率和一台高分屏机器各跑一遍比写一堆异常捕获更管用。6. 让Scripting Tracker跑得更可靠回归模板、结果标记和告警钩子Scripting Tracker 用起来以后下一步就是别让它变成新的黑匣子。我每接一个任务都会顺手生成一张回归基线任务参数不变期望结果里的行数范围、状态消息类型、幂等跳过数量记录下来。每天晚上让批处理把当天所有任务结果和基线做一次 diff差异不等于失败但会在报告里标红。这个动作不需要复杂的测试框架一个结果目录加一个文本 diff 就够了。一个可靠的结果标记最好不是布尔值而是一个枚举。我惯用的标记有sap_tcode_ok、grid_data_ok、grid_empty_unknown、lsmw_errors_found、idempotent_skipped、timeout_failed。每个标记都对应日志里的固定写法这样回归脚本不用猜“successTrue 到底是什么意思”。比如 LSMW 导入成功跑完并不代表数据正确只有lsmw_errors_found为 0 时才值得继续往业务侧发布结果。告警钩子不需要做得很重。最简单的方式是脚本在结束前检查结果标记只对标记是lsmw_errors_found或timeout_failed的任务发起一个 HTTP POST 到值班系统def notify_if_bad(marker: str, endpoint: str): if marker in (lsmw_errors_found, timeout_failed): requests.post(endpoint, json{marker: marker, run_id: run_id}, timeout3)逻辑说明requests.post只负责把结果推送出去不等待告警页面打开避免通知逻辑拖慢主流程。参数说明endpoint指向团队成员自己的告警聚合服务没有就先用企业微信机器人或邮件接口核心是“只在异常时打扰人”。以前我也只写脚本不写回归等到一次采购订单含税价格批量导错花了两天对账才意识到日志里没有基线就永远不知道系统是什么时候开始变的。从那以后我坚持每个任务必须有结果标记和回归基线宁可少一点花活也绝不放弃可追溯。希望这个思路对你也有用。本文还有配套的精品资源点击获取
返回列表