mcpField
D
debugging-techniques

debugging-techniques

github.com/happy-technologies-llc开发4143 次安装3 天前更新
代码仓库

关于 debugging-techniques

面向 ServiceNow 开发者、管理员和支持工程师的调试指南,涵盖服务端与客户端脚本、日志及常见错误。它结合平台调试器、浏览器开发工具和 MCP 查询工具定位问题。

主要功能

  1. 01分析服务端日志和脚本执行记录
  2. 02使用 Script Debugger 逐步调试
  3. 03借助浏览器工具排查客户端脚本
  4. 04检查事务性能与慢查询
  5. 05诊断业务规则、工作流和流程

适用场景

  1. 01排查业务规则或脚本错误
  2. 02分析客户端请求和网络错误
  3. 03定位慢查询及流程执行问题

MCP 相关

该技能使用 ServiceNow MCP 服务的表查询、记录获取和后台脚本工具,检查日志、脚本与执行记录。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/happy-technologies-llc/happy-platform-skills --skill debugging-techniques

安装后在 Claude Code 中输入/debugging-techniques确认已加载。

详细介绍

ServiceNow 调试技巧

概述

掌握使用内置工具和技巧调试 ServiceNow 应用的方法。本技能涵盖服务器端调试、客户端调试、日志分析和常见错误排查。

  • 解决什么问题? 识别并解决业务规则、脚本包含文件、客户端脚本、工作流和流程中的问题
  • 谁应该使用此技能? ServiceNow 开发人员、管理员和支持工程师
  • 预期结果是什么? 更快地识别问题、高效排查故障并编写更整洁的代码

先决条件

  • 所需 ServiceNow 角色:使用 Script Debugger 需要 admin 或 script_write
  • 有权访问 System Logs(System Logs > All)
  • 了解浏览器开发者工具(Chrome DevTools、Firefox Developer Tools)
  • 了解 JavaScript 基础知识

流程

服务器端调试
日志记录函数

ServiceNow 为服务器端脚本提供了多个日志记录函数。请根据日志级别和可见性要求选择。

函数日志级别使用场景
gs.log(message, source)调试开发/测试——旧版函数,建议使用 gs.debug
gs.debug(message)调试详细故障排查(需要启用调试)
gs.info(message)信息常规操作的提示性消息
gs.warn(message)警告不会中止执行的潜在问题
gs.error(message)错误需要处理的错误

最佳实践:日志消息中始终包含上下文:

// BAD - No context
gs.info('Record updated');

// GOOD - Full context
gs.info('[IncidentHandler] Incident ' + current.number + ' updated by ' + gs.getUserName() +
        ' - State changed from ' + current.state.getDisplayValue() + ' to ' + previous.state.getDisplayValue());

查询系统日志:

Tool: SN-Query-Table
Parameters:
  table_name: syslog
  query: source=IncidentHandler^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
  fields: sys_created_on,level,message,source
  limit: 50
  order_by: sys_created_on
  order_by_desc: true
Script Debugger

Script Debugger 支持逐步执行服务器端脚本。

启用 Script Debugger:

  1. 转到 System Diagnostics > Script Debugger
  2. 点击 Enable Debugging,为当前会话启用调试
  3. 使用调试器 UI 在脚本中设置断点
  4. 触发脚本(例如,更新一条记录)
  5. 使用 F10(单步跳过)、F11(单步进入)、F5(继续)逐步执行代码

调试业务规则:

Tool: SN-Query-Table
Parameters:
  table_name: sys_script
  query: collection=incident^active=true
  fields: name,order,when,script,condition
  limit: 50
  order_by: order

主要功能:

  • 变量检查(将鼠标悬停在变量上)
  • 调用堆栈可视化
  • 监视表达式
  • 条件断点
会话调试模块

在会话期间为特定组件启用详细日志记录。

常见会话调试模块:

模块用途启用路径
Session Debug调试所有会话System Diagnostics > Session Debug > All
Business Rules记录 BR 执行情况System Diagnostics > Session Debug > Business Rules
SQL记录数据库查询System Diagnostics > Session Debug > SQL
Security调试 ACLSystem Diagnostics > Session Debug > Security
Client Scripts记录客户端脚本数据System Diagnostics > Session Debug > Client Scripts

