ServiceNow
Debugging ServiceNow: Session Debug, Slow Queries, Transaction Logs, and Script Tracing
Where to look first
When something is broken — a Business Rule is not firing, a form is slow, a notification is not sending — there are specific logs and tools for each problem. Do not guess. Go to the data.
| Problem | Where to look | Navigation path |
|---|---|---|
| Script errors | System Logs > All | syslog_list.do |
| Slow forms/transactions | Transaction Log | syslog_transaction_list.do |
| Slow database queries | Slow Queries | sys_slow_query_list.do |
| Email not sending | Email Log | sys_email_list.do |
| Business Rule not firing | Session Debug > Business Rule | See below |
| ACL blocking access | Session Debug > Security | See below |
| Flow Designer errors | Flow Execution Details | Flow Designer > Executions |
| Integration failures | Outbound HTTP logs | sys_outbound_http_log_list.do |
Session Debug
Session Debug turns on detailed tracing for your current session. It does not affect other users. Enable it, reproduce the issue, then check the output in System Logs.
Enable via the System Diagnostics menu
// Navigate to: System Diagnostics > Session Debug > Enable All // Or enable specific modules: // Debug Business Rule — shows which BRs fire, in what order, execution time // Debug Security Rules — shows ACL evaluation for every field/table access // Debug SQL — shows the raw SQL generated by GlideRecord queries // Debug Log — shows all gs.log/info/warn/error output // After enabling, perform the action you want to debug (e.g., save an incident) // Then check: System Logs > All (filter by your session)
What Debug Business Rule shows you
// Example output in System Logs after saving an incident: // // === Business Rule: Set Priority (BEFORE, order 100) === // Table: incident // Condition: priority changes // Result: EXECUTED (4.2ms) // // === Business Rule: Auto-Assign (AFTER, order 200) === // Table: incident // Condition: assignment_group is empty // Result: SKIPPED (condition false) // // This tells you exactly which rules ran, which were skipped, and why.
What Debug Security shows you
// Example output when a user can't see a field: // // ACL: incident.caller_id (read) // Role required: itil — PASS // Condition: active=true — PASS // Script: answer = ... — FAIL // Result: DENIED // // Now you know exactly which ACL is blocking and which check failed.
System Logs
// Everything you write with gs.info, gs.warn, gs.error shows up here
// Filter by source to find your script's output:
gs.info('My debug output', 'MyScriptInclude');
// In the syslog table, filter:
// Source = MyScriptInclude
// Level = Info/Warning/Error
// Created > last 10 minutes
Transaction Log
Every HTTP request to the instance is logged with timing data. When a form is slow, find the transaction here.
// Navigate to: syslog_transaction_list.do // Key fields: // URL — which page/form/API was requested // Response time — total milliseconds // SQL count — number of database queries // Business Rule time — time spent in BRs // // Red flags: // Response time > 5000ms — slow transaction // SQL count > 100 — too many queries (N+1 problem likely) // Business Rule time > 2000ms — heavy BR logic
Slow Query Log
Queries that take longer than the threshold (default 500ms) are automatically logged here.
// Navigate to: sys_slow_query_list.do // Key fields: // Table — which table was queried // Execution time — how long the query took // Source — which script/BR triggered it // Query — the encoded query string // // Common causes: // Missing index on a filtered field // No setLimit() on a large table query // Dot-walking through multiple reference fields // GlideRecord loop inside another GlideRecord loop (N+1)
Email debugging
// When a notification does not send, check these in order: // 1. sys_email_list.do — is the email record created? What is its state? // States: ready, sent, send-failed, skipped // // 2. If state = skipped: // Check the notification's conditions and "Who will receive" config // Check if the user unsubscribed (notification_preference table) // // 3. If state = send-failed: // Check syslog for SMTP errors // // 4. In sub-production instances: // Check glide.email.test.user property — it redirects ALL email // to a single address. This is by design to prevent test emails // going to real users.
Script debugging without session debug
// Quick debugging pattern for Business Rules:
(function executeRule(current, previous) {
// Temporarily add targeted logging
gs.info('[BR:SetPriority] Fired on ' + current.number +
' | impact=' + current.getValue('impact') +
' | urgency=' + current.getValue('urgency') +
' | old_priority=' + (previous ? previous.getValue('priority') : 'N/A'));
// Your logic here...
gs.info('[BR:SetPriority] Result: priority set to ' + current.getValue('priority'));
})(current, previous);
// Find your logs: System Logs > All, filter Source CONTAINS SetPriority
Stats.do — Quick instance diagnostics
Navigate to your-instance.service-now.com/stats.do for a quick overview of instance health: memory usage, active transactions, semaphore counts, node status, and session counts. Useful during performance incidents when you need a fast read on whether the instance itself is under stress.
Common traps
- Session debug left on: Debug sessions generate large amounts of log data. Always disable after you are done. Leaving it on in production degrades performance.
- Logging sensitive data:
gs.infowrites to syslog which is visible to admins. Never log passwords, PII, or API keys. - Debug output not showing: If you enabled debug but see nothing, check that you are looking at the correct time window and that your script actually executed. Also verify you are on the correct node in a multi-node instance.
- Transaction log vs slow query: A slow transaction does not always mean a slow query. The time could be in Business Rule execution, external REST calls, or Flow Designer actions. Check the breakdown columns.