Standardisera hur fält ska visas/döljas, låsas och göras tvingande i ServiceNow

En sak som man kan bli förvirrad av är varför fält visas, eller inte visas, vid olika tillfällen. Likaså att fält låses. Det finns olika sätt att dölja, visa, låsa och göra fält tvingande och där någonstans börjar spagettin. Att ha ett sätt att jobba med detta underlättar för förvaltning och felletning.

Sätta värde för attribut

De olika komponenter som går att använda för detta listas här:

UI Policy

Beroende på förutsättningar/värden i ett formulär så kan man bestämma följande för ett fält:

  • Mandatory

  • Visible

  • Read only

Client Script

Baserat på vissa event för själva objektet (ex. Incident) eller ändringar i formuläret kan man styra värden på attributen som man vill. Du kan bestämma värden av följande för fält (i praktiken kan du göra allt man kan göra från ett script på klientsidan här då det är vanlig scriptning man använder Client Script till):

  • Mandatory

  • Visible

  • Read only

ACL tillsammans med roller

ACL:er styr rättigheter på objekt- och fältnivå. ACL:er är kopplade till roller som är kopplade till grupper vars gruppmedlemmar får rollerna och rättigheterna som är kopplade till rollerna. Det man kan styra via ACL är:

  • Visible

  • Read only

Dictionary

Den inställning du gör här påverkar all användning av relaterat fält. Inställningar du gör här kan du inte åsidosätta någon annanstans. Följande kan du bestämma här:

  • Mandatory

  • Read only

UI Action

Rent krasst skulle man kunna använda UI Action för att göra ändringar i formuläret på samma sätt som ett Client Script gör. Dock är det att föredra att använda, exempelvis, UI Policy för att påverka fälten då UI Action agerar på en händelse. Framför allt är det bra om vi kan se till att vi använder så få sätt som möjligt och då kanske denna inte behövs. Med det sagt kan man påverka fält på samma sätt som för Client Script:

  • Mandatory

  • Visible

  • Read only

Standardisera

Ok, hur gör vi nu då. Ett förslag är att använda de olika funktionerna ovan på detta sätt, i prioritetsordning uppifrån:

UI Policy Använd UI Policy som först alternativ för att bestämma om ett fält ska vara Mandatory, Read only eller Visible. Det går att göra samma saker med Client Script men enligt ServiceNows dokumentation sparar man prestanda på att använda UI Policy. Det är möjligt att den prestandaskillnaden inte är märkbar men det är lättare att konfigurera dessa attribut i UI Policy än att programmera dessa i Client Script. M.a.o., går det att ställa in dessa attribut i UI Policy, gör det, utan undantag. Eller, ok, ett undantag, det är när vi använder ACL:er och roller istället. Läs där nere (det skulle kunna gå att lösa detta med scriptdelen i UI Policy men vi försöker undvika script om det går). Ska policyn användas i alla ärvande tabeller så kan man definiera policyn i tabellen som ärvs och markera Inherit (Advanced view) så ärvs policyn till alla ärvande tabeller.

ACL och roller För att styra vilka rättigheter olika roller har använder vi ACL:er tillsammans med roller. Du kan läsa här om hur man sätter upp en sådan struktur för tabeller/objekt som kommer med ServiceNow. Har du skapat en egen tabell så behöver du sätta upp reglerna som ACL:er.

  • Sätt förs upp rättigheterna för tabellen (<tabell>.

  • Sätt sedan upp en generell regel för alla fält (<tabell>.*). Båda dessa ska ge relaterade roller rätt att se objekt och fält.

  • För att dölja fält, sätt upp regler för specifika fält och definiera roll som har rätt att se det fältet (<tabell>.<fält>). På ovan länk har jag ett exempel på detta.

Notera att när man skapar en ny tabell så läggs följande regler automatisk till, allt annat (som exempelvis <tabell>.*) måste läggas till. ServiceNow har även skapat en ny roll och kopplat den till reglerna:

  • <tabell> | delete

  • <tabell> | write

  • <tabell> | create

  • <tabell> | read

Dictionary Enda anledningen till att sätta attribut härifrån är om man vet att fältet alltid ska vara antingen Mandatory eller Read only oavsett var det används. Fast du kan troligtvis använda UI Policy till detta, tillsammans med arv (om det finns tabeller som ärver varandra) enligt ovan.

Client script Använd helst inte detta för att styra nämnda attribut, använd UI Policy istället. Det kanske finns tillfällen när UI Policy inte går att använda utan man måste använda Client Script istället. Kommer ni på något sådant, skriv gärna i kommentaren nedan.

UI Action Liksom för Client script, undvik att använda UI Action om det absolut inte går m.h.a. något ovan. Jag kan inte komma på något tillfälle när man måste använda UI Action istället för UI Policy.

Applicera standarden

Det finns speciellt två scenarior när man ska använda denna standard. Ena är när man behöver sätta värdet på något attribut/fält och det andra är när man måste hitta var attribut/fält sätts.

Om man har som princip att alla alltid börjar uppifrån i listan under “Standard” ovan och använder det sätt som först är en gångbar lösning, då bör det vara mycket lättare att även hitta vad det är som sätter attributet. Börja alltid högst upp även när du letar efter hur värdet sätts.

Och om du fortfarande inte hittar var saker styrs kanske du kan titta om det finns någon Business rule som gör något (finns exempel när Business rule tar bort incidenter för visning. En sådan regel kan, och gör ibland, titta på vad användaren har för roll och ser till att inte visa några, exempelvis, incidenter för användaren).

Fortsätt läsa

Standardisera återanvändning av JavaScript i ServiceNow

Det blir normalt sett en del scriptande i ServiceNow. Smart grej är att tänkta på att designa koden så den går att återanvända. Då slipper man själv, och kollegorna, att utveckla samma funktion flera gånger och man spar tid. Man måste så klart ha ett arbetssätt så kollegorna vet om vad det finns för funktion att tillgå utan att man måste hålla på med för mycket dokumentering. Har man ett standardiserat sätt att jobba med återanvändning så ska det vara lätt att hitta funktion som har blivit utvecklad i systemet.

Allt i denna artikel är gjort i Orlando.

Naturliga ställen för att skapa kod för återanvändning är i Script include på serversidan och UI Script på klientsidan. Vi skapar klasser i vilka vi kan ha funktioner som vi når från övriga script på server- respektive klientsidan. Det är praktiskt om vi kan använda oss av abstrakta metoder så vi slipper skapa objekt innan användning. Det kan gå, men inte alltid. Exempelvis måste vi skapa objekt om vi vill att objektet ska ha kunna hålla på värden mellan anrop till klassens funktioner.

Det var ju enkelt, då gör vi så. Var det allt? Nja, vi kanske måste kolla på hur vi dokumenterar detta. Bra kod dokumenterar sig själv säger man och man räknar med kommentarer i texten till det så är det helt sant. Helst skulle man ju vilja generera JSDoc från koden man gjort men det tittar vi inte på nu. Sen måste vi titta lite på hur vi skapar klasserna också. Vill vi ha abstrakta metoder? Inte lika rättframt som för Java även om det är besläktade språk.

Namnstandard

För att vara säkra på att de klasser vi skapar inte kolliderar med de klasser som redan finns i ServiceNow behöver vi en namnstandard.

<prefix><objekt>Utils

Prefix är 1-2 bokstäver som gör att klassen skiljer sig om vi råka skapa en klass för ett objekt där ServiceNow redan har skapat en klass.

Objekt är den, troligtvis, tabell som ska användas. Kan vara andra entiteter också.

Utils är bara en statisk text som visar att det är någon form av verktygs- eller hjälpklass.

Exempel:

scIncidentUtils

‘sc’ står i det här fallet för SMICloud (mitt företag). ‘incident’ för att klassen ska användas i incidentsammanhang. Hade vi inte lagt till ‘sc’ i början hade vi fått krock med incidentUtils, på serversidan, som kommer med ServiceNow.

Klass

Vi skapar klasser i UI Script för klientsidan och Script Includes för serversidan. Vi jobbar med klasser för det är välstrukturerat sätt att kapsla in funktioner relaterade till samma område. Vi kommer kunna anropa en funktion genom att antingen anropa den direkt via klassen (abstract) eller skapa ett objekt och använda det för att anropa funktioner. Här kommer du behöva ta ett beslut, behöver du att klassen bär på data som du ska använda senare i scriptet måste du skapa ett objekt. Behöver du använda en funktion bara för att göra ett anrop och sen behöver du inte klassen längre, du kan du anropa funktionen utan att skapa ett objekt. Kallas abstrakt funktion normalt sett (oklart om det är rätt term i det här fallet, men sättet är iaf likt).

Exempel

Låt säga att en incident inte ska kunna relatera till ett problem som har lägre prioritet än själva incidenten. Vi gör jämförelsen när vi försöker spara när incidenten fått ett nytt relaterat problem eller när incidentens prioritet ändras. Är problemets prioritet lägre än incidentens så ska inte uppdateringen sparas och ett meddelande skrivas i formuläret. I en komplett lösning måste man även implementera kontroller på problemsidan men vi utgår bara från incidentsidan i detta exempel.

Vi skapar först ett Script include som göra själva jämförelsen (Jag har inte använt mig av fellhanteringen jag pratar om här för att göra koden så ren som möjligt. Lägg gärna till den i skarpa fall.):

/** @class      scIncidentUtil      Utility class incidents */
var scIncidentUtil = Class.create();
scIncidentUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    /** Compare two objects' priorities. The both input parameters/objects must to have a field 'priority' of the same format. 
    *@param     reference1      The first reference object that the priority should be compared with.  
    *                       reference2      The second reference object that the priority should be compared with. 
    **/
    comparePriorities: function(reference1, reference2) {
            //Compare using normal javascript functionality and return. Exactly what should happen is not decided here since that would minimize the general use of this function
            return reference1.priority.localeCompare(reference2.priority);

    },

    type: 'scIncidentUtil'
});

