incident-management

安装量: 52
排名: #14246

安装

npx skills add https://github.com/groeimetai/snow-flow --skill incident-management

Incident Management restores normal service operation as quickly as possible while minimizing business impact.

Incident Lifecycle

New (1)
    ↓
In Progress (2)
    ↓ ← On Hold (3)
Resolved (6)
    ↓
Closed (7)

Cancelled (8) ← Can occur from New/In Progress

Key Tables

| incident | Incident records

| incident_task | Sub-tasks for incidents

| incident_alert | Related alerts

| problem | Related problems

Creating Incidents (ES5)

Basic Incident Creation

// Create incident (ES5 ONLY!)
var incident = new GlideRecord('incident');
incident.initialize();

// Required fields
incident.setValue('caller_id', callerSysId);
incident.setValue('short_description', 'Email not working');
incident.setValue('description', 'User cannot send or receive emails since this morning');

// Classification
incident.setValue('category', 'software');
incident.setValue('subcategory', 'email');
incident.setValue('impact', 2);
incident.setValue('urgency', 2);
// Priority is calculated automatically from impact/urgency

// Assignment
incident.setValue('assignment_group', getGroupSysId('Email Support'));

// Optional: affected CI
incident.setValue('cmdb_ci', emailServerSysId);

var incidentSysId = incident.insert();
gs.info('Created incident: ' + incident.getValue('number'));

Priority Matrix

// Priority calculation (ES5 ONLY!)
// Priority = Impact x Urgency matrix
var priorityMatrix = {
    '1-1': 1,  // High Impact + High Urgency = Critical
    '1-2': 2,  // High Impact + Medium Urgency = High
    '1-3': 3,  // High Impact + Low Urgency = Moderate
    '2-1': 2,  // Medium Impact + High Urgency = High
    '2-2': 3,  // Medium Impact + Medium Urgency = Moderate
    '2-3': 4,  // Medium Impact + Low Urgency = Low
    '3-1': 3,  // Low Impact + High Urgency = Moderate
    '3-2': 4,  // Low Impact + Medium Urgency = Low
    '3-3': 5   // Low Impact + Low Urgency = Planning
};

function calculatePriority(impact, urgency) {
    var key = impact + '-' + urgency;
    return priorityMatrix[key] || 4;
}

Incident Assignment (ES5)

Auto-Assignment Rules

// Assignment rule script (ES5 ONLY!)
// Business Rule: before, insert, incident

(function executeRule(current, previous) {
    // Skip if already assigned
    if (current.assignment_group) {
        return;
    }

    var group = determineAssignmentGroup(current);
    if (group) {
        current.assignment_group = group;

        // Optionally assign to on-call
        var onCallUser = getOnCallUser(group);
        if (onCallUser) {
            current.assigned_to = onCallUser;
        }
    }
})(current, previous);

function determineAssignmentGroup(incident) {
    var category = incident.getValue('category');
    var subcategory = incident.getValue('subcategory');

    // Category-based assignment
    var mapping = {
        'network': 'Network Support',
        'hardware': 'Desktop Support',
        'software-email': 'Email Support',
        'software-erp': 'ERP Support',
        'database': 'Database Admins'
    };

    var key = category;
    if (subcategory) {
        key = category + '-' + subcategory;
    }

    var groupName = mapping[key] || mapping[category] || 'Service Desk';

    var group = new GlideRecord('sys_user_group');
    if (group.get('name', groupName)) {
        return group.getUniqueValue();
    }

    return null;
}

Reassignment with Tracking

// Track reassignments (ES5 ONLY!)
// Business Rule: before, update, incident

(function executeRule(current, previous) {
    // Check if assignment group changed
    if (current.assignment_group.changes()) {
        // Increment reassignment count
        var count = parseInt(current.getValue('reassignment_count'), 10) || 0;
        current.reassignment_count = count + 1;

        // Add work note
        current.work_notes = 'Reassigned from ' +
            previous.assignment_group.getDisplayValue() +
            ' to ' + current.assignment_group.getDisplayValue();

        // Alert if excessive reassignments
        if (count >= 3) {
            gs.eventQueue('incident.excessive.reassignments', current, count.toString(), '');
        }
    }
})(current, previous);

Major Incident Management (ES5)

