Business Rules
Audit Trail and Change Logging
Create detailed audit trail records when sensitive fields are modified, maintaining compliance and tracking changes.
(function executeRule(current, previous /*null when async*/) {
// Configuration: Define fields to audit
var auditedFields = [
'priority',
'state',
'assignment_group',
'assigned_to',
'close_code',
'resolved_by'
];
// Configuration: Define critical tables that require full auditing
var criticalTables = ['incident', 'change_request', 'problem'];
// Check if any audited fields changed
var changedFields = [];
auditedFields.forEach(function(fieldName) {
if (current[fieldName].changes()) {
changedFields.push(fieldName);
}
});
// Only proceed if there are changes to audit
if (changedFields.length === 0) {
return;
}
// Create audit records for each changed field
changedFields.forEach(function(fieldName) {
var grAudit = new GlideRecord('u_audit_trail'); // Create this table for audit logging
grAudit.initialize();
// Record metadata
grAudit.u_table_name = current.getTableName();
grAudit.u_record_id = current.sys_id.toString();
grAudit.u_record_number = current.number.toString();
grAudit.u_field_name = fieldName;
// Get field label
var fieldLabel = current.getElement(fieldName).getLabel();
grAudit.u_field_label = fieldLabel;
// Record old and new values
var oldValue = previous ? previous.getValue(fieldName) : '';
var newValue = current.getValue(fieldName);
grAudit.u_old_value = oldValue;
grAudit.u_new_value = newValue;
// Get display values for reference fields
if (current.getElement(fieldName).getED().isReference()) {
grAudit.u_old_display_value = previous ? previous[fieldName].getDisplayValue() : '';
grAudit.u_new_display_value = current[fieldName].getDisplayValue();
}
// Record who made the change
grAudit.u_changed_by = gs.getUserID();
grAudit.u_changed_at = new GlideDateTime();
// Record IP address and session info
grAudit.u_ip_address = gs.getSession().getClientIP();
grAudit.u_session_id = gs.getSession().getSessionToken();
// Categorize the change type
if (fieldName === 'state') {
grAudit.u_change_type = 'Status Change';
} else if (fieldName === 'assignment_group' || fieldName === 'assigned_to') {
grAudit.u_change_type = 'Assignment Change';
} else if (fieldName === 'priority') {
grAudit.u_change_type = 'Priority Change';
} else {
grAudit.u_change_type = 'Field Update';
}
// Add business context
grAudit.u_reason = current.work_notes.toString() || 'No reason provided';
// Insert audit record
var auditId = grAudit.insert();
if (auditId) {
gs.info('Audit trail created for ' + current.number + ', field: ' + fieldLabel +
', changed by: ' + gs.getUserName());
}
});
// Optional: Send alert for critical changes
if (changedFields.indexOf('priority') !== -1) {
var oldPriority = previous ? previous.priority.toString() : '';
var newPriority = current.priority.toString();
// Alert if priority increased to Critical
if (newPriority === '1' && oldPriority !== '1') {
gs.eventQueue('audit.critical_priority_change', current, gs.getUserID(), current.sys_id);
gs.warn('AUDIT: Priority changed to Critical for ' + current.number +
' by ' + gs.getUserName());
}
}
// Optional: Add audit summary to work notes
var auditSummary = 'AUDIT: Fields changed - ' + changedFields.join(', ') +
' | Changed by: ' + gs.getUserName() +
' | Time: ' + new GlideDateTime().getDisplayValue();
current.comments = auditSummary;
})(current, previous);How to use it
1. Create a custom table u_audit_trail with fields: u_table_name, u_record_id, u_record_number, u_field_name, u_field_label, u_old_value, u_new_value, u_old_display_value, u_new_display_value, u_changed_by, u_changed_at, u_ip_address, u_session_id, u_change_type, u_reason 2. Create an after Business Rule on tables you want to audit 3. Check "Update" checkbox only 4. Customize auditedFields array for your requirements 5. Consider data retention policies for audit records 6. Test thoroughly to ensure no performance impact
Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.