Notera att denna Script include är det API vi skapat och i vilken vi ska fylla på med funktioner relaterat till incidenter. Skapa en annan Script include för övriga tabeller/objekt.

Vi skapar sen en Business rule från vilken vi använder vår util-klass och funktion. Sätt följande värden:

  • Markera Advanced då vi måste scripta.

  • When sätts till before (om vi måste göra ‘abort’ så får inget sparas innan.

  • Business rule används när vi skapar och uppdaterar incidenten så markera Insert och Update.

  • Kör regeln endast om man väljer nytt relaterat problem till incidenten eller när incidentens prioritet uppdateras. Sätts i Filter Condition.

Business rule

Business rule


Och så klipper vi in detta scrip under flik Advanced:

(function executeRule(current, previous /*null when async*/) {

    //In case problem has a lower priority than the incident, abort and inform the user.
    var comparison = scIncidentUtil.prototype.comparePriorities(current, current.problem_id);
    if(comparison == -1){
        gs.addErrorMessage("Incident cannot have higher priority than related problem. Update not saved.");
    }
    
})(current, previous);

När vi nu uppdaterar incidentens prioritet eller relaterade problem görs kontrollen. Om incidentens prioritet är lägre eller lika med problemets prioritet så händer inget. Annars skrivs ett meddelande ut i formuläret:

Felmeddelande i incidentformuläret

Felmeddelande i incidentformuläret

Ett alternativ till ovan lösning hade kunna vara att lägga den på task-nivå. Då hade man kunnat använda den för objekt som ärver task-tabellen också. I detta scenario så sker jämförelsen på ett lite annat sätt på problemsidan så kanske är det bra att skapa en utility-klass för problem där man itererar igenom alla relaterade incidenter och gör en jämförelse. Ingenting hindrar dig från att göra själva iterationen i en utility-klass för problem och göra de enskilda jämförelserna m.h.a. denna utility-klass för incident (även om det kanske är lite overkill för en sådan enkel jämförelse).

Fortsätt läsa

Standardisera hur rättigheter används i ServiceNow

Har du någon gång suttit och slitit ditt hår när du försökt förstå hur accessreglerna fungerar då du sitter och letar efter fel? Jag har… Det går ju att debugga ACL-reglerna rätt bra men för att göra det lättare att förvalta plattformen kan det vara bra att man har definierat en struktur för tilldelning av rättigheter som alla förstår och använder. Detta går nog att göra på olika sätt men här är ett förslag hur man kan jobba med att tilldela rättigheter för de som ska kunna se olika saker samt de som ska kunna jobba med olika saker i ServiceNow.

Allt i denna artikel är gjort i Orlando.

När vi jobbar med rättigheter har vi lite olika komponenter att tillgå i ServiceNow:

Access Control Rules (ACL)

Själva reglerna som definierar access till olika tabeller och fält

Roller

ACL:er kan kopplas till roller som används antingen av grupper eller läggs direkt på personer (vilket man inte ska göra).

Grupper

En grupp kan kopplas till en roll som har vissa rättigheter (d.v.s. associerade till ACL-regler). Medlemmar i en grupp får relaterade rättigheter. Det är endast på detta sätt man ska tilldela rättigheter till personer. Inga rättigheter ska läggas direkt på en person även om det rent tekniskt är möjligt. Genom att koppla rättigheter/roller till gruppen kan man göra justeringar i gruppen som slår på alla medlemmar. Det är även lätt att ge och ta bort rättigheter från personer.

Skapa och uppdatera ACL:er

För att kunna skapa och uppdatera ACL:er som diskuteras i denna artikel måste admin få rättigheter att göra det. Annars kan han/hon endast läsa dessa.

1. Klicka på “System Administrator” (eller den användare som du har i den listan):

Skärmavbild 2020-11-03 kl. 12.41.02.png

2. Markera “security_admin” och klicka “Ok”. Nu kan du uppdatera ACL:er.

Skärmavbild 2020-11-03 kl. 12.41.10.png

Rätt att se ärendetyp

Låt oss säga att vi har en användargrupp som ska kunna se incidenter. Samma princip gäller oavsett vilket objekt (ex. change, problem) det är i ServiceNow.

(1) Vi skapar en grupp som heter “AG View Incident”. ‘AG’ står för Access Group. I.o.m. att detta inte är en grupp som ska vara synligt, exempelvis kunna tilldela incidenter till, gör det inget att namnet har prefix AG.

(2) För objekt som kommer OOB så finns det redan roller vi kan använda. Skulle vi sätta upp egna roller så måste vi gå in och göra ändringar på funktionalitet som kommer med plattformen och det ska vi inte göra. För att se incidenter krävs det att man har rollen ‘sn_incident_read’.

(3) Det krävs två ACL:er för att en användare ska kunna läsa, men inte skapa eller skriva, incidenter. Följande krävs (vi behöver inte skapa dessa med undantag om vi vill visa fält som är dolda enligt nedan):

incident Ger access till tabellen

incident.* Ger access till fälten i incident.

incident.<field> Styr rättigheterna för specifika fält. Exempelvis finns en regel för incident.work_notes som ger roll ‘sn_incident_write’ access att läsa Work Notes. I.o.m. att det bara finns en läsregel för det fältet och roll ‘sn_incident_read’ inte finns med så kommer användare som inte har roll ‘sn_incident_write’ se Work Notes. Vill du att användaren ska kunna se Work Notes kan du skapa en ACL där du ger ‘sn_incident_read’ rätt att se det fältet. Gör ‘Insert and stay’ på work_note-regeln och lägg till roll till ‘sn_incident_read’ (roll-listan kopieras inte när man gör ‘Insert and stay’).

Notera att det finns en Business Rule (‘incident query’) som säkerställer att man har rätt roll för att se incidenter. Detta är en av anledningarna till att vi inte vill skapa egna ACL:er och roller utan använda vad som finns. Skulle vi skapa egna ACL:er och roller så skulle vi behöva justera funktionen i denna affärsregel.

Skapar man egna objekt/tabeller behöver man skapa egna ACL:er och koppla dessa till roller.

(4) Vi behöver koppla roll ‘sn_incident_read’ till ‘AG View Incident’. Gå till gruppen och lägg till roll ‘view_incident’ i den relaterade listan längst ner.

(5) Ta en användare som inte redan har rättigheter att se incidenter och lägg till den personen i ‘AG View Incident’.

(6) Impersonate ovan användare. Skriv in ‘incident.list’ i vänstermenyns sökfält och tryck enter. En lista med incidenter ska visas. Om du klickar på ena öppnas incidenten med alla fält låsta.

Hemliga/Säkerhetsklassade fält

Låt säga att vi lägger ut ett fält för personnummer i incidentformuläret. Det ska inte kunna ses av alla utan endast av personer med rätt behörighet. Låt oss kalla fältet för “Social number” (u_social_number).

(1) Skapa och lägg ut fältet som första steg. Impersonate samma person som tidigare och kolla att du kan se fältet.

(2) Skapa en regel, incident.u_social_number, specifikt för detta fält. Vi tilldelar rollen security_admin till denna ACL. Så här ser regeln ut:

Skärmavbild 2020-10-29 kl. 17.28.45.png

(3) Impersonate samma användare som tidigare. Lista incidenter och öppna en incident. Du ska nu inte kunna se fältet ‘Social Number’ men alla andra. Om Security Admin loggar in så kommer den personen se fältet.

Rätt att arbeta med ärende

Vi fortsätter att jobba med incidentformuläret. Nu behöver vi ha möjlighet att skapa grupper för de som faktiskt ska jobba med incidenter också. Det är folk i olika supportlinjer i organisationen.

(1) Skapa en grupp som heter ‘2nd Line’.

(2) Vi måste lägga ut ett fält i gruppformuläret som heter ‘Type’. Gör det (m.h.a. Form Design, fältet finns fördefinierat).

(3) Vi måste skapa en typ för vårt ändamål. Skriv in ‘sys_user_group_type.list’ i sökfältet ovanför vänstermenyn. Tryck enter.

(4) Skapa en ny typ som heter ‘incident_agent’.

(5) Gå tillbaka till grupp ‘2nd Line’ och välj den nya typen i fältet du lagt ut.

(6) Lägg in en medlem i gruppen som inte är samma som fick läsrättigheter ovan och som inte har rätt att jobba med incidenter.

(7) Öppna en incident. Högertryck på texten ‘Assignment group’ och välj Dictionary.

(8) Vi måste nu se till att grupp med typ ‘incident_agent’ går att välja. Det är det som står i fliken ‘Reference Specification’ som bestämmer vilka grupper man kan välja. Då fält ‘Assigned to’ är ärvt från task-tabellen så kommer alla ändringar vi gör här slå på alla andra formulär som också använder det fältet. Det måste vi undvika och för det ändamålet så ska vi göra ‘Override’ på reference qualifier. Med ServiceNow kommer ‘itil’ definierat som ‘Type’ för assigned to.

I den relaterade listan ‘Dictionary override’ finns en rad med tabell ‘incident’. Öppna den. Det finns ett fält som heter ‘Override reference qualifier’ och när du markerar den visas ett textfält som heter ‘Reference qualifier’. Här ska du skriva in referensen till den grupptyp du vill ska vara valbar. Skriv in följande men ändra sys_id till den grupptyp du definierat i systemet:

typeLIKE244696dbdb04241014c5808768961910

Du kan få fram sys_id genom att gå till typen du skapade ovan och välja att kopiera sys_id.

(9) Spara och gå tillbaka incidenten. Klicka på förstoringsglaset bredvid fältet ‘Assignment group’. Fönstret som visas ska se ut så här:

Skärmavbild 2020-10-29 kl. 17.45.32.png

Skulle du göra samma sak på ett problem eller change så skulle du få en annan lista innan du gjort anpassningarna i denna artikel. Notera att på change måste du göra en override på “Attributes” och skriva in tree_picker=false också. Av någon anledning fungerar detta inte om den är satt till true (den sätts direkt i Dictionary till true i relaterade listan ‘Attributes’).

Nu kan man ju tro att det är klart men det är det ju inte. Om du gör impersonate på den användare du la till i gruppen så kommer den personen inte se några incidenter, vi måste fixa lite rättigheter.

(10) Vi kan återanvända samma struktur som för accessgruppen vars medlemmar skulle kunna läsa incidenter med skillnaden att vi nu måste tilldela rättigheter för att kunna skriva också. Gå till grupp “2nd Line”.

(11) En grupp kan ingå i en annan grupp. Så istället för att tilldela ‘2nd Line’ en roll så behåller vi strukturen med accessgrupper. M.a.o. skapar vi en grupp ‘AG Write Incident’ och kopplar roll ‘sn_incident_write’ till den. Vi kopplar ihop grupperna genom att välja grupp ‘AG Write Incident’ som ‘Parent’ till ‘2nd Line’. Nu räcker det med att vi lägger till användare i grupp ‘2nd Line’ för att de ska få rättigheter att jobba med incidenter. På det sättet förlitar vi oss på samma sätt att jobba med rättigheter (d.v.s. accessgrupper) men behöver endast administrera användare för den grupp som de som ska jobba med incidenter är med i.

Om det finns någon som ska kunna uppdatera incidenter utan att vara tilldelad lägger man den personen direkt i accessgruppen (exempelvis om en person är på semester kanske dennes chef ska kunna tilldela den personens ärenden till någon annan). Rollen ‘sn_incident_read’ ingår i gruppen ‘sn_incident_write’ så den får användaren på köpet.

Gör du impersonate på personen som är med i ‘2nd Line’ så kommer personen kunna se och arbeta med incidenter.

Det finns begränsningar med ovan sätt att arbeta. Du kan ju bara ha en ‘Parent’ till en grupp. Är det så att de som är med i ‘2nd Line’ ska kunna jobba med flera ärendetyper (change, problem, etc.) så funkar det inte. Då är det bättre att man helt separerar accessgrupper och grupper för tilldelning. Då måste man lägga varje användare som ska jobba med, exempelvis, incidenter i en accessgrupp (‘AG Write Incident’) samt i en grupp som används för tilldelning (‘2nd Line’). Ingen ‘Parent’ väljs då i någon grupp. Detta är troligtvis det sätt som kommer vara vanligast.

(13) Nu så, nu kan du välja vilka som ska kunna jobba med incidenten också.

Det finns fördefinierade roller för andra objekt OOB. Det är bara att använda dessa för relaterade objekt på samma sätt som är beskriver i denna artikel Listar de vanligaste här:

Skärmavbild 2020-10-30 kl. 10.05.06.png

Felhantering av script i ServiceNow

För långsiktig, och varför inte kortsiktig, stabilitet i ServiceNow bör man ha en bra felhantering i scripten man utvecklar. Här beskriver jag hur man kan skapa ett standardiserat sätt för detta i plattformen för att inte behöva återskapa hjulet hela tiden samt för att alla ska ha samma sätt att arbeta på.

Allt i denna artikel är gjort i Orlando.

Lösningen består av följande:

  • En Script Include

  • Ett UI Script

  • Ett Scheduled Script

Exempel för användning från både klientsida och serversida är beskrivna nedan.

I Script Include och UI Script finns javaklasser/API definierade som används för att på ett standardiserat sätt logga fel som uppstår i script man utvecklat. Denna loggning hamnar i error logg (‘syslog’).

För att man inte ska behöva gå in och titta varje dag om det kommit några nya fel så skapar man ett schemalagt script som kollar om det dykt upp några nya fel. Har det gjort det skapas en incident med information om de fel som uppstått och läggs på rätt CI och rätt grupp.

Lösningen är gjord på det sätt att det inte är någon skillnad på hur man använder API:t på klient eller serversidan.

Format på information i error log

Outputen i loggen kan exempelvis se ut så här:

[ERROR][Error type: RangeError][Script type: Client Script][Script: Change Assigned To][Function: onChange][Other info: n/a][Thrown error message: toPrecision() argument must be between 1 and 100]

Beskrivning i den ordning de loggas:

[<nivå>] 		[ERROR] 		 

INFO, WARNING, ERROR | Notera att man anger manuellt detta värde i koden och det sker ingen validering.

[<feltyp>] 		[RangeError]

Här skrivs felet in som man hämtar från objekt “Error” som kastas av systemet.

[<scripttyp>] 		[Client Script]

Vilken typ av script det är så man lätt ska hitta det i systemet

[<namn>] 		[Change Assigned To]

Namnet på det script, affärsregel, etc. så man lätt ska hitta var felet kastades.

[<funktionsnamn>] 	[onChange]

Namnet på den funktion i vilken felet kastades.

[<övrig info>] 	[xxx]

Övrig information som man vill logga hamnar i det här fältet. Detta används troligtvis om man har fel som är återkommande och man behöver mer information vid debugging.

[<info om fel>] 	[Thrown error message: toPrecision() argument must be between 1 and 100]

Felmeddelande som systemet skickar med i det felobjekt som kastas.

Script Include

Först börjar vi titta på den Script Include som anropas från något script på serversidan eller från lösningens UI Script.

Som du ser i bilden nedan så jobbar vi i globala scopet då detta är något som ska kunna användas i hela plattformen. Den måste också vara anropbar från klienten.

Script Include scLogginUtil

Script Include scLogginUtil

Koden nedan kan du kopiera in i en script include som du döper till “scLoggingUtil”. I övrigt har jag dokumenterat vad som händer i koden i scriptet.

Vill du läsa mer om script includes och GlideAjax kan du läs här:

Script Include

GlideAjax

Script Include scLoggingUtil:

/** @class      scLogUtil       Utility class for handling logging */
var scLoggingUtil = Class.create();
scLoggingUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    /** Handles logging requests from the client*/
    logClientError: function() {
        try {
            
            //We need the data from the client to be put in the same ojbect structure as if the data was coming from a server side script and also mapped to some of the data coming with a thrown error (e.g. .name and .message). Do note that since a thrown error is an object we use object here instead of array.
            var parameters = {};
            parameters.name = this.getParameter('sysparm_error_name');
            parameters.level = this.getParameter('sysparm_level');
            parameters.typeOfScript = this.getParameter('sysparm_type_of_script');
            parameters.nameOfScript = this.getParameter('sysparm_name_of_script');
            parameters.nameOfFunction = this.getParameter('sysparm_name_of_function');
            parameters.otherInfo = this.getParameter('sysparm_other_info');
            parameters.message = this.getParameter('sysparm_message');

            this.logError(parameters);

            return true;

        } catch (err) { //In the unlikely event that something goes wrong in logClitenError(), we do a print to the error log directly from here

            gs.logError("[ERROR][" + err.name + "][Script include][scLoggingUtil][logClientError][" + err.message + "]");
            return false;

        }
    },

    /**
     *Print the error to the error log
     *@param        err     An object containing a defined set of information about the error. 
     *                      err.level: INFO, WARNING, ERROR. 
     *                      err.name: Type of error caught by a thrown error or defined manually. Preferable the first on if possible. 
     *                      err.typeOfScript: Client Script, Script Include, Business Rule, etc. 
     *                      err.nameOfScript: The actually name of the entitey where the script retains. 
     *                      err.nameOfFunction: A script can contain multiple functions. This defines the function where the error was thrown. 
     *                      err.otherInfo: In case there is a need, mainly for debuggin purpose, to post additional information to the error log, this information can be added to otherInfo.
     *                      err.message: The message thrown by the error. 
     */
    logError: function(err) {

        //The actually writing to the error log
        gs.logError("[" + err.level + "]" + 
                    "[Error type: " + err.name + "]" + 
                    "[Script type: " + err.typeOfScript + "]" + 
                    "[Script: " + err.nameOfScript + "]" + 
                    "[Function: " + err.nameOfFunction + "]" +
                    "[Other info: " + err.otherInfo + "]" + 
                    "[Thrown error message: " + err.message + "]");

    },

    type: 'scLoggingUtil'

});