Declare Major Incident

// Declare major incident (ES5 ONLY!)
function declareMajorIncident(incidentSysId, reason) {
    var incident = new GlideRecord('incident');
    if (!incident.get(incidentSysId)) {
        return false;
    }

    // Set major incident flag
    incident.setValue('major_incident_state', 'confirmed');
    incident.setValue('priority', 1);

    // Set major incident fields
    incident.setValue('u_major_incident_start', new GlideDateTime());
    incident.setValue('u_major_incident_reason', reason);

    // Assign to Major Incident team
    var miTeam = new GlideRecord('sys_user_group');
    if (miTeam.get('name', 'Major Incident Team')) {
        incident.setValue('assignment_group', miTeam.getUniqueValue());
    }

    // Add work note
    incident.work_notes = 'MAJOR INCIDENT DECLARED\nReason: ' + reason;

    incident.update();

    // Trigger notifications
    gs.eventQueue('incident.major.declared', incident, '', '');

    // Create bridge call record
    createBridgeCall(incident);

    return true;
}

function createBridgeCall(incident) {
    var bridge = new GlideRecord('u_bridge_call');
    bridge.initialize();
    bridge.setValue('u_incident', incident.getUniqueValue());
    bridge.setValue('u_dial_in', '1-800-555-0123');
    bridge.setValue('u_pin', generatePin());
    bridge.setValue('u_start_time', new GlideDateTime());
    bridge.insert();
}

Major Incident Communication

// Send major incident update (ES5 ONLY!)
function sendMajorIncidentUpdate(incidentSysId, updateText, recipientGroups) {
    var incident = new GlideRecord('incident');
    if (!incident.get(incidentSysId)) {
        return;
    }

    // Add to work notes
    incident.work_notes = 'MAJOR INCIDENT UPDATE:\n' + updateText;
    incident.update();

    // Build recipient list
    var recipients = [];
    for (var i = 0; i < recipientGroups.length; i++) {
        var members = getGroupMembers(recipientGroups[i]);
        recipients = recipients.concat(members);
    }

    // Send notification
    var eventParams = JSON.stringify({
        update: updateText,
        recipients: recipients
    });
    gs.eventQueue('incident.major.update', incident, eventParams, '');
}

Incident Escalation (ES5)

Time-Based Escalation

// Escalation script for scheduled job (ES5 ONLY!)
(function executeScheduledJob() {
    var LOG_PREFIX = '[IncidentEscalation] ';

    // Find incidents needing escalation
    var now = new GlideDateTime();

    // P1 not acknowledged in 15 minutes
    escalateUnacknowledged('1', 15);

    // P2 not acknowledged in 30 minutes
    escalateUnacknowledged('2', 30);

    // P1 not resolved in 4 hours
    escalateUnresolved('1', 240);

    // P2 not resolved in 8 hours
    escalateUnresolved('2', 480);

    function escalateUnacknowledged(priority, minutes) {
        var threshold = new GlideDateTime();
        threshold.addSeconds(-minutes * 60);

        var gr = new GlideRecord('incident');
        gr.addQuery('priority', priority);
        gr.addQuery('state', 1);  // New
        gr.addQuery('sys_created_on', '<', threshold);
        gr.addNullQuery('assigned_to');
        gr.query();

        while (gr.next()) {
            gs.info(LOG_PREFIX + 'Escalating unacknowledged P' + priority + ': ' + gr.number);
            gr.escalation = 1;
            gr.work_notes = 'Auto-escalated: Not acknowledged within ' + minutes + ' minutes';
            gr.update();
            gs.eventQueue('incident.escalation.unacknowledged', gr, priority, '');
        }
    }

    function escalateUnresolved(priority, minutes) {
        var threshold = new GlideDateTime();
        threshold.addSeconds(-minutes * 60);

        var gr = new GlideRecord('incident');
        gr.addQuery('priority', priority);
        gr.addQuery('state', 'IN', '1,2');  // New or In Progress
        gr.addQuery('sys_created_on', '<', threshold);
        gr.query();

        while (gr.next()) {
            var currentEsc = parseInt(gr.getValue('escalation'), 10) || 0;
            if (currentEsc < 3) {
                gr.escalation = currentEsc + 1;
                gr.work_notes = 'Auto-escalated: Not resolved within target time';
                gr.update();
                notifyNextLevel(gr);
            }
        }
    }

    function notifyNextLevel(incident) {
        var group = incident.assignment_group.getRefRecord();
        if (group.manager) {
            gs.eventQueue('incident.escalation.manager', incident, group.manager, '');
        }
    }
})();