通过脚本启用:

// Enable business rule debugging for current session
gs.setProperty('glide.debugger.current.enabled', 'true');
脚本执行历史

跟踪脚本执行情况以排查问题。

Tool: SN-Query-Table
Parameters:
  table_name: sys_script_execution_history
  query: sys_created_onONLast 1 hour@javascript:gs.hoursAgo(1)@javascript:gs.nowDateTime()
  fields: script,execution_time,status,error_message,sys_created_on
  limit: 100
  order_by: sys_created_on
  order_by_desc: true

客户端调试

浏览器控制台方法
方法用途
console.log()常规日志记录
console.info()提示性消息
console.warn()警告消息
console.error()错误消息
console.table()以表格形式显示数据
console.trace()显示调用堆栈

ServiceNow 专用方法:

// jslog - ServiceNow legacy logging (outputs to console when enabled)
jslog('Client script executed: ' + g_form.getValue('number'));

// Check if debug mode is enabled
if (window.NOW && NOW.debug) {
    console.log('[DEBUG] Form loaded for: ' + g_form.getValue('sys_id'));
}
浏览器 DevTools 调试

Chrome DevTools 工作流:

  1. 打开 DevTools(F12 或 Cmd+Option+I)
  2. 转到 Sources 标签页
  3. 在 scripts.do?sysparm_type= 下或页面源代码中查找客户端脚本
  4. 点击行号设置断点
  5. 使用 Watch 面板监视变量
  6. 使用 Scope 面板检查局部变量/闭包变量

实用 DevTools 命令:

// In Console - Inspect form field
g_form.getValue('short_description');

// Get all form values
g_form.serialize();

// Check if field is mandatory
g_form.isMandatory('priority');

// Inspect GlideAjax response
// Set breakpoint in callback function to inspect 'response' object
网络选项卡分析

监控 AJAX 调用和 API 请求:

  1. 打开 DevTools > Network 选项卡
  2. 按 XHR/Fetch 筛选
  3. 查找以下调用:
    • xmlhttp.do - GlideAjax 调用
    • api/now/ - REST API 调用
    • sysparm_processor - 表单提交

常见网络问题:

  • 401/403 错误 - 身份验证/ACL 问题
  • 500 错误 - 服务端脚本错误
  • 响应缓慢 - 在 Timing 选项卡中查看细分情况

事务日志

分析事务性能
Tool: SN-Query-Table
Parameters:
  table_name: syslog_transaction
  query: sys_created_onONLast 1 hour@javascript:gs.hoursAgo(1)@javascript:gs.nowDateTime()^urlLIKEincident
  fields: url,response_time,user,sys_created_on,status
  limit: 50
  order_by: response_time
  order_by_desc: true
检测慢查询
Tool: SN-Query-Table
Parameters:
  table_name: syslog
  query: messageLIKEslow query^sys_created_onONToday@javascript:gs.beginningOfToday()@javascript:gs.endOfToday()
  fields: sys_created_on,message,source
  limit: 100

调试业务规则

了解业务规则的执行顺序

对于每项操作(插入、更新、删除),业务规则按以下顺序执行:

  1. before 规则(按顺序升序)- 在写入数据库之前执行
  2. after 规则(按顺序升序)- 在写入数据库之后执行
  3. async 规则 - 异步执行

关键:顺序很重要!

Tool: SN-Query-Table
Parameters:
  table_name: sys_script
  query: collection=incident^active=true^when=before
  fields: name,order,when,condition,script
  limit: 100
  order_by: order

调试顺序问题:

// Add to each business rule to trace execution order
gs.info('[BR Debug] ' + current.sys_class_name + ' - ' +
        'Name: ' + current.getTableName() + '_BR_Name - ' +
        'Order: ' + 100 + ' - ' +
        'When: before - ' +
        'Record: ' + current.number);
常见业务规则调试模式

检查脚本是否正在运行:

(function executeRule(current, previous) {
    gs.info('[BR_NAME] Script starting for: ' + current.getDisplayValue());

    // Your logic here

    gs.info('[BR_NAME] Script completed');
})(current, previous);