UI Script

För att kunna använda denna funktion från klienten måste vi också ha ett UI Script som anropar ovan Script Include. Klienten anropar funktion logClientError() (om man anropar från script på serversida anropar man logError() direkt). Detta är inbakat i API:t och inget vi egentligen behöver tänka på när vi använder API:t.

UI Script ska vara globalt då det ska kunna nås från hela plattformen. I detta fall har jag bara brytt mig om Desktop som UI Type.

UI Script scLoggingUtil

UI Script scLoggingUtil

Koden nedan kan du kopiera in i ett UI Script som du döper till “scLoggingUtil”. I övrigt har jag dokumenterat vad som händer i koden i scriptet.

Vill du läsa mer om UI Script kan du gör det här:

UI Script

/** @class      scLogUtil       Utility class for handling logging */
var scLoggingUtil = Class.create();

scLoggingUtil.prototype = {

    initialize: function(){

    },

    /**Prepares the error data and sends it to the server
    *@param             level           INFO, WARNING, ERROR
    *@param             err             Thrown error object
    *@param             typeOfScript    The type of script where the error was thrown
    *@param             nameOfScript    The name of the script where the error was thrown
    *@param             nameOfFunction  Name of the function where the error was thrown 
    *@param             otherInfo       If additional information is needed, mainly for debuggin purpose, that information can be added here. 
    *
    */
    logError: function(err, level, typeOfScript, nameOfScript, nameOfFunction, otherInfo) {
        try{
            var ga = new GlideAjax('scLoggingUtil');        
            ga.addParam('sysparm_name', 'logClientError');
            ga.addParam('sysparm_message', err.message);
            ga.addParam('sysparm_error_name', err.name);
            ga.addParam('sysparm_type_of_script', typeOfScript);
            ga.addParam('sysparm_name_of_script', nameOfScript);
            ga.addParam('sysparm_name_of_function', nameOfFunction);
            ga.addParam('sysparm_other_info', otherInfo);

            ga.addParam('sysparm_level', level);
            ga.getXML(responseHandler);

        }catch(err){//In the unlikely event that something goes wrong in above function, we do a print to the concole  directly from here

            jslog("[ERROR]" + 
                  "[Error type: " + err.name + "]" + 
                  "[Script type: UI Script]" + 
                  "[Script: scLoggingUtil]" + 
                  "[Function: logError->catch]" +
                  "[Thrown error message: " + err.message + "]");

        }
        /**This callback function handles the response from the server. If everyhting works fine we do nothing. If something goes wrong on the server side (and answer is false) we print an error message to the console. 
        */
        function responseHandler(response) {
            var answer = response.responseXML.documentElement.getAttribute("answer");

            //Do note that the result is returned as a string, not a bool
            if(answer == "false"){
                jslog("[ERROR]" + 
                      "[Error type: Problem logging error in error log]" +
                      "[Script type: UI Script]" +
                      "[Script: scLogingUtil]" +
                      "[Function: logError->responseHandler]");
            }
        }
    },

    type: 'scLoggingUtil '


};