Incident Resolution (ES5)

Resolve Incident

// Resolve incident with validation (ES5 ONLY!)
function resolveIncident(incidentSysId, resolution) {
    var incident = new GlideRecord('incident');
    if (!incident.get(incidentSysId)) {
        return { success: false, message: 'Incident not found' };
    }

    // Validate state transition
    var currentState = incident.getValue('state');
    if (currentState === '6' || currentState === '7') {
        return { success: false, message: 'Incident already resolved/closed' };
    }

    // Validate resolution fields
    if (!resolution.code) {
        return { success: false, message: 'Resolution code is required' };
    }
    if (!resolution.notes) {
        return { success: false, message: 'Resolution notes are required' };
    }

    // Update incident
    incident.setValue('state', 6);  // Resolved
    incident.setValue('resolution_code', resolution.code);
    incident.setValue('close_notes', resolution.notes);
    incident.setValue('resolved_at', new GlideDateTime());
    incident.setValue('resolved_by', gs.getUserID());

    // Link to problem/known error if provided
    if (resolution.problem) {
        incident.setValue('problem_id', resolution.problem);
    }
    if (resolution.knowledge) {
        incident.setValue('u_resolution_article', resolution.knowledge);
    }

    incident.update();

    // Notify caller
    gs.eventQueue('incident.resolved', incident, '', '');

    return {
        success: true,
        message: 'Incident resolved',
        number: incident.getValue('number')
    };
}

Incident Metrics (ES5)

Calculate MTTR

// Calculate Mean Time to Resolve (ES5 ONLY!)
function calculateMTTR(startDate, endDate, filters) {
    var ga = new GlideAggregate('incident');
    ga.addQuery('resolved_at', '>=', startDate);
    ga.addQuery('resolved_at', '<=', endDate);
    ga.addQuery('state', 'IN', '6,7');

    // Apply optional filters
    if (filters.priority) {
        ga.addQuery('priority', filters.priority);
    }
    if (filters.category) {
        ga.addQuery('category', filters.category);
    }

    ga.addAggregate('AVG', 'calendar_duration');
    ga.addAggregate('COUNT');
    ga.query();

    if (ga.next()) {
        var avgDuration = ga.getAggregate('AVG', 'calendar_duration');
        var count = ga.getAggregate('COUNT');

        // Convert to hours
        var durationObj = new GlideDuration(avgDuration);
        var hours = durationObj.getNumericValue() / 3600000;

        return {
            mttr_hours: Math.round(hours * 100) / 100,
            incident_count: parseInt(count, 10)
        };
    }

    return { mttr_hours: 0, incident_count: 0 };
}

MCP Tool Integration

Available Tools

| snow_query_incidents | Query incident records

| snow_query_table | Advanced incident queries

| snow_execute_script_with_output | Test incident scripts

| snow_create_business_rule | Create incident automation

Example Workflow

// 1. Query open P1 incidents
await snow_query_incidents({
    query: 'priority=1^active=true',
    fields: 'number,short_description,assigned_to,opened_at'
});

// 2. Check incident metrics
await snow_execute_script_with_output({
    script: `
        var stats = calculateMTTR(gs.beginningOfThisMonth(), gs.endOfThisMonth(), {});
        gs.info('MTTR: ' + stats.mttr_hours + ' hours');
    `
});

// 3. Find unassigned incidents
await snow_query_table({
    table: 'incident',
    query: 'active=true^assigned_toISEMPTY',
    fields: 'number,short_description,priority,assignment_group'
});

Best Practices

  • Clear Classification - Proper category/subcategory

  • Impact Assessment - Accurate impact/urgency

  • Assignment Rules - Automated routing

  • Escalation Paths - Defined procedures

  • Communication - Regular updates

  • Resolution Codes - Consistent categorization

  • Knowledge Linking - Link to KB articles

  • ES5 Only - No modern JavaScript syntax

返回排行榜