| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- /**
- * logger.js — 结构化日志
- *
- * 为什么单独成模块:设备脚本出错时,唯一能依赖的就是回传的日志。
- * 把日志格式固定下来(`[TTA][步骤名] 内容`),PC 侧就能按前缀过滤、按步骤计时,
- * 而不是靠人肉读一堆散乱的 console.log。
- *
- * 2026-10-13 增加**文件落盘通道**(sink):界面侧的「运行记录 → 详情的执行日志」
- * 要看的就是这些行。之所以不做成"界面去抓 console",是因为
- * console 是另一个进程的 stdout,界面根本读不到(见 bridge.js 的通道说明)。
- * sink 由 bridge 在启用宿主模式时装上,**独立运行时为空 → 零开销**。
- *
- * 依赖:无。始终通过 TikTokAuto.logger 取用,因此可以被放在 concat 顺序的最前面。
- */
- TikTokAuto.logger = (function () {
- 'use strict';
- var PREFIX = '[TTA]';
- var startedAt = Date.now();
- /** 文件落盘回调,由 bridge 注入:function(level, step, message) */
- var sink = null;
- function stamp() {
- return ('+' + (Date.now() - startedAt) + 'ms');
- }
- function write(level, step, message) {
- var line = PREFIX + stamp() + '[' + level + '][' + step + '] ' + message;
- console.log(line);
- if (sink) {
- /* 落盘失败绝不能影响流程:日志是"顺带记录的",不是"必须成功的"。 */
- try {
- sink(level, step, message);
- } catch (ignored) {
- /* 刻意吞掉:sink 抛错会把一次正常的日志调用变成流程中断 */
- }
- }
- }
- return {
- /** 装上文件落盘通道(传 null 卸载) */
- setSink: function (fn) {
- sink = typeof fn === 'function' ? fn : null;
- },
- /** 记录一次进入某步骤 */
- step: function (name, message) {
- write('STEP', name, message === undefined ? '' : message);
- },
- info: function (step, message) {
- write('INFO', step, message);
- },
- /** 可恢复的问题:值得记下来,但不中断流程 */
- warn: function (step, message) {
- write('WARN', step, message);
- },
- error: function (step, message) {
- write('ERROR', step, message);
- },
- /** 机器可读的结构化结果,PC 侧用它做断言 */
- result: function (payload) {
- console.log(PREFIX + 'RESULT ' + JSON.stringify(payload));
- },
- /** 从脚本开始到现在的耗时,用于定位"哪一步慢" */
- elapsedMs: function () {
- return Date.now() - startedAt;
- }
- };
- }());
|