Användning från klientsidan

För att anropa scLoggingUtil från ett, exempelvis, Client Script gör man så här. “err” är det kastade felobjektet: :

var logUtil = new scLoggingUtil();      
logUtil.logError(err, "ERROR", "Client Script","Change Assigned To", "onChange", "n/a");

Du kan också anropar funktionen direkt:

scLoggingUtil.prototype.logError(err, "ERROR", "Client Script","Change Assigned To", "onChange", "n/a");


Se beskrivningen av funktion logError i UI Script scLoggingError ovan.

Om du har skapat både UI Script och Script Include enligt ovan kan du testa funktionen genom följande exempel:

1. Skapa ett Client Script för incident.

2. Sätt Type = onChange

3. Sätt Field name till Assigned to

4. Se till att den är Global

5. Kopiera in följande script och spara:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }

    try{
        //As an example, we trigger an error on purpose. toPrecision() cannot be 500. 
        var num = 1;
        num.toPrecision(500); 
        
    }catch(err){
        //Let's catch the error and log it
        var logUtil = new scLoggingUtil();
        logUtil.logError(err, "ERROR", "Client Script","Change Assigned To", "onChange", "n/a");

    }
}

6. Gå till en existerande incident (om den redan är öppen ladda om så att scripten laddas).

7. Ändra Assigend To. Du behöver inte spara.

8. Gå till Error Log (“Errors” i menyn).

9. Sortera så senaste “Created” är högst upp. Nu bör du se något som detta i loggen:

[ERROR][Error type: RangeError][Script type: Client Script][Script: Change Assigned To][Function: onChange][Other info: n/a][Thrown error message: toPrecision() argument must be between 1 and 100]

Användning från serversidan

För att anropa Script Include scLoggingUtil från, exempelvis, en Business Rule gör man så här. “err” är det kastade felobjektet:

var logUtil = new scLoggingUtil();
logUtil.logError(err);

Du kan också anropa funktionen direkt:

scLoggingUtil.prototype.logError(err);

Se beskrivningen av funktion logError i Script Include scLoggingError ovan.

Om du har skapat Script Include enligt ovan kan du testa funktionen genom följande exempel:

1. Skapa en Business Rule för incident. D.v.s. sätt Table = Incident

2. Välj “When” till “Before”

3. Markera endast “Update”

4. Markera “Advanced”

5. Kopiera in följande script:

(function executeRule(current, previous /*null when async*/ ) {

    try {
        //As an example, we trigger an error on purpose. toPrecision() cannot be 500. 
        var num = 1;
        num.toPrecision(500);

    } catch (err) {

        //Prepare the data to be logged
        err.typeOfScript = "Business Rule";
        err.nameOfScript = "convertNum";
        err.level = "ERROR";
        err.nameOfFunction = "executeRule";
        err.otherInfo = "n/a";

        //Access script include scLoggingUtil and log the error
        var logUtil = new scLoggingUtil();
        logUtil.logError(err);


    }

})(current, previous);

6. Öppna eller gå till incidenten du ska testa med.

7. Ändra något och spara. Ändra inte Assigned To om du inte vill trigga ytterligare fel (om du har gjort klientövningen ovan).

8. Gå till Error Log (“Errors” i menyn).

9. Sortera så senaste “Created” är högst upp. Nu bör du se något som detta:

[ERROR][Error type: RangeError][Script type: Business Rule][Script: convertNum][Function: executeRule][Other info: n/a][Thrown error message: Precision 500 out of range.]

Samla ihop felen till en incident m.h.a. Scheduled Script

Det är inte till så stor nytta att ha ett gemensamt sätt att jobba med felhantering om inte felen upptäcks och kan hanteras. Därför är det bra med ett automatiskt jobb som kollar om det dykt upp några nya fel senaste dygnet och skapar en incident med information om felen. Notera att vi skapar max en incident per dygn men alla fel listas i den incidenten. Tänk om något fel uppstår flera hundra gången under ett dygn, jag tycker inte vi behöver ha flera hundra incidenter för det felet då. Antal gånger som felet uppstått kommer ändå stå i incidenten.

1 Skapa ett Scheduled Script

2. Markera “Conditional”.

3. Kopiera in följande kod till “Condition”. Detta för att vi inte behöver köra en del kod om det inte finns några nya fel:

//Only run this if there are any new errors in the error log to collect
answer = checkNewErrors();

function checkNewErrors() {
    try {
        var gr = new GlideRecord('syslog');
        //The query is the same as in the run script. In this request, were are checking to se if there are any errors from yesterday. Depending on when you run the scheduled job you may need to change the request query. Related error messages start with '[ERROR]' in this case. 
        gr.addEncodedQuery("sys_created_onONYesterday@javascript:gs.beginningOfYesterday()@javascript:gs.endOfYesterday()^level=2^messageSTARTSWITH[ERROR]");
        gr.query();
        return gr.hasNext();
    } catch (err) {
        var logUtil = new scLoggingUtil();
        logUtil.logError(err, "ERROR", "Scheduled job", "Create incident on error", "Condition", "n/a");

    }
}

4. Kopiera in följande kod till “Run this script”:

collectErrors();

