Does anyone know if it is possible to run a metric definition against a sys_field?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-22-2009 05:38 PM
Does anyone know if it is possible to run a metric definition against a sys_field? We are trying to run a metric against the "updated by" field (sys_updated_by) at a task or incident level.
- Labels:
-
Service Mapping
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎04-13-2010 09:51 AM
Try list-editing the "Field" column in the Metrics list to the DB name you're trying to track (sys_updated_by), instead of selecting it from the list.
I'm assuming that as long as it's referenced properly, you will be able to track it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎12-29-2010 12:55 PM
This may be really over-due, but I ran into this same issue recently. I did however find this on the Metric Definition Plugin wiki page.
"Note: Metrics work on any audited field. If a field is not audited (e.g. the system field sys_updated_by), the values will not be reliable."
http://wiki.service-now.com/index.php?title=Metric_Definition_Plugin
It is for this reason that you cannot use some of the fields in metrics. I am not fully sure if that means all sys_fields are not audited. I am going to try to create a metric script to calculate this. If that does not work I will have to create another field and business rule to update that field. By doing so, if the table is already audited, my new field should then be as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-04-2011 08:27 PM
So a little more research into this....
I appears that the script calculation will only run once per record. Unlike the Field Value Duration, which will create a metric instance every time the field value changes. e.g. "Assigned to Changes", a metric instance is created and the previous one (if there) is closed out with duration and value information. The script calculation examples that are currently in there only run once.
e.g.
Resolved by Known Error - On resolution, if the incident references a Problem that is a Known Error, create one of these
Create to Resolve Duration - When an incident goes into state resolved or closed, calculate the duration from open
First Call Resolution - If the incident is inactive and the update count (sys_mod_count) is zero, create one of these.
I have tried to create conditions in the script calculations such as "if (current..changes())..." or "if (current. > "number")..." and a few other things, but they do not run. However if I do some evaluative condition e.g. "current. == something" then when that condition is true it will create a metric instance. I am trying to find out more detailed information as the documentation for this is a little sparse right now.
I have come up with a way around this. I utilize a business rule to create an event whenever the condition I specify is true. I pass in some necessary values in the parameters. I then created a script action to take the parameters and create a metric instance record. By doing so I get the metric instance and whatever value I need and can now report on it via the database view. Currently this will create a metric instance and complete it immediately. Depending on what I hear back about the script calculation full functionality I will add in an update capability.
----------Example Business Rule ------------
//event.parm1 = sys_id
//event.parm2 = table,definition,value,start,end
var table = current.getTableName();
var def = "39857ce90a0a3c18012bd53e1b95cb8b";
var value = gs.getUserDisplayName();
var start = gs.nowDateTime();
var end = gs.nowDateTime();
var mistuff = new Array(table,def,value,start,end);
var ustuff = mistuff.join('~');
gs.eventQueue("metric.update.script",current, current.sys_id, ustuff );
---------------------------------------------------
The "def" variable is the sys_id of the Metric Definition you want associated with this metric instance. I just created a blank script calculation metric definition for this. I also used the "~" delimiter because I found that some users, values etc, may have a "," in them as is standard in an array. I then used it below to split it back into an array. I created a new event called metric.update.script for this.
------------ Example Script Action -----------
//event.parm1 = sys_id
//event.parm2 = table,definition,value,start,end
var id = event.parm1;
var stuff = event.parm2;
var stuffsplit = stuff.split("~");
var table = stuffsplit[0];
var def = stuffsplit[1];
var value = stuffsplit[2];
var start = stuffsplit[3];
var end = stuffsplit[4];
var gr = new GlideRecord("metric_instance");
gr.initialize();
gr.table = table;
gr.id = id;
gr.definition = def;
gr.value = value;
gr.calculation_complete = true;
gr.start = start;
gr.end = end;
gr.duration = gs.dateDiff(start, end);
gr.insert();
-------------------------------------
As I get more info, I will post it in here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-12-2011 10:18 AM
For "posterity sake" I have been meaning to add more information to my last post. Basically, the before solution I gave will work, but it is not really a smooth integration with the rest of the metric definition process. It is a hack, that worked. i.e. getting the data in the table. So going forward I would suggest the using the following method.
Quick Background on how the plugin works:
There is an OOTB Business Rule that runs when a a task is inserted, updated, or deleted. It is really simple actually.
var gru = new Packages.com.glide.script.GlideRecordUtil.get(current)
var fieldsChanged = gru.getChangedFieldNames();
gs.eventQueue('metric.update', current, fieldsChanged.toString(), current.sys_mod_count, 'metric_update');
This java class returns a list of the fields that have changed. The fields that have changed (looking like this "[priority, urgency]" - bracketed ) are then put into an event (metric.update). The event triggers the built in Metric Definition script include "MetricInstance". This basically queries all metric definitions to see if there are any definitions that have one of these fields specified. If it finds one, and if the definition is of type "Field Value Duration" it does its standard process of creating a metric instance and calculating the field durations. If it is of type "Script Calculation" it will run the script you have specified.
So back to the root question to this post. Can you use "SYS" related fields in the OOTB functionality? As in my previous post, NO since they are not audited fields. But here is how you can MAKE it work within the same metric.update process without recreating the wheel. Forget the extra script action I suggested before. Just follow the same basic metric.update event process. You can either create a new event, or modify the existing event to add in your fields.
Create your own event:
var changedfields = [];
//Add whatever "SYS" related evaluations below and .push() them into the "changedfields" array.
if(current.sys_mod_count.changes()){
changedfields.push('sys_mod_count');
}
if(changedfields.length >=0 ){
var fields = "[" + changedfields.toString() + "]";
//gs.addInfoMessage(fields);
gs.eventQueue("metric.update",current,fields,current.sys_mod_count,"metric_update");
}
This will output an event, and the standard script action will run. You will need to have some metric definitions created that have the "SYS" related fields selected. It will then run the script calculation you have specified.
If you want to integrate it into the existing event so only 1 is created you could do this:
var gru = new Packages.com.glide.script.GlideRecordUtil.get(current)
var fieldsChanged = gru.getChangedFieldNames();
var au = new ArrayUtil(); //Access the ArrayUtil() script include
var fieldsChangedarr = au.convertArray(fieldsChanged); //This converts the java arraylist (fieldsChanged) to a javascript array.
//add some "SYS" field related evaluations below and .push() those field names into the "fieldsChangedarr" array.
if(current.sys_mod_count.changes()) {
fieldsChangedarr.push('sys_mod_count');
var newfields = "[" + fieldsChangedarr.join() + "]";
}
gs.eventQueue('metric.update', current, newfields, current.sys_mod_count, 'metric_update');
Now to point out the some items in a Script Calculation. There is a nice script include. Your script can be as easy as the below while using the methods from the script include. This will start an instance every time the field changes and complete the previous instance if there was one in there.
/ Variables available
// current: GlideRecord - target incident
// definition: GlideRecord - (this row)
createMetric();
function createMetric() {
var mi = new MetricInstance(definition, current);
if (mi.metricExists()){
mi.endDuration();
}
mi.startDuration();
}
Or if you want to put additional information in your field_value, value, start, or end fields you can customize your new metric instance record this way.
// current: GlideRecord - target incident
// definition: GlideRecord - (this row)
//if (current.field == 'something')
createMetric();
function createMetric() {
var mi = new MetricInstance(definition, current);
if (mi.metricExists()){
mi.endDuration();
}
var gr = mi.getNewRecord();
gr.field_value = current.assigned_to.getDisplayValue();
gr.value = current.assigned_to.getDisplayValue();
gr.start = current.sys_updated_on;
gr.calculation_complete = true;
gr.insert();
}
Hope this helps for "posterity sake".