调试条件:

// Log condition evaluation
gs.info('[BR_NAME] Condition check - current.state: ' + current.state +
        ', previous.state: ' + previous.state +
        ', Result: ' + (current.state != previous.state));

检查当前值与之前的值:

// Log all changed fields
var changes = current.changesLog();
if (changes) {
    gs.info('[BR_NAME] Changes: ' + changes);
}

调试工作流和流程

工作流调试

查询工作流上下文:

Tool: SN-Query-Table
Parameters:
  table_name: wf_context
  query: active=true
  fields: name,state,started,ended,id,scratchpad
  limit: 50
  order_by: sys_created_on
  order_by_desc: true

检查工作流历史记录:

Tool: SN-Query-Table
Parameters:
  table_name: wf_history
  query: context.active=false^sys_created_onONLast 7 days@javascript:gs.daysAgo(7)@javascript:gs.nowDateTime()
  fields: activity,from_state,to_state,additional_info,sys_created_on
  limit: 100
  order_by: sys_created_on
  order_by_desc: true
Flow Designer 调试

查询流程执行记录:

Tool: SN-Query-Table
Parameters:
  table_name: sys_flow_context
  query: state!=complete^ORstate=error
  fields: name,state,started,ended,error_message
  limit: 50
  order_by: sys_created_on
  order_by_desc: true

启用流程调试模式:

  1. 在 Flow Designer 中打开流程
  2. 点击 更多操作(三个点)> 调试
  3. 触发流程
  4. 在 Debug 面板中查看执行情况

常见错误消息及解决方案

“表中未找到记录”

原因: GlideRecord 查询未返回任何结果
解决方案:

var gr = new GlideRecord('incident');
gr.addQuery('number', 'INC0000001');
gr.query();
if (gr.next()) {
    // Record found
} else {
    gs.warn('Record not found: INC0000001');
}
“用户未获授权”

原因: ACL 阻止访问
解决方案:

  1. 启用 Session Debug > Security
  2. 检查 ACL 日志:System Logs > Security
  3. 查询 ACL:
Tool: SN-Query-Table
Parameters:
  table_name: sys_security_acl
  query: name=incident
  fields: name,operation,condition,script,role
  limit: 100
“脚本无效”或“脚本错误”

原因: JavaScript 语法错误或运行时异常
解决方案:

  1. 在 System Logs 中检查堆栈跟踪
  2. 使用 Script Debugger 逐步调试
  3. 使用浏览器控制台验证语法
“超过最大执行时间”

原因: 脚本运行时间过长(30 秒以上)
解决方案:

  • 使用 GlideAggregate 进行计数,避免循环
  • 使用 setLimit() 限制结果集
  • 对于大型操作,改用 Scheduled Job
“违反互斥约束”

原因: 多个进程正在更新同一条记录
解决方案:

  • 检查是否存在递归业务规则
  • 添加条件以防止重复进入:
if (current.update_in_progress) return;
current.update_in_progress = true;
“超过嵌套调用限制”

原因: GlideRecord 操作嵌套过多或存在递归调用
解决方案:

  • 重构以减少嵌套深度
  • 使用 GlideAggregate 进行计数
  • 拆分为单独的事务

工具使用

MCP 工具(Claude Code/Desktop)
工具用途
SN-Query-Table查询 syslog、执行历史记录和脚本记录
SN-Execute-Background-Script在实例上运行诊断脚本
SN-Get-Record获取特定日志或脚本记录
REST API(ChatGPT/Other)
端点方法用途
/api/now/table/syslogGET查询系统日志
/api/now/table/sys_script_execution_historyGET查询脚本执行历史记录
/api/now/table/syslog_transactionGET查询事务日志
原生工具(Claude Code)
工具用途
Bash执行 curl 命令以调用 REST API
Read读取本地脚本文件以进行比较

最佳实践

  • 始终包含上下文: 记录函数名称、记录标识符和操作类型
  • 使用适当的日志级别: 开发时使用 Debug,生产环境追踪时使用 Info,遇到问题时使用 Error
  • 清理调试代码: 部署到生产环境前,移除或禁用详细日志记录
  • 使用条件日志记录: 将调试语句放在属性检查中
  • 结构化日志记录: 使用一致的格式:[Component] Action - Details
  • 在预生产环境中测试: 操作生产环境前,务必先在开发或测试环境中调试