//If there are any new errors, create an incident with information about the errors
function collectErrors() {
    try {

        //In this request, were are getting errors from yesterday. Depending on when you run the scheduled job you may need to change the request query. Related error messages start with '[ERROR]' in this case. 
        var logGa = new GlideAggregate('syslog');
        logGa.addEncodedQuery("sys_created_onONYesterday@javascript:gs.beginningOfYesterday()@javascript:gs.endOfYesterday()^level=2^messageSTARTSWITH[ERROR]");
        //We aggregate and group the messages so we don't get several rows for the same type of error.
        logGa.addAggregate('count');
        logGa.orderByAggregate('count');
        logGa.groupBy('message');
        logGa.query();
        var errors = "";
        //Loop through the result and create the text for the description field containing the number of occurences of the message and the message itself.
        while (logGa.next()) {
            var messageCount = logGa.getAggregate('count');
            errors += messageCount + "::" + logGa.message + "\n";
        }


        //Create incident

        //We want to assign the incident to the support group of ServiceNow. Hence, we need to get the CI which the support group is related to. You can use the sys_id of the support group directly but if you change supportgroup for the CI ServiceNow the incorrect support group will be assigned to the incident. 
        var grCI = new GlideRecord('cmdb_ci');
        var groupAssigned = grCI.get('869e6e47939f31003b4bb095e57ffbea');

        //Create the new incident. In this case we defined Short Description, Description, CI and Assignment Group. You may want to change/add data for the new incident. E.g. if default priority is not the one you want you may define the priority as well. 
        gr = new GlideRecord('incident');
        gr.initialize();
        gr.short_description = "Errors collected from the error log";
        gr.description = errors;
        gr.cmdb_ci = "869e6e47939f31003b4bb095e57ffbea";
        if (groupAssigned) {
            gr.assignment_group = grCI.support_group;
        }

        gr.insert();

    } catch (err) {
        var logUtil = new scLoggingUtil();
        logUtil.logError(err, "ERROR", "Scheduled job", "Create incident on error", "Run this script", "n/a");
    }
}

4. Du måste ändra de sys_id som är definierade i koden så de matchar den instans du jobbar med. I raden med grCI.get är det sys_id för det CI som gäller för ServiceNow (eller dom du vill använda något annat CI). Vi behöver en Support Group som är kopplad till det CI som används annars blir det problem när incidenten ska tilldelas en grupp.

Du kan så klart definiera vilka parametrar som ska sättas till vad enligt eget önskemål.

5. Spara

6. För att test behöver vi inte definiera något schema. Klicka på “Execute Now”.

7. Gå till incidenterna. Sortera så senaste incidenten kommer högst upp.

8. När du öppnar den ska den se ut liknande denna. Antal förekomster av listat fel står längs till vänster om själva felet:

incident.png

Sen är det bara att reda ut vad som blivit fel och fixa till det.

För att starta schemaläggningen definierar du schemat i Scheduled Script. Ovan lösning letar efter fel “Yesterday”. Rimligt är att köra jobbet mellan midnatt och start av arbetsdag så man har eventuella fel i en incident när man kommer till jobbet, kanske 01:00:

Schemaläggning av Scheduled Script

Schemaläggning av Scheduled Script

Principer för utveckling och konfigurering av ServiceNow

För att skapa gemensamma arbetssätt, minimera problem, skapa långsiktig stabilitet och få en bra förvaltningsbarhet är det bra att sätta upp ett antal principer för vad som gäller när man utvecklar och konfigurera ServiceNow. I en serie artiklar kommer jag beskriva några sådana principer.

Det finns fler saker man kan standardisera än det jag tar upp här. Exempelvis:

  • Standardisera mailmallar

  • Standardisera återanvändbar HTML-kod i Service Portal (portalen bygger mycket på att ingående komponenter återanvänds så mycket är redan redo för återanvändning).

  • Skapa standardiserade integrationer för export av data (exempelvis kanske en hostingfirma vill ge sina kunder möjlighet att importera CMDB-data) inkluderat säkerhetslösning (måste vara toksäkert så ingen kund råkar få med data relaterad till en annan kund).

Jag har valt att gå igenom några punkter som är mycket centrala i ServiceNow och som jag frekvent brukar använda vid utveckling och förvaltning. Bara att klicka sig vidare:

Ska du sätta upp, eller förbättra, en supportverksamhet, Help eller Service Desk? I den här artikeln diskuterar vi saker att tänka på

När man sätter upp en supportorganisation krävs en del planering samt att man förstår naturen av en supporverksamhet. Exakt vad som krävs beror på typ av verksamhet, tillhandahållna tjänster, storlek på företaget, kundgrupper, etc. En startup kan ha andra behov än ett stort väletablerat företag. I denna artikel går vi igenom saker du behöver tänka på när du sätter upp, eller genomför förbättringsarbete, av din egen supportorganisation. 

Målgruppen för denna artikel är personer som ska sätta upp en supportverksamhet, Help Desk, Service Desk, etc. i ett litet (< 50) till mellanstort (< 250) företag. Vi har dock lagt in lite saker att tänkte på för större företag i slutet av artikeln. För definitioner av "Help Desk" och "Service Desk", se denna artikel

Terje Hatt, tidigare global chef över Fujitsu Customer Service och SEB Service Desk, för tillfället konsult på Daymark AB, är medförfattare till denna artikel. 

Små till medelstora företag

SLA (Service Level Agreement)

SLA är ett avtal man gör med kunden. I detta avtal finner man responstider, åtgärdstider, datum och tidpunkter för servicefönster, överenskomna tillgänglighetstider för tillhandahållna tjänster, etc. Exempelvis kan ett SLA specificera responstiden för en incident till 30 min för kontorstid men 2 timmar utanför. Avtalet kan också definiera att en levererad IT-tjänst ska ha en tillgänglighet på 97,5% av alla timmar på dygnet under en mätperiod på ett kalenderår, exkluderat servicefönster. 

SLA är en av en viktig grundpelare för att veta vad som förväntas av supportverksamheten så att denna kan organisera sig efter dessa krav. 

Definiera tydliga och mätbara mål för supporten

Om du definierar mål för din supportverksamhet kan du planera bemanning, utbildning och nödvändiga processer för att uppnå målen. Alla mål måste inte finnas med i ett SLA för en supportverksamhet. 

Vill du sätta upp en supportverksamhet som bara dispatchar inkomna ärenden till rätt grupp som kan hjälpa kunden? Detta är normalt för ett Call Centre vars policy brukar vara "Catch and dispatch". En "Catch and dispatch"-funkion har låg lösningsgrad och kan ha målet att dispatcha så många ärenden som möjligt. Personalen i en sådan funktion kan behöva utbildning i hur man kommunicerar med kunder och hur man hanterar "svåra" kunder. 

Ska ni sätta upp ett supportfunktion med hög lösningsgrad? Då är det ett "Competence centre", eller normalt kallat Helt Desk eller Service Desk, ni sätter upp. Förutom samma utbildning som personalen i en "Catch and dispatch"-funktion behöver personalen i en sådan funktion ha domän-/expertkunskap om de ärenden som kommer in. 

Inom de olika typerna av funktioner kan man sätta olika typer av mål. För "Catch and dispatch" kan målet vara hur många samtal som ska hanteras. Inom "Competence centre" kan det vara lösningsgrad av inkomna ärenden. 

Definiera supportkanaler och informera användarna om hur de kontaktar supporten

Hur ska du ta emot supportförfrågningar från användarna? Detta spelar roll för hur du ska utrusta supportpersonalen. I de fall då kunden ska kunna ringa in måste supportpersonalen ha bra headsests för att både kunna skriva och prata samtidigt. Ska kunden endast använda email så behövs ett ärendehanteringsverktyg, som stödjer kommunikation från kunden endast med hjälp av email, för att administrera inkomna ärenden. Ett ärendehanteringsverktyg är nödvändigt oavsett hur användarna kontaktar supporten då allt måste administreras på ett sätt så att man inte tappar ärenden mellan stolarna. 

Nedan följer några normala kanaler för kommunikation:

  1. Email
  2. Ärendehanteringsverktyg (både för email och när användaren själva kan logga in)
  3. Telefon
  4. Webbformulär (för att skicka en förfrågan från en hemsida)
  5. Facebooksida
  6. Twitter

Gör det lätt för användarna att hitta information om hur man kontaktar supporten. Normalt så tittar användarna på din hemsida för att få information om hur man kontaktar supporten. Presentera gärna denna information på första sidan. 

Sätt förväntningarna hos kunden/användarna

Om du har en businesss-to-business (B2B) supportfunktion så har du troligtvis ett SLA som definierar responstider och kanske åtgärdstider. Har du en business-to-consumer (B2C) supportfunktion så kanske inte det är fallet. 

Hantering av förväntningar hos B2B 

Förväntningarna mellan företag är oftast definierat i ett SLA, som vi har diskuterat ovan. 

Det är en sak att ha ett SLA definierat och signerat, en annan sak att nödvändiga personer ska veta vad erat SLA säger och därmed vilka förväntningar som finns. Tyvärr händer det att personer som borde veta om, exempelvis, responstider inte gör det. Organisationen måste utbilda nödvändig personal om förväntningarna som finns från dem som leverantör och vad kunden har blivit lovad. 

Den här informationen ska vara lätt tillgänglig oavsett tidpunkt. Om det är ett enkelt SLA kan information finnas tillgänglig på intranätet. Om det är ett stort företag med många olika tjänster, kunder och avtal kan man lägga information i en tjänstekatalog och/eller CMDB (Configuration Management Database) där varje tjänst eller server har sitt avtal kopplat. 

Om det ändå inte finns något SLA kan det vara bra att definiera vilka nivåer verksamheten ska mäta sig mot för att kunna tillhandahålla någon nivå av kvalitet på supporttjänsterna. Obegränsad svarstid på en förfrågan är inte ett alternativ...

Hantering av förväntningar hos B2C

Denna sektion kan också gälla intern support i stora organisationer. 

