logger.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /**
  2. * logger.js — 结构化日志
  3. *
  4. * 为什么单独成模块:设备脚本出错时,唯一能依赖的就是回传的日志。
  5. * 把日志格式固定下来(`[TTA][步骤名] 内容`),PC 侧就能按前缀过滤、按步骤计时,
  6. * 而不是靠人肉读一堆散乱的 console.log。
  7. *
  8. * 2026-10-13 增加**文件落盘通道**(sink):界面侧的「运行记录 → 详情的执行日志」
  9. * 要看的就是这些行。之所以不做成"界面去抓 console",是因为
  10. * console 是另一个进程的 stdout,界面根本读不到(见 bridge.js 的通道说明)。
  11. * sink 由 bridge 在启用宿主模式时装上,**独立运行时为空 → 零开销**。
  12. *
  13. * 依赖:无。始终通过 TikTokAuto.logger 取用,因此可以被放在 concat 顺序的最前面。
  14. */
  15. TikTokAuto.logger = (function () {
  16. 'use strict';
  17. var PREFIX = '[TTA]';
  18. var startedAt = Date.now();
  19. /** 文件落盘回调,由 bridge 注入:function(level, step, message) */
  20. var sink = null;
  21. function stamp() {
  22. return ('+' + (Date.now() - startedAt) + 'ms');
  23. }
  24. function write(level, step, message) {
  25. var line = PREFIX + stamp() + '[' + level + '][' + step + '] ' + message;
  26. console.log(line);
  27. if (sink) {
  28. /* 落盘失败绝不能影响流程:日志是"顺带记录的",不是"必须成功的"。 */
  29. try {
  30. sink(level, step, message);
  31. } catch (ignored) {
  32. /* 刻意吞掉:sink 抛错会把一次正常的日志调用变成流程中断 */
  33. }
  34. }
  35. }
  36. return {
  37. /** 装上文件落盘通道(传 null 卸载) */
  38. setSink: function (fn) {
  39. sink = typeof fn === 'function' ? fn : null;
  40. },
  41. /** 记录一次进入某步骤 */
  42. step: function (name, message) {
  43. write('STEP', name, message === undefined ? '' : message);
  44. },
  45. info: function (step, message) {
  46. write('INFO', step, message);
  47. },
  48. /** 可恢复的问题:值得记下来,但不中断流程 */
  49. warn: function (step, message) {
  50. write('WARN', step, message);
  51. },
  52. error: function (step, message) {
  53. write('ERROR', step, message);
  54. },
  55. /** 机器可读的结构化结果,PC 侧用它做断言 */
  56. result: function (payload) {
  57. console.log(PREFIX + 'RESULT ' + JSON.stringify(payload));
  58. },
  59. /** 从脚本开始到现在的耗时,用于定位"哪一步慢" */
  60. elapsedMs: function () {
  61. return Date.now() - startedAt;
  62. }
  63. };
  64. }());