故障排除

日志未显示

症状: gs.log/gs.info 语句未显示在 System Logs 中 原因: 日志级别已过滤或属性已禁用 解决方案:

  1. 检查 System Properties 中的 glide.log.level
  2. 确保 glide.script.log.level 允许相应的日志级别
  3. 使用始终会记录日志的 gs.error()
脚本调试器未触发

症状: 脚本执行时未触发断点 原因: 会话错误、脚本已缓存或条件未满足 解决方案:

  1. 确保为你自己的会话(而非其他管理员的会话)启用了调试
  2. 清除缓存:System Diagnostics > Cache Management > Flush Cache
  3. 验证脚本条件的结果为 true
业务规则未触发

症状: 业务规则已启用,但似乎未激活 原因: 条件未满足、表错误或筛选条件不匹配 解决方案:

Tool: SN-Query-Table
Parameters:
  table_name: sys_script
  query: name=YOUR_BUSINESS_RULE_NAME
  fields: name,active,collection,when,order,condition,filter_condition,script
  limit: 1

示例

示例 1:跟踪业务规则执行
// Add to business rule for debugging
(function executeRule(current, previous) {
    var startTime = new Date().getTime();
    var brName = 'Validate Incident Priority';

    gs.info('[' + brName + '] START - Record: ' + current.number);

    try {
        // Original business rule logic
        if (current.priority == 1 && !current.assignment_group) {
            gs.info('[' + brName + '] Setting mandatory assignment group');
            gs.addErrorMessage('Critical incidents require an assignment group');
            current.setAbortAction(true);
        }
    } catch (e) {
        gs.error('[' + brName + '] ERROR: ' + e.message + '\nStack: ' + e.stack);
    }

    var duration = new Date().getTime() - startTime;
    gs.info('[' + brName + '] END - Duration: ' + duration + 'ms');
})(current, previous);
示例 2:查询近期错误
Tool: SN-Query-Table
Parameters:
  table_name: syslog
  query: level=error^sys_created_onONLast 24 hours@javascript:gs.hoursAgo(24)@javascript:gs.nowDateTime()
  fields: sys_created_on,source,message
  limit: 100
  order_by: sys_created_on
  order_by_desc: true
示例 3:使用 GlideAjax 调试客户端脚本
// Client Script
function onLoad() {
    console.log('[MyClientScript] Form loaded, fetching data...');

    var ga = new GlideAjax('MyAjaxProcessor');
    ga.addParam('sysparm_name', 'getData');
    ga.addParam('sysparm_record_id', g_form.getUniqueValue());

    ga.getXMLAnswer(function(response) {
        console.log('[MyClientScript] Response received:', response);

        if (!response) {
            console.error('[MyClientScript] Empty response from server');
            return;
        }

        try {
            var data = JSON.parse(response);
            console.table(data);
        } catch (e) {
            console.error('[MyClientScript] Failed to parse response:', e);
        }
    });
}
示例 4:用于日志分析的后台脚本
Tool: SN-Execute-Background-Script
Parameters:
  script: |
    // Find all errors in last hour with stack traces
    var gr = new GlideRecord('syslog');
    gr.addQuery('level', 'error');
    gr.addQuery('sys_created_on', '>=', gs.hoursAgo(1));
    gr.orderByDesc('sys_created_on');
    gr.setLimit(20);
    gr.query();

    var results = [];
    while (gr.next()) {
        results.push({
            time: gr.sys_created_on.getDisplayValue(),
            source: gr.source.toString(),
            message: gr.message.toString().substring(0, 200)
        });
    }

    gs.info('=== Recent Errors ===\n' + JSON.stringify(results, null, 2));
  description: Analyze recent error logs

相关技能

  • development/script-includes - 编写可复用的服务器端脚本
  • development/business-rules - 业务规则开发与最佳实践
  • development/client-scripts - 客户端脚本技术
  • admin/script-execution - 系统日志配置与管理

参考资料

评论

支持 Markdown