När en kund ringer supporten så förväntar de sig (eller hoppas iaf...) på ett snabbt svar. Tyvärr är det inte alltid så. Vad ett företag, eller myndighet, kan göra är att tillhandahålla information från deras växel. När man ringer Skatteverket får men ett meddelande i telefon liknande detta: "Du har nummer 123 i kön. 95 agenter jobbar på att så snabbt som möjligt hjälpa dig". Tänk om man endast hade fått informationen "Du har nummer 123 i kön", hade du väntat kvar i telefonen? Genom att presentera hur många som jobbar i supporten, eller estimerad väntetid, får personen en uppfattning om hur länge de kommer behöva vänta. Varför inte presentera denna information bredvid supportnumret på hemsidan?: "För närvarande har vi 12 min väntetid". 

Liknande sätt att sätta förväntningarna kan användas om användaren mailar till supporten eller skickar in frågan vi ett formulär på hemsidan. Ett automatiskt svar kan skickas ut som informera om förväntad tid innan de får hjälp. Detta skulle kunna reflektera SLA som företaget har definierat även om det inte är ett signerat avtal. Eller så kan det finnas någon intelligens som i systemet som räknar ut hur långa svarstiderna är för tillfället. 

Samma gäller här som för B2B, finns det inget SLA är det bra att definiera vilka svars- och åtgärdstider som förväntas för att kunna tillhandahålla en viss kvalitet på supporttjänsten och för att ha något att sätta förväntningarna mot. 

"Knowledge management"

Bra kunskapshantering kan markant minska arbetsbelastning för supportpersonal samt även svars- och åtgärdstider på supportfrågor. 

Kunskap kan hanteras på olika sätt: 

Dokumentera återkommande uppgifter - Samma typ av supportfrågor kan återkomma i en supportverksamhet. Dokumentera dessa, informera om dessa och gör dessa tillgängliga för supportpersonalen så inte nästa person måste uppfinna hjulet igen. I bästa fall kan man automatisera hur dessa frågor löses, men det är inte fokus för denna artikel. 

Driftstatus - Om det för tillfället är driftproblem kan man lägga upp information om detta dit användarna vänder sig för att få support (ex. intranätet, supportportal, etc.). Om de ser att det finns information om driftstörningar så kanske de väljer att inte registrera ett ärende och därmed sparas en del arbete för supportpersonalen. Man kan också proaktivt skicka ut information om pågående störningar till användarna genom att använda mail- eller SMS-listor. Ytterligare sätt kan vara att presentera information för användare baserat på vad de skriver när de ska registrera ett ärende via ett webbformulär. Om det finns pågående störningar och man kan matcha det med vad användaren skriver i webbformuläret så väljer kanske användaren att läsa denna information istället för att skapa ett nytt ärende. 

Supportartiklar - Du kan tillhandahålla olika typer av artiklar till dina användare. Dessa bör finnas tillgängliga i en supportportal. Baserat på vad en användare skriver när de ska registrera ett ärende så kan man matcha det med de artiklar som finns och presentera ett urval. Detta kan vara artiklar om workarounder för kända fel, användarguider, etc. Comaround har ett bra verktyg för detta där många av supportförfrågningar kan hanteras innan supportpersonalen kopplas in. Verktyget kommer med massor av färdiga användarguider för, exempelvis, Windows OS, MS Office, olika mobiltelefoner, mm. 

Registrera en supportförfrågan

För att tillhandahålla en god support är ett ärendehanteringsverktyg nödvändigt. Vilken typ av ärendehanteringsverktyg som ska tillhandahållas hänger på vilken typ av supportverksamhet man satt upp. Läs denna artikel för att få information om olika typer av verktyg.

Du använder detta verktyg för att hålla ordning på kundernas supportärenden. All information och kommunikation sparas i ett sådant verktyg. När en annan supportperson tar över ett annat ärende finns all information sparad så denne kan fortsätta där den första slutade utan att göra ett detektivarbete för att ta reda på vad som hänt. 

Information som sparas i ett sådant verktyg kan användas för statistisk uppföljning. Exempelvis kan man identifiera olika områden eller system som behöver extra fokus. Om det exempelvis är ovanligt många incidenter registrerade på ett specifikt system så måste man kanske reda ut varför och åtgärda problemet. Har man en växande trend av antal ärenden måste man vidta åtgärder för att hantera denna växande mängd. 

Ett par olika exempel på ärendehanteringsverktyg listas här: 

ServiceNow - I princip det enda riktiga alternativet om man vill ha ett mycket kraftfullt, kompetent och anpassningsbart verktyg med processtöd idag med (jag kanske inte är helt objektiv här...). Tillhandahålls som tjänst från molnet. 

Freshdesk - Enkelt ärendehanteringsverktyg. Tillhandahålls som tjänst från molnet. 

Zendesk - Enkelt ärendehanteringsverktyg. Tillhandahålls som tjänst från molnet. 

Stora företag

Det finns lite mer att tänka på för större organisationer (>250 anställda) som vi vill också vill presentera. Beroende på verksamhet kan detta så klart vara intressant för mindre företag också. 

OLA (Operational Level Agreements)

OLA kan användas i större verksamheter där supporten är beroende av interna enheter för att kunna leverera sina tjänster. OLA är egentligen bara ett internt SLA mellan olika interna enheter.  

Det är viktigt att ett OLA mappas till de SLA som skrivs med kunden. Ett OLA kan inte ha en svarstid på att den interna enheten ska börja jobba inom 2 timmar om SLA mot kunden har definierat svarstiden till 1 timma. 

Tillsätt ansvariga för processer och styrning

För att sätta upp en supportverksamhet som är anpassat till uppsatta mål måste en person som ansvarar för styrningen tillsättas. Inom ansvaret för denna person ligger att definiera strategier för hur supportverksamheten ska struktureras. Detta kan bl.a. innehålla ansvar för att hur supporten ska organiseras, vilka verktyg som ska användas, utbildning av personal, supportkulturen, etc. Det är även den som ansvarar för styrningen att etablera strategier för arbetet med processer, vilket tar oss till nästa punk, processansvariga. 

I större verksamheter finns det ofta en processansvarig för varje process. Denna person ansvarar för att definiera processen, anpassa den när verksamheten växer och mognar, definiera krav på supportverktyg som stödjer processen, etc. Den processansvariga är inte den som exekverar själva processen. Istället hjälper den ansvariga verksamheten i användandet av processen. Processen ska byggas in i de arbetssätt som personalen använder sig av. Det är processägarens ansvar att utbilda personalen i hur de olika processerna fungerar. 

Varför separera olika ärendetyper i en supportverksamhet

Den här artikeln handlar inte om varför man ska jobba med ärendetyper som incident, problem, change request, etc. Den handlar om varför man bör separera ärenden i olika typer till att börja med. Stöd för de olika ärendetyperna implementeras i ett ärendehanteringssystem. 

Ibland tycker jag att det kan vara svårt att hitta argumenten för varför något ska göras eller implementeras. De känns självklart men när jag ska börja argumentera varför så finns inte argumenten till hands alltid. Istället dyker de upp efter ett tag, när diskussionen är slut. Jag har fundera på att skriva något om varför man ska göra olika saker i en ITSM-verksamhet. I huvudsak för min egen referens skull för att ha när jag kommer till nya kunder. Det här kan vara början på det...

I mitt nuvarande uppdrag ansåg jag att verksamheten skulle dra fördel av att dela upp sina aktiviteter i olika ärendetyper. Jag tog fram ett underlag till ledningen för att stödja mitt case. Denna verksamhet är en HR-organisation, vilket i praktiken är en supportverksamhet som också administrerar HR-system. HR-processer är också mycket viktiga i en sån här verksamhet och är uppsatta som Configuration Items i CMDB och ändringshanteras i processen för Change Management. Innehållet i den här artikeln går även att applicera på IT-verksamheter. 

Nedan kan du se hur jag argumenterade (med mindre förändringar från det faktiska materialet): 


Behov/Effekt

Tydlig separation av olika typer av aktiviteter. 

Motivation

  • Svårt att skilja mellan olika typer av aktiviteter som change (RFC), incidenter, problem, service requests, etc. när de hanteras som en och samma typ i verksamheten och verktyget. 
  • Svårt att skriva och följa upp SLA om olika aktiviteter registreras som en och samma typ i ärendehanteringsverktyget. 
  • Svårt att veta vad man ska gör om man inte kan skilja på, exempelvis, incidenter och problem i ärendehanteringsverktyget (bara se till att användaren kommer vidare eller fixa root cause?). 

Behov/Effekt

Möjlighet att prioritera olika aktiviteter korrekt

Motivation

  • När olika typer av aktiviteter, som incidenter, problem, change request, service requests, hanteras som en och samma typ i ärendehanteringsverktyget kan det vara svårt att urskilja incidenterna som i sin natur har högst prioritet. 

Behov/Effekt

Analysera hur system eller processer mår

Motivation

  • Antal incidenter och problem som registreras på ett system eller process kan var en god grund för att ta reda på hur systemet eller processen mår. System eller process med flest incidenter och problem behöver kanske mer resurser för att stabiliseras. Detta kräver så klart att man väljer Configuration Item (Ex. applikation, server, nätverkskomponent, process, tjänst, etc.) i alla ärenden så man kan få ut korrekt statistik. 

Behov/Effek

Analysera trender för olika typer av aktiviteter

