Service offerings,commitments, outages and availaibility

Ruth_Porter
Kilo Explorer

Hi there,
We have been looking at the ServicePortfolio management plugin with a view to getting availability reports for service offerings using outage records set up on incidents and have some question.
1. It sesm that availability is calculated using outgaes linked to the service offering; can you roll up outgaes form individual cIS to the relevant service offering:
2. Do the entries shown by the module called Availability happen in real time? By that I mean if you add an outage record for a Service Offering should the releavnt entries here reflect it immediately or is doen periodically?
3. Can anyone explain how all these elements fit together?
Thanks in advance for any help, Ruth

25 REPLIES 25

CapaJC
ServiceNow Employee
ServiceNow Employee

For the original questions, looking at the scripts involved:

1) is no - Availability is coded against Service Offerings with no rollup, currently.

2) is yes - When an outage is created/modified against a Service Offering, a business rule on the Outage table calls a script include to recalculate the relevant "Last 30 days", "Last 7 days", and "Last 12 months" Availability records used to render the Homepage widget for that Service Offering.

Sounds like you only need to contact customer support if you've messed with the "Process SLAs" Business Rule, since the plugin modifies it. You'll need the modified version and not your customized version.


Ruth_Porter
Kilo Explorer

Thanks James - though not the answer I was hoping for on question 1 😉


williamsun
Mega Guru

abridged answer.
the SLA commitment is the only one that calculates achieved percentage, the availability gauge is fed off the outage table only.
to make the out of the box gauge work, you need to put the service offering directly into the CI field of your incident (not very useful).
I did a re-write of the coding for it to feed off of the affected services, but it needs to consider a refresh of impacted services (like in the Change form) and you need to deactivate the old scheduled job "Calculate SLA Results" and schedule this new one that basically does the same as the original does in three recursive scripts, but instead of just considering the CI in the incident field, it looks for all incidents that impact the service:

Name: Calculate SLA Results (homebrew)
Schedule: I run it daily at 3:00 am
Script:



mySLAResultsCalculator('daily', gs.beginningOfYesterday(), gs.endOfYesterday());
mySLAResultsCalculator('last7days', gs.beginningOfDay(gs.daysAgo(7)), gs.endOfYesterday());
mySLAResultsCalculator('last30days', gs.beginningOfDay(gs.daysAgo(30)), gs.endOfYesterday());
mySLAResultsCalculator('last12months', gs.beginningOfDay(gs.yearsAgo(1)), gs.endOfYesterday());
if(gs.isFirstDayOfWeek()) mySLAResultsCalculator('weekly', gs.beginningOfLastWeek(), gs.endOfLastWeek());
if(gs.isFirstDayOfMonth()) mySLAResultsCalculator('monthly', gs.beginningOfLastMonth(), gs.endOfLastMonth());
if(gs.isFirstDayOfYear()) mySLAResultsCalculator('annually', gs.beginningOfLastYear(), gs.endOfLastYear());

function mySLAResultsCalculator(type, start, end) {
gs.print('SLA Result type: ' + type);
gs.print('Start date: ' + start);
gs.print('End date : ' + end);

var sladelete = new GlideRecord('service_sla_result');
if (type != 'last7days' && type != 'last30days' && type != 'last12months') sladelete.addQuery('start', start);
sladelete.addQuery('type', type);
sladelete.query();
while(sladelete.next()) sladelete.deleteRecord();

var commits = new GlideRecord('service_offering_commitment');
commits.addQuery('service_commitment.type', 'sla');
commits.query();

while (commits.next()){
gs.print('DUPLA: ' + commits.service_offering.name + ' - ' + commits.service_commitment.name);
var item = new GlideRecord('u_manual_sla_results');
item.addQuery('task_sla_end_time', '>=', start);
item.addQuery('task_sla_end_time', '<=', end);
item.addQuery('soc_service_commitment', commits.service_commitment);
item.addQuery('soc_service_offering', commits.service_offering);
item.query();
var totalTasks = 0;
var total_dur = 0;
var total_bdur = 0;
var breached = 0;
var achieved = 0;
while (item.next()){
var dur = myGetDuration(item.task_sla_duration);
var bdur = myGetDuration(item.task_sla_business_duration);
total_dur = total_dur + dur.getNumericValue();
total_bdur = total_bdur + bdur.getNumericValue();
gs.print(item.task_sla_task.number + ': ' + item.task_sla_stage);
if (item.task_sla_stage == "breached")
breached += 1;
if (item.task_sla_stage == "achieved")
achieved += 1;
}
totalTasks += breached + achieved
var meanDuration = 0;
var meanBusinessDuration = 0;
var achievedPct = 100;
var totalDuration = myGetDuration(total_dur);
var totalBusinessDuration = myGetDuration(total_bdur);
if (totalTasks > 0) {
meanDuration = total_dur / totalTasks;
meanBusinessDuration = total_bdur / totalTasks;
achievedPct = (achieved / totalTasks) * 100
}

var met = achievedPct >= commits.service_commitment.sla_percent;
gs.print('Achieved: ' + achieved);
gs.print('Breached: ' + breached);
gs.print('Total : ' + totalTasks);
gs.print('Total Duration : ' + totalDuration);
gs.print('Avg. Duration : ' + meanDuration);
gs.print('Total B. Duration: ' + totalBusinessDuration);
gs.print('Avg. B. Duration : ' + meanBusinessDuration);
gs.print('Commited %: ' + commits.service_commitment.sla_percent);
gs.print('Achieved %: ' + achievedPct);
gs.print('Commitment met?: ' + met);
var gr = new GlideRecord('service_sla_result');
gr.setValue('service_offering', commits.service_offering);
gr.setValue('service_commitment', commits.service_commitment);
gr.setValue('start', start);
gr.setValue('end', end);
gr.setValue('met_commitment', met);
gr.setValue('absolute_mean', myGetDuration(meanDuration));
gr.setValue('absolute_duration', totalDuration);
gr.setValue('absolute_percentage', achievedPct);
gr.setValue('sla_percentage', commits.service_commitment.sla_percent);
gr.setValue('business_mean', myGetDuration(meanBusinessDuration));
gr.setValue('business_duration', totalBusinessDuration);
gr.setValue('achieved', achieved);
gr.setValue('breached', breached);
gr.setValue('absolute_count', totalTasks);
gr.setValue('type', type)
gr.insert();
}
}

function myGetDuration(s){
var answer = new GlideDuration();
answer.setValue(s);
return answer;
}


Does any one know if the later releases..i.e - Dublin... has provided any additional functionality for this? I looked at the release notes but did not see anything specific.


Hi William,



I see you make use of a custom table "u_manual_sla_results"


Does this table only have the following fields?


task_sla_end_time


soc_service_commitment


soc_service_offering



I've been trying to work over the same problem with our SLA data, as Ruth's issue #1.



Thanks,


Stephen