- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 05-19-2021 01:01 AM
Our Service Desk is the frontline of our IT support operation. Customers contact them, they solve the Incidents they can at the point of contact, and they route the rest to other internal teams. Sometimes, though, those internal teams reassign their own Incidents to the Service Desk, which subverts the intended flow and places an undue burden on the Service Desk (who already experience by far the highest volume of Incidents in the organization). To help tackle this problem, we wanted to be able to:
- See which internal teams were reassigning their Incidents to the Service Desk
- Rank those teams by the volume of their reassignments
- Drill-Down to examine individual Incidents in order to better understand why they were reassigned
ServiceNow comes out-of-the-box with the Assignment Group platform metric, which tracks every change to every Incident's Assignment Group field, but - on its own - it can't tell you anything about the sequence of those assignments (like which group previously occupied the Assignment Group field). We could have designed a new platform metric to capture precisely that, but we'd already collected years of data with the Assignment Group metric, so we really wanted to leverage that. We did, through the use of Performance Analytics, and the steps below describe how.
This solution relies on:
All of which come out-of-the-box with ServiceNow. |
1 | Login to ServiceNow as a user with the pa_admin role. | |
2 |
Click Scripts inside Automation under Performance Analytics. Click New beside Scripts. Set Name to Previous Assignment Group in Incident Assignment Group Metric, Description to Return the sys_id of the previous assignment group for the supplied (current) Incident. Only use with breakdowns based on the Incident Assignment Group metric (incident_metric table with definition = 'Assignment Group')., Facts table to Incident Metric [incident_metric], Fields to Definition, ID, Value, and Start, Script to:
Click Submit. | |
3 |
Click Automated Breakdowns inside Breakdowns under Performance Analytics. Click New beside Breakdowns [Automated View]. Set Name to Previous Assignment Group and Description to A breakdown, specifically for use with the Assignment Group metric, that uses a scripted mapping to determine which group was assigned to the Document ID (Incident) prior to the currently assigned group. On the Automated tab, set Breakdown Source to Groups (sys_id=76407c23d7030100b96d45a3ce61034, in case there's more than one with the same name). Click Submit.
| |
4 | After the Previous Assignment Group breakdown page reloads, click New on the Breakdown Mappings tab. Set the Facts Table to Incident Metric [incident_metric], Scripted to true, and Script to Previous Assignment Group in Incident Assignment Group Metric. Click Submit. | |
5 |
Click Indicator Sources inside Sources under Performance Analytics. Click New beside Indicator Sources. Set Name to Incident.Assignments.to.Service.Desk, Description to A source that returns the number of times Incidents were assigned to the Service Desk., Valid for frequency to Daily (or any other frequency you want), Facts Table to Incident Metric [incident_metric], Conditions to Definition is Assignment Group AND Value is Service Desk AND Start on Today. Click Submit.
| |
6 |
Click Automated Indicators inside Indicators under Performance Analytics. Click New beside Indicators [Automated View]. Set Name to # Incident Assignments to Service Desk, Description to The number of times Incidents were assigned to the Service Desk. , Frequency to Daily (or the frequency you chose in the previous step), Direction to None, Unit to #, and Precision to 0. On the Source tab, set Indicator Source to Incident.Assignments.to.Service.Desk, Collect records to true, Aggregate to Count, and Value when Nil to 0. On the Access Control tab, set Publish on Analytics Hub to true. On the Other tab, set Render Continuous Lines to true. Click Submit. After the page reloads, click Edit on the Breakdown tab, add Previous Assignment Group to the Breakdowns List, and click Save. | |
7 |
Click Elements Filters inside Breakdowns under Performance Analytics, then click New. Set Title to All Groups Except 'Unassigned', Breakdown Source to Groups, Facts Table to Group [sys_user_group], and Filter to Name is not Unassigned. Click Submit. | |
8 | Under Performance Analytics > Jobs, schedule a regular job to collect data for the # Incident Assignments to Service Desk indicator going forward at the frequency you want. Execute an ad-hoc job to collect historical records. | |
9 | To display the data, create a widget (Performance Analytics > Widgets) based on the # Incident Assignments to Service Desk indicator and then place that widget on a dashboard. |
The end result, used in a workbench widget, will look like this...
The total number you see is at the top is a count of all Incident assignments to the Service Desk, including times when the Service Desk is the very first assignment (with no prior assignment group routing it to the Service Desk). Using the Previous Assignment Group breakdown, though, you can see the volume for each assignment group that routed Incidents to the Service Desk. You'll also see an 'Unassigned' category in that breakdown, and that's counting every instance of an Incident being first-assigned to the Service Desk (Incidents that weren't assigned to any other group prior to being assigned to the Service Desk). If you want to ignore the Unassigned category, choose All Groups Except 'Unassigned' from the Select a Filter drop-down.
But what if I only want to see reassignments?
If you don't want the 'unassigned' value to be included in the overall score or the breakdown, we can take this a step further with a formula indicator...
10 |
Click Formula Indicators inside Indicators under Performance Analytics. Click New beside Indicators [Formula View]. Set Name to # Incident Reassignments to Service Desk, Description to The number of times Incidents were reassigned to the Service Desk after being previously assigned to other groups., Direction to Minimize, Unit to #, and Precision to 0. In the Formula field, add:
On the Access Control tab, set Publish on Analytics Hub to true. On the Other tab, set Render Continuous Lines to true. Click Submit. After the page reloads, click Edit on the Breakdown tab, add Previous Assignment Group to the Breakdowns List, and click Save. |
The end result, used in a workbench widget, will look like this...
How about the percentage of reassignments?
Now that we have Indicators counting both reassignments and overall assignments, we can define another formula indicator to divide one by the other...
11 |
Click Formula Indicators inside Indicators under Performance Analytics. Click New beside Indicators [Formula View]. Set Name to % Incident Reassignments to Service Desk, Description to The number of times Incidents were reassigned to the Service Desk (after being previously assigned to other groups) divided by the overall number of times Incidents were assigned to the Service Desk., Direction to Minimize, Unit to %, and Precision to 1. In the Formula field, add:
On the Access Control tab, set Publish on Analytics Hub to true. On the Other tab, set Render Continuous Lines to true. Click Submit. After the page reloads, click Edit on the Breakdown tab, add Previous Assignment Group to the Breakdowns List, and click Save. |
The end result, used in a workbench widget, will look like this...
- 11,885 Views

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
This is what I needed. Thanks for sharing.
However, can this is done without PA on a plain GUI?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi, Karun! Great question!
If I couldn't (or didn't want to) use PA to measure this, I think I'd try to tackle the problem by creating a Script Include javascript function. In that function, I would...
- Query the metric_instance table for records where Definition [definition] = 'Assignment Group' and Value [value] = 'Service Desk' (or your preferred assignment group). That gives you all the instances where Incidents were assigned to the Service Desk.
- In a loop, for each one of those instances, I'd query the metric_instance table again. This time I'd look for records where Definition [definition] = 'Assignment Group', Document ID [id] = the id of the instance I'm looping through,Start [start] is less than the start field of the instance I'm looping through, and Value [value] is not equal to 'Service Desk'. That gives you the full set of assignments for that particular Incident, until just before the Incident is assigned to the Service Desk, and it also excludes all earlier reassignments to the Service Desk to reduce the data we need to process. As part of the query, I'd also sort the results in descending order so that the very first one becomes the assignment that happened right before the Service Desk received the Incident.
- I'd then take the sys_id from the most recent of those result and store it in an array. As the loop continues, that array would contain all the sys_ids of all the metric_instance records for the assignments that happened just prior to the Service Desk receiving those Incidents.
Here's what that would look like in javascript...
function getPreviousGroupAssignment(groupName) {
var returnMe = [];
var assignments = new GlideRecord('metric_instance');
assignments.addQuery('definition','39d43745c0a808ae0062603b77018b90');
assignments.addQuery('value',groupName);
assignments.query();
while(assignments.next()) {
var reassignments = new GlideRecord('metric_instance');
reassignments.addQuery('definition','39d43745c0a808ae0062603b77018b90');
reassignments.addQuery('id',assignments.id);
reassignments.addQuery('start','<',assignments.start);
reassignments.addQuery('value','!=',groupName);
reassignments.orderByDesc('start');
reassignments.query();
reassignments.next();
returnMe.push(reassignments.sys_id.toString());
}
return returnMe
}
Note that, instead of hardcoding 'Service Desk' into the script, I provided a 'groupName' variable that can be set to any group when the function is called.
Once the Script Include is created, I can then create a report on the Incident Metric [incident_metric] (or Metric [metric_instance]) table that has at least two filters...
- Definition is Assignment Group
- Sys ID (mi_sys_id) is javascript:getPreviousGroupAssignment("Service Desk");
The getPreviousGroupAssignment("Service Desk") function would then return a list of sys_ids for all the metric instances just prior to Service Desk reassignment, so the report would show you that list, and you could group by 'Value' to see exactly which groups were reassigning and at what volume.
Warning: I do think there's a problem with this approach because the first query in the script is essentially unbound. It will look for all Assignment Group metric instances with a Value of 'Service Desk', and that could result in hundreds of thousands of records or more. To improve the performance, you might want to add a way to include a date range (the start field between two dates). Performance Analytics doesn't have this problem because its data collection process always happens in a strict window of time (today, this week, this month, etc).
If anyone is reading this who has a better way to approach the solution without Performance Analytics, please feel free to chime in!
-Gray
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Oh! I just thought of another way to approach this, though I think it's a bit less elegant because it doesn't rely on existing data from the built-in Assignment Group metric. You could create a new scripted Platform Metric that watches for the Assignment Group field to change on Incidents and, in addition to recording the name of the new assignment group in the Value field, you could also record the name of the previous assignment group. Like "prevgrp:Service Analysis,newgrp:Service Desk". With the data formatted like that, you could then run a report that filters for records with Value contains newgrp:Service Desk. It would take some javascript development, but the end result would be much faster to use than the Script Include solution I described earlier.

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I'll check the first method before I go for Platform metric and update here.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @graycarper thanks for this.I have a requirement where i need to capture the duration for which an assignment groups keeps the ticket "Unassigned" to an individual . In other words , how long before a particular assignment group starts acting on a ticket. Could you share any suggestions.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
I'd approach this by using a Platform Metric. This is a little more complicated than the average Platform Metric, though, because you want to watch for two different changes (the first time the Assignment Group is set, then the first time the Assigned To field is set) and act differently in each case. Normally Platform Metrics can only watch for one change, but we can get around that limitation by combining a Platform Metric with a Business Rule. Here's how I'd do that for your scenario...
1 |
Click Definitions under Metrics in the left-navigation bar and then click New beside Metric Definitions. Set Name to Task Assignment Group Duration to First Assignee, Table to Task [task], Field to Assignment Group, Type to Script Calculation, and Description to The duration between the time the the Assignment Group field is first set and the subsequent time the Assigned To field is set. This script is empty because a business rule does the heavy lifting. Open the Additional Actions hamburger menu, click Save. |
2 |
When the definition reloads after saving, open the Additional Actions hamburger menu again, then click Copy sys_id - sca (or just copy the sys_id from the Metric Definition's URL). You'll need the sys_id for your new metric definition (something like 'b6128710db001300f653f34ebf96190d') in the next step. |
3 |
Click Business Rules under System Definition in the left-navigation bar. Click New beside Business Rules. Set Name to Task Assignment Group Duration to First Assignee Metric, Table to Task [task], and Advanced to true. On the When to Run tab, set When to after, Insert to true, and Update to true. Add a filter condition for Assigned To changes OR Assignment Group changes. On the Advanced tab, set Script to:
At the top of the script, change the metricSysID variable to match the sys_id you copied in the previous step. Click Submit. |
I haven't actually tested this solution, though, so you'll need to do that testing and make sure the results make sense. If I made any mistakes in my script, you'll need to find and fix them (sorry!).
I should also mention that you don't need to focus this metric on the Task table if you don't want to. If you only need to measure this for Incidents, for example, it would be better to use the Incident table instead of the Task table.
If you have any questions, just let me know.
-Gray
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Getting error at stage 10 Formula Indicators. Anything missing? Do you have any alternative for stage 10?
var res = [[# Incident Assignments to Service Desk]]- [[# Incident Assignments to Service Desk > Previous Assignment Group = Unassigned]];
scores.if(pa.getCurrentBreakdownID() == '6f31277f1bc470108b020e93cc4bcb7d' // used breakdown Sys id
&& pa.getCurrentElementID() != 'unmatched') { res = [[# Incident Assignments to Service Desk]]; }
res;
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
This is a great question, and I do believe we can accomplish what you're asking for by adding another Breakdown to the same Indicator: Next Assignment Group. First, you'd need to make a new script that's similar to the one in step 2. Something like...
var nextAssignmentGroup = function(){
var returnMe = null;
// Query metric_instance for rows that have the same Document ID and
// Definition. Only look for the next most recent row that
// doesn't have the same value (Assignment Group name).
var assignments = new GlideRecord('metric_instance');
assignments.addQuery('definition',current.mi_definition);
assignments.addQuery('id',current.mi_id);
assignments.addQuery('value','!=',current.mi_value);
assignments.addQuery('start','>',current.mi_start);
assignments.orderBy('start');
assignments.setLimit(1);
assignments.query();
while(assignments.next()) {
// If we found a next assignment group,
// look up its sys_id and return that.
if(assignments.value != null){
var groups = new GlideRecord('sys_user_group');
groups.addQuery('name',assignments.value);
groups.query();
while(groups.next()) {
returnMe = groups.sys_id;
}
}
}
return returnMe;
};
nextAssignmentGroup();
This gives us the sys_id of the Assignment Group that the Incident was assigned to after the Service Desk.
You'll then need to repeat steps 3 and 4, but this time create a Next Assignment Group automated breakdown that maps to the script above.
Finally, you'll need to edit your Indicator, add the new Next Assignment Group breakdown, and run data collection for that breakdown.
I haven't tested this, so there might be bugs in the script you'll have to fix, but I'm pretty sure the theory is sound and that it will work. If you have any questions, or if you need clarification on any part of my suggestion, just let me know.
-Gray
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi
I see the negative percentage for % of reassignments
Note : In Analytics hub it shows positive percentage ,issue is only in dashboard view/widget level
Could you please suggest?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Could you please help?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Can we also do it for multiple groups like we are doing it for 'service desk' on same dashboard/report?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @raja_5! I'm so sorry for my delayed reply - I took a long vacation and have only just returned to work.
> I see the negative percentage for % of reassignments
This is caused by one of the indicators in your formula returning a negative number, and that can only happen if the indicator is being calculated through subtraction. In the article, subtraction is only part of the # Incident Reassignments to Service Desk definition in step 10. That indicator is calculated by taking the number of overall assignments and subtracting the number that weren't reassignments (those where the previous assignment group is 'Unassigned'), but that should never be negative because the overall number of assigned Incidents should always be larger than those that weren't reassignments.
That subtraction can mess with the way the Previous Assignment Group breakdown is calculated, though, and that's why there's a second part of the script in step 10. It looks like I neglected to mention that the sys_id in that script (6f31277f1bc470108b020e93cc4bcb7d) needs to be replaced with the sys_id of your own Previous Assignment Group breakdown. Have you done that? If not, navigate to Performance Analytics > Automated Breakdowns, search for the Previous Assignment Group breakdown, open it, copy its sys_id from the resulting URL, and paste that sys_id into the # Incident Reassignments to Service Desk formula.
I don't think that's really what the problem is, but we probably need to rule it out to be sure. If it isn't the problem, then we need to see where the negative value is coming from. You'd need to check the value of each indicator involved in the calculation for the August 25th date. If none of them are negative, then I think this is a question for ServiceNow Support (the formula isn't producing results that make sense based on data from the indicators used in the formula). If you do find a negative one, then we'll need to determine why it's negative. To do that, you'd need to examine everything in the definition of the indicator (Indicator Source, filter conditions, scripts, etc). I usually build a report, using all the same filters from the Indicator and Indicator Source, to simulate the data that the Indicator is getting and look for problems.
> Can we also do it for multiple groups like we are doing it for 'service desk' on same dashboard/report?
If you want to do this for multiple assignment groups, and see each of those groups separately (like in their own breakdowns), this approach can't give that to you directly. In step 5, when you define the Incident.Assignments.to.Service.Desk Indicator Source, you use filter conditions to tell the source to only focus on the Service Desk ("Value is Service Desk"). You could look for multiple values there using or conditions (e.g. "Value is Service Desk or Value is Device Support"), but that would combine all the results into a single score, not show you how many / the percentage of Incident reassignment to each group.
If you want to use the solution this article describes for multiple assignment groups, you'd need to create a separate set of indicators - one for each assignment group - and a separate widget for each. You could then put each widget on the same dashboard (in the same tab or on different tabs).
I hope this helps! If you're still running into trouble, let me know what you've learned in your investigation (with screenshots if possible) and I'll try to continue helping.
-Gray
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @graycarper
Sorry for the delay,
Thank you for the response!
Negative score issue is sorted. it was just a data issue.
regarding multiple groups: removed the filter assignment is "service desk" and added assignment group is not empty so that I should be able to select any assignment group from breakdown
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi, I was trying this solution however, in my incident_metric facts table and list collector, there are no variables named Value (only Field Value shows up as an option to select ). Are those the same?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
@raja_12 have you tried the solution here? @graycarper I am unable to get data loaded into my widget. It shows blank. My Job was run to collect data from past 3 months. Is there anything I am missing. I attempted this in my PDI.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi, @anuradha_bhatt! Thank you so much for giving this process a try! I'm so sorry you've run into hurdles, though. 😓
To answer your first question: Field Value and Value are two different fields, and they both come from the Metric [metric_instance] table (which is one of the tables included in the incident_metric database view). I created a fresh PDI and metric_instance has the Value field, so I think your instance should have it too. You can verify that by visiting the metric_instance table definition: https://<instance>.service-now.com/sys_db_object.do?sys_id=6197ef3adb332200ddfb3c00ad961965
For your second question: I just checked, and in a fresh PDI the Assignment Group metric has no data, so that's my first suspicion. You can check to see if your Assignment Group metric has data by visiting it: https://<instance>.service-now.com/metric_definition.do?sys_id=39d43745c0a808ae0062603b77018b90
If it doesn't have data, you'll need to create data by reassigning Incidents to different assignment groups. If it does have data, then my next suspicion is that Incidents have never been reassigned to a group named "Service Desk". The process, as written, only works if you have a group named "Service Desk" and have reassigned Incidents to it in your instance (though the process can absolutely be adjusted to work for any other group name).
If the Assignment Group metric does have data and that data includes records with the value field set to "Service Desk", then the problem is likely in the way Performance Analytics is looking for the data (in the Indicator Source, Automated Indicator, or Breakdown). For now, though, just let me know what you find based on my suggestions above and we'll go from there.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thank you very much for this, it is very useful!
I have a question if you don't mind.
Which breakdown did you use to create the time line?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @AEterni! I'm so glad you've found this useful!
What you're seeing there is a Workbench widget (All > Performance Analytics > Widgets) that has five Main Widget Indicators, one for each time interval that we wanted to collect data for. Here's what that widget configuration looks like...
After following the instructions in the article, you'll have created everything you need for the Daily widget indicator. To get Weekly, Monthly, etc like you're pointing out in your screenshot, you'll need to repeat steps 5, 6, 8, 10, and 11 for each time interval you want. (You'll need to create new Indicator Sources and Automated Indicators, schedule data collection jobs for them, and build new Formula Indicators with them.)
Does that help? If you run into trouble trying to create those time intervals, just let me know and I'll do my best to assist.
-Gray
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Great article, thank you! My use case is slightly different, but this got me thinking in a good direction. If I get totally stuck, I might reach out to you, but thanks again!
//Per
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Ahhh...I understand.
I tried differently. I tried using the same indicator, adding the "Age" breakdown.
Thank you for your input.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks so much, @PerV! I'm so glad this article helped! Please do reach out if you get stuck, though, and I'll see if I can help with your use case. 👍
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thanks for sharing these detailed steps! Is there a way to alter the script to show initial assignment group as opposed previous assignment group?
Given an incident/request has been assigned to multiple assignment groups over its life, I would like to create a report to show the first assignment group of any incident/request task so that I can share the report to Platform users on the number of incidents/requests being sent to other teams for resolution
Thanks
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi @NicolaH! I'm so glad you found this useful! Yes, absolutely, you can modify the script to look for the first assignment instead of the previous one. Here's what that would look like (though I'm writing this freehand and haven't tested it):
var firstAssignmentGroup = function(){
var returnMe = null;
// Query metric_instance for rows that have the same Document ID and
// Definition. Only return the oldest row, which is the first assignment.
var assignments = new GlideRecord('metric_instance');
assignments.addQuery('definition',current.mi_definition);
assignments.addQuery('id',current.mi_id);
assignments.orderBy('start');
assignments.setLimit(1);
assignments.query();
// Find and return the value (Assignment Group name) of the metric instance
var groups = new GlideRecord('sys_user_group');
groups.addQuery('name', assignments.value;);
groups.query();
while(groups.next()) {
returnMe = groups.sys_id;
}
return returnMe;
};
firstAssignmentGroup();
If you run into any trouble with that, let me know and I'll dig deeper.
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Wow thanks for the quick response, I'm getting very close to seeing what I need to see. It appears this formula is providing me with the last assignment group the ticket ended up with. I have filtered on Value | is | D&I Analytics Operations however I am wanting to view number of tickets assigned to the first 'New' value where 'Hosting - windows server' is.
The \line of code [assignments.orderBy ('start'); ] is looking at the 'start' date/time, is there a way to reference the first 'Update time' or First 'update' from Audit history as this is what I need to reference. Hope this makes sense!
Thanks again