Motivation

  • Analyser av trender för olika ärendetyper kan användas som underlag när man planerar bemanning eller andra åtgärder för att bemöte trenderna. 
  • Om ett system har en uppåtgående trend av incidenter kan man vidta åtgärd innan allvarliga problem, eller total systemhaverier, uppstår. 
  • Analysera trender för att fokusera resurser till mest behövande ställe

Självklart kan man alltid analysera ärenden, om man inte separerar dessa i något verktyg, för att få reda på vad det är för aktivitet. Detta är dock mycket ineffektivt och det är inte lätt att implementera olika arbetsflöden för olika aktiviteter, vilket enligt mig är ett krav. Du kan inte följa upp SLA och skapa användbara rapporter om du inte separera olika typer av aktiviteter i ärendehanteringssystemet. 

Vad är det för skillnad på ett verktyg för en Help Desk, Service Desk eller ITSM-verksamhet?

Det finns flera olika namn för ärendehanteringssystem (ex. (blir lite engelska, hur sjutton översätter man...?) help desk system, service desk tool, ticketing tool, issue tracker system, trouble ticketing system, ITSM tool, etc.) var syften är att underlätta hanteringen administrationen av olika typer av förfrågningar från personer eller organisationer med någon typ av behov av hjälp eller annan typ av request (ex. change request). Är det någon skillnad på dessa verktyg? Om det finns, vad är skillnaden och definitionen för dessa verktyg. Låt oss försöka komma på det. 

Jag trodde det här skulle bli en enkel artikel att skriva. "Jag googlar väl lite för att hitta passande definitioner och så skriver jag om det här...". Så lätt var det inte... För att definiera de olika typerna av verktyg var jag tvungen att gräva lite djupare och nedan följer min slutsatser. Kommentera gärna om du inte håller med. Det blir lite engelska då man ofta refererar till den här typen av verktyg på engelska. 

Ticketing tool | Ärendehanteringsverktyg

Finns det en definition som passar alla typer av verktyg? Vi börjar med att lista vad som är gemensamt för alla dessa verktyg: 

  1. Det måste vara möjligt för en användare att registrera ett ärende som någon (agent) ska hjälpa till med
  2. Någon (agenten) ska kunna ta emot ärendet
  3. Agenten och användare ska kunna komplettera ärendet med ytterligare information
  4. Agenten ska kunna svara användaren från verktyget
  5. Agenten och användare ska kunna kommunicera kring ärendet så att konversationen hamnar i verktyget

Jag tycker ovan är minsta gemensamma nämnaren för den här typen av verktyg. Om något av ovan saknas är det inte ett verktyg värt att överväga anser jag. Vi kan använda "Ticketing tool" eller "Ärendehanteringsverktyg" som en generell term för denna typ av verktyg. Några av er kanske inte håller med men så här tänker jag: 

Ett ärendehanteringsverktyg ger dig en plats i kön. Du står i kön för att få hjälp. Du ska m.a.o kunna registrera ditt ärende och får en köplats i ett ärendehanteringsverktyget. Agenten kan så klart fuska och välja ett ärende som ligger längre bak i kön (det har nog hänt, typ en eller två gånger...). 

 

"Men är inte ett ärende ett problem?" kanske någon av er säger. Det kan så klart vara ett problem men det kan också vara en förändringsförfrågan (Change Request), begäran om användarguidning av en applikation (Service Request), mm. Oxfords Dictionaries definierar "ärende" så här:

Svenska, fritt översatt: (inom informationsteknologi) ett ärende som registrerats i ett uppdragssystem med detaljer om ett problem som måste hanteras eller andra uppgifter som ska utföras

Engelska: (in information technology) a request logged on a work tracking system detailing an issue that needs to be addressed or task that must be performed

"Work tracking system" eller "uppdragssystem" är ett ärendehanteringsverktyg. 

Definitionen för ett "Ärendehanteringsverktyg | Ticketing tool" skulle kunna se ut så här: 

Svenska: Ett ärendehanteringsverktyg är en applikation som tillhandahåller möjligheten att skapa ärenden som tas emot av en person, eller automatisk process, som ser till att nödvändiga aktiviteter utförs för att hjälpa personen som efterfrågat hjälp. Verktygen ska tillhandahålla möjligheten att registrera information och status på ärendet samtidigt som det ska vara möjligt att kommunicera mellan personen som efterfråga hjälp och agenten.  

Engelska: A ticketing tool is an application used to facilitate the creation of requests that are received by a person or an automatic process, who/which takes action in order to help the requestor with what has been requested. The tool should facilitate registration of information and progress about the request and also handles the communication between the requesting part and the agent.

Ok, då var det tydligt. Låt oss fortsätta definiera övriga verktyg. 

Verktyg för service desk och help desk 

När man letar efter definition för dessa verktyg hittar man bara definitioner för "Service desk" och "Help desk", inte själva verktygen. Men det är en bra startpunkt, låt oss undersöka definitionerna för nämnda funktioner. 

Help desk 

Så här definierar ITILv3 Help Desk:

Svenska fritt översatt: [1] (Service Operation) En kontaktpunkt för användare att rapportera incidenter. En Help Desk är normalt mer tekniskt orienterad än en Service Desk och tillhandahåller inte en "Single Point of Contact" för all interaktion. Termen Help Desk används ofta synonymt med Service Desk. 

Engelska: [1] (Service Operation) A point of contact for Users to log Incidents. A Help Desk is usually more technically focused than a Service Desk and does not provide a Single Point of Contact for all interaction. The term Help Desk is often used as a synonym for Service Desk.

och dictionary.com definierar det som:

Svenska fritt översatt: ett center för teknisk support tillhandahållen av affärsverksamheten eller organisationen

Engelska: a center for technical support provided by the business or organization

och Oxford Dictionaries

Svenska fritt översatt: en tjänst som tillhandahåller information och support till dataanvändare, speciellt inom ett företag

Engelska: a service providing information and support to computer users, especially within a company.

Wikipedia utvecklar det lite mer men i grunden stödjer de ovan definitioner.

Baserat på ovan kan vi göra slutsatsen att en Help Desk

  1. inte är tungt processorienterad. En ärende är på sin höjd vidarebefordrat till en annan teknisk grupp för åtgärd. 
  2. huvudfokus på att hjälpa användare med incidenter och problem. 
  3. tillhandahåller inte nödvändigtvis en "Single Point of Contact". 
  4. kanske inte tillhandahåller en ägare av ärendet som följer upp statusen och framsteg.

Enligt ITILs definition [1], "Service Desk" är ofta synonymt med "Help Desk". Så är det säker men notera att ITIL själv har olika definitioner på Service Desk och Help Desk. 

Ytterligare definitioner kan finnas på TechTarget.

Service desk 

Så här definierar ITILv3 Service Desk:

Svenska fritt översatt: [1] (Service Operation) "Singel Point of Contact" mellan tjänsteleverantören och användaren. En typisk Service Desk hanterar incidenter och service request samt hanterar kommunikationen med användaren. 

Engelska: [1] (Service Operation) The Single Point of Contact between the Service Provider and the Users. A typical Service Desk manages Incidents and Service Requests, and also handles communication with the Users. 

Wikipedia utvecklar även detta lite mer. Del av skillnaden mellan Help Desk och Service Desk förklarar så här:

[..] En service desk syftar till att underlätta integreringen av affärsprocesser i infrastrukturen för service management. [..]

[..] A service desk seeks to facilitate the integration of business processes into the service management infrastructure. [..] 

Jag tolkar ovan som att affärsprocesserna kan initieras i, eller tas vid av, en Service Desk. Exempel skulle kunna vara en HR-process som handlar om anställning. En del aktiviteter i den processen kan initieras via en Service Desk. ITIL-processer är också en del av affärsprocessen då en organisation kan tillhandahåller dessa processer som tjänster i en tjänstekatalog (möjligtvis sammanfattat i "Supporttjänster"). 

Baserat på ovan kan vi göra slutsatsen att en Service Desk

  1. kan vara/är processorienterad
  2. kan hjälpa användare med incidenter och problem men även andra typer av supportfrågor
  3. tillhandahåller en "Single Point of Contact" som sköter kommunikationen med användaren
  4. äger ärenden och ansvarar för uppföljning av status och framsteg

Ytterligare definitioner kan finnas på TechTarget.

Slutsats

Definition av Help Desk-verktyg

Ett Help Desk-verktyg är en applikation som tillhandahåller möjligheten att skapa en supportförfrågan som tas emot av en person som vidtar åtgärder för att hjälpa användaren. Verktyget ska tillhandahålla möjligheten att registrera information om ärendet, framsteg på ärenden och även möjlighet till kommunikation mellan användaren och supportpersonal. Ett Help Desk-verktyg behöver inte tillhandahålla processtöd eller stöd för "Single Point of Contact" (ex. ägandeskap av ärenden utöver tilldelade person). 

Definition av Service Desk-verktyg:

Ett Service Desk-verktyg är en applikation som tillhandahåller möjligheten att skapa en supportförfrågan som tas emot av en person eller automatisk process som vidtar åtgärder för att hjälpa användaren eller initierar relaterad process i organisationen. Verktyget ska tillhandahålla möjligheten att registrera information om ärendet, framsteg på ärenden och även möjlighet till kommunikation mellan användaren och supportpersonal. Ett Service Desk-verktyg måste tillhandahålla processtöd och stöd för "Single Point of Contact" (ex. ägandeskap av ärenden utöver tilldelade person). 

Med dessa definitioner färdiga kan vi se att samma typ av verktyg kan ibland användas i både en Service Desk och Help Desk. Det är en fråga om hur man konfigurerar verktygen. Det är troligare att man kan använda ett Service Desk-verktyg i en Help Desk än tvärtom då ett verktyg för en Service Desk, enligt definition, innehåller mer funktionalitet. ITSM-verktyg och Service Desk-verktyg är samma typ av verktyg. 

A Service Desk/ITSM tool can support other processes and activities that not necessarily need to pass through the Service Desk. Among others, these could be Release and Change Management activities. 

Service Desk-/ITSM-verktyg kan användas för processer som inte nödvändigtvis inte passerar själva Service Desken. Bland andra kan det vara processer för Release och Change. 

Trouble ticket system/Issue tracker system

När jag gjorde den här analysen kunde jag inte identifiera någon direkt skillnad på Trouble Ticket-/Issue Tracker-verktyg och Help Desk-system. Några vill jämföra Trouble Ticket-/Issue Tracker-verktyg med ett system för att administrera rapporterade buggar. Jag håller inte riktigt med om det. Ett ärende/problem som rapporterats kan resultera i att en bugg registreras i ett system för administration av buggar. 

Du kan läsa mer om dessa typer av system här: 

Wikipedia

TechTarget

Slutsats

It is difficult to find out what the difference is between the different types of tools out there. Making use of difference sources and the definitions of what a Service Desk and a Help Desk is, these are the definitions I came up with: 

Det är ganska svårt att reda ut exakt vad definitionen för de olika verktygen där ute är. Genom att använda olika källor och definitioner för vad ett Service Desk-verktyg och ett Help Desk-verktyg är om jag upp med följande definitioner: 

Ärendehanteringsverktyg | Ticketing tool

Ett ärendehanteringsverktyg är en applikation som tillhandahåller möjligheten att skapa ärenden som tas emot av en person, eller automatisk process, som ser till att nödvändiga aktiviteter utförs för att hjälpa personen som efterfrågat hjälp. Verktygen ska tillhandahålla möjligheten att registrera information och status på ärendet samtidigt som det ska vara möjligt att kommunicera mellan personen som efterfråga hjälp och agenten.  

Service Desk-/ITSM-verktyg

Ett Service Desk-verktyg är en applikation som tillhandahåller möjligheten att skapa en supportförfrågan som tas emot av en person eller automatisk process som vidtar åtgärder för att hjälpa användaren eller initierar relaterad process i organisationen. Verktyget ska tillhandahålla möjligheten att registrera information om ärendet, framsteg på ärenden och även möjlighet till kommunikation mellan användaren och supportpersonal. Ett Service Desk-verktyg måste tillhandahålla processtöd och stöd för "Single Point of Contact" (ex. ägandeskap av ärenden utöver tilldelade person). 

Help Desk-/Trouble Ticket-/Issue Tracker-system

Ett Help Desk-verktyg är en applikation som tillhandahåller möjligheten att skapa en supportförfrågan som tas emot av en person som vidtar åtgärder för att hjälpa användaren. Verktyget ska tillhandahålla möjligheten att registrera information om ärendet, framsteg på ärenden och även möjlighet till kommunikation mellan användaren och supportpersonal. Ett Help Desk-verktyg behöver inte tillhandahålla processtöd eller stöd för "Single Point of Contact" (ex. ägandeskap av ärenden utöver tilldelade person). 

Referenser

[1] The Official Introduction to the ITIL Service Lifecycle, OGC - Office of Government Commerce

Att välja ett ärendehanteringsverktyg för Service Desk, Help Desk, ITSM eller Service Management.

Att välja verktyg kan vara lite svårt idag med alla typer av ärendehanteringsverktyg som finns där ute idag. För att göra det lite lättare listar den här artikeln olika saker att tänka på i själva urvalsprocessen. 

Jag är inte den första som försöker sätta ihop en sån här lista. Jack Wallen har skapa en top-10-lista. Hans fokus ligger mer på specifika krav medan jag försök hålla en lite högre nivå. Alex Hisaka har också satt ihop en lista, mer lik den här. 

  1. Vad ska du ha verktyget till? Det kan kännas som en självklar fråga men att förstå svaret på detta kan få dig att förstå om du ska ha ett verktyg för Service Desk, Help Desk, Test Management, Bug Tracking, Service Management, etc. Du kan läsa mer om olika typer av verktyg i följande artikel.

    När du hart gjort detta klart för dig är det dags att börja med mer specifika krav. Leta rätt på de verktyg som verkar intressanta. Jämför verktygens funktionalitet med de krav du specificerat. När du är klar med detta bör du ha minskat antalen potentiella verktyg till endast några få. 

    Om det är första gången du letar efter denna typ av verktyg och inte är van vid kravställnig av dessa kan du leta rätt på ett antal ärendehanteringsverktyg som verkar intressanta. Läs på vad verktygen kan göra och vad de har för funktion. Efter ett tag börjar du förstå vad som är möjligt med denna typ av verktyg och det borde leda till att du kan börja se vilka krav er verksamhet borde ha på ett sådant systemet. 
     
  2. Användbarhet och effektivitet Mycket funktion kommer oftast med sämre användbarhet. Normalt sett så är det en balans mellan användbarhet och funktionalitet. Välj inte ett verktyg med massor av extra funktionalitet om du inte är säker på att ni behöver det nu eller i framtiden. Ju komplexare ett verktyg är desto dyrare är det normalt sett att förvalta och konfigurerar om. Ibland krävs t.o.m. ren utveckling. 

    Man ska ha användbarhet i åtanke både när det gäller att använda system men också för konfigurering av systemet. Om du enkelt kan anpassa innehållet/formulär så att endast den information som är nödvändig för användaren vid en given tidpunkt är synlig så bidrar det med värde då "less is more". 
     
  3. Underhåll Detta är något som man inte ska underskatta. Det kan vara mycket dyrt med underhåll, mångdubbelt dyrare än själva licenskostnaden ibland. Du måste exempelvis bestämma om du ska ha en molnlösning (klart du ska...), hosta den själv eller använda en SaaS-lösning. Det finns också andra varianter som exempelvis PaaS. PaaS är en plattform som man ofta måste utveckla eller konfigurera i ganska stor omfattning för att anpassa till de behov man har (Exempelvis ServieNow). Företag kan ha flera utvecklare på heltid för sådana system. 

    SaaS - Software as a Service
    PaaS - Platform as a service
    In house - Installeras och driftas internt


    Som nämndes ovan, ibland kan konfigurering vara den dyra posten. Detta kan vara avgörande då det kan ta mycket tid att sätta upp verktyget enligt de krav ni har. Med det sagt, i mer komplexa verksamheten kan det vara värt den extra kostnaden att sätta upp samt vidareutveckla funktionen över tid. Oftast vidareutvecklar man verktygen i samband med att organisationen mognar. Det är ditt jobb att utvärdera vad som är värt vad. 
     
  4. Dokumentation När du börjat jobba med verktygen kommer du säkerligen komma på saker du vill göra som ni inte tänkte på när ni köpte verktyget. Du behöver ha bra instruktioner för att göra tänkta anpassningar. Mao så är bra och lättförståelig dokumentering viktigt så ta med det som en punkt i utvärderingen. 
     
  5. Budget och funktionalitet Att betala mer betyder inte att du får ett bättre verktyg i förhållande till de behov som finns. Det kan betyda att ni betalar för mycket för ett avancerat verktyg vars funktion ni inte behöver och kanske får ni extra dyr förvaltningskostnad. 
     
  6. Branding Det är viktigt för de flesta organisationer att anpassa verktyget till sin grafiska profil. Det är extra viktigt om det är kunder som ska använda sig av verktyget för att skicka in supportfrågor. En del verktyg låter dig konfigurera utseende och logga m.h.a ett enkelt grafiskt gränssnitt medan en del är mer avancerade och tillhandahåller möjligheten att editera CSS-filer. CSS är mer avancerat och kräver en mer avancerad kompetens. Fördelen är så klart att man ofta har flera möjligheter att påverka utseendet. En del verktyg erbjuder båda möjligheterna. 
     
  7. Testperiod De flest verktyg av enklare karaktär erbjuder en gratis testperiod. Det är en självklarhet att testa verktyget ett tag innan man tar ett definitivt beslut. För mer avancerade verktyg kan det hända att denna möjlighet inte finns. Det får så klart bli del av en förstudie att försäkra sig om att verktygen passar bra till tänkt verksamhet. 

Om du ska introducera verktyget i en större verksamhet är det ett normalt sett ett omfattande arbete. Exempelvis ska processer definieras eller analyseras och sedan ska man implementera stöd för processerna i verktyget. Ett tips är att ta in konsulter som är vana att jobba med processutveckling (exempelvis ITSM-konsulter) samt konsulter som kan sätta upp verktygen. 

Tänk alltid på att när ni tar in ett mer avancerat verktyg som exempelvis ServiceNow, definiera standarder för hur ni konfigurerar och utvecklar. Detta förenklar framtida utveckling och förvaltning avsevärt, man får anpassningar gjorda snabbare och billigare med ökad kvalitet.