Best practices in servicenow

Community Alums
Not applicable

Hi , I would like to know to best practices in servicenow to avoid performance issues.

Example: writing client scripts , Business rules , schedule jobs, script includes , ACL scripts , transform scripts etc.

Kindly help.

Thanks & Regards

Chandra Singala

 

10 REPLIES 10

Hi Scott,

This may not be the right place to ask this. But I wanted to know what is the best way to delete a Custom Rule specified by the Best Practice Engine.

Vishakha
Mega Guru

Hi,

All replies are correct I just want to add more content in this:

I have compiled a list of ServiceNow best practices after going through the ServiceNow recommended best practices. This could be helpful for developers who wanted to have a quick look at best practices.

Server-side Scripting Technical Best Practices Overview

  • Make code easy to read
    • Add comments to your code
    • Use Whitespace and empty lines to make the code more readable
    • Write a simpler statement such as if/else instead of ternery because less exp. developers might work on your code and it should be easier for them to understand and manage the application.
  • Break your code into modular components for specialized functions
    • Construct reusable functions wherever you see the same or similar logic repeated
  • Variables and functions
    • Use Descriptive variable and function names
    • Store function results in a variable so that you can reuse the variable instead of calling the same function multiple times.
    • Verify the value of variable exists before using them
    • Get into the practice of returning some type of value when you create functions
    • Avoid using Eval function. The eval() function evaluates or executes an argument. Improper use of eval() opens up your code for injection attacks and debugging can be more challenging, as no line numbers are displayed with an error, for example.
    • When writing Jelly code, avoid using dynamic JEXL expressions inside the Jelly tag (or <g2:evaluate>). While the code appears to work, it affects a memory resource (called PermGen) in the Java Virtual Machine, which can lead to performance issues and even system outages over time.

For example, instead of using ${jvar_userid}, use jelly.jvar_user_id;

  • Interacting with Database
    • Avoid using complex gliderecord queries. Instead of creating a series of addQuery() and addOrCondtion(), try to use addEncodedQuery() which is easier to create and maintain.
    • Use GlideAggregate for simple record counting. If you need to count rows, you have two options: the getRowCount() method from GlideRecord, or GlideAggregate. Using GlideRecord to count rows can cause scalability issues as tables grow over time, because it retrieves every record with the query and then counts them. GlideAggregate gets its result from built-in database functionality, which is much quicker and doesn’t suffer from the scalability issues that GlideRecord does.
    • Avoid complex queries on large data sets. As your instance grows, these queries can affect performance.
    • Let the database do the work wherever possible. For example, if you want to fetch 1 active record from the list of 1 million records, generally we use addActiveQuery. It is better to add setLimit(1) as well because we anyway need only 1 record. Similarly, wherever possible, try to use the database to fetch the data than processing or filtering it at the client or server.
  • Use Self Executing Functions, wherever possible
    • A self-executing function is both declared and invoked within the same script field. Whenever writing a script that only needs to run in a single context, such as a transform map script, use this type of function.
  • Avoid Coding Pitfalls
    • Always experiment in a sandbox before trying it out on staging or production instances
    • Do not use hard-coded values such as hardcoding sys_ids in scripts. Instead use system properties and use gs.getProperty and fetch the sys_ids
    • Avoid dot walking to the sys_id of the reference field. For example, instead of current.caller_id.sys_id, use current.getValue(“caller_id”); The value of a reference field is a sys_id.
    • Use getDisplayValue, wherever possible instead of calling the getValue(“field name”). Tomorrow if the table has changed the display value, then you need to make changes in the code, which can be avoided if used getDisplayValue().

Client Scripting Technical Best Practices Overview

  • Things to consider
    • Use client scripts to validate data
    • If you have written multiple client scripts on a single table, ensure you have set the script order correctly. Lower the order value executes first.
    • Use UI policies instead of client scripts to set field attributes such as mandatory, visible, read-only.
    • Try to restrict list editing, if not required. Otherwise, if you have written client scripts or UI policies on the fields of a form, then you need to ensure that the data in these fields are managed similarly during list edit as well.
  • Run only necessary client scripts
    • Client Scripts have no Condition field. This means onLoad() and onChange() scripts run in their entirety every time the appropriate form is loaded. To avoid running time-consuming scripts unnecessarily, make sure Client Scripts perform only necessary tasks.
    • Add newValue != oldValue in onChange client scripts to run only when the newValue is different from oldValue
    • Ensure isLoading and newValue check exists in onChange Client scripts
    • Call GlideAjax only when it's necessary. So check for the values before calling the script include, as it involves a server look up. So it is best to call only when it's needed.
    • Always enclose code in functions so that the variables declared inside this block don’t collide with other client scripts.
  • Minimize Server Lookups
    • Client scripting uses either data available on the client or data retrieved from the server. Use client data as much as possible to eliminate the need for time-consuming server lookups.
    • The top ways to get information from the server are g_scratchpad, and asynchronous GlideAjax lookup.
    • The primary difference between these methods is that g_scratchpad is sent once when a form is loaded (information is pushed from the server to the client), whereas GlideAjax is dynamically triggered when the client requests information from the server.
    • GlideRecord and g_form.getReference() callback are also available for retrieving server information. However, these methods are no longer recommended due to their performance impact.
    • When using setValue() on a reference field in a form, be sure to include the display value with the value (sys_id). If you set the value without the display value, ServiceNow does a synchronous Ajax call to retrieve the display value for the record you specified. This extra round trip to the server can leave you at risk of performance issues.
  • Client scripting practices to Avoid
    • Avoid Global Client Scripts: A global client script is any client script where the selected Table is Global. Global client scripts have no table restrictions; therefore they will load on every page in the system introducing browser load delay in the process.
    • Avoid DOM Manipulation: Avoid Document Object Model (DOM) manipulation if possible. It can cause a maintainability issue when browsers are updated. The only exception is when you are in charge of the DOM: in UI Pages, and the Service Portal. Better to use GlideForm API wherever possible.

Business Rules Technical Best Practices Overview

  • Ensure the when the field is thought through when writing the BR.
  • Use Async instead of after if the values that you are updating does not need to be shown immediately to the user.
  • Use Conditions in BR: Since Business Rules are evaluated whenever an insert, update, delete or query action is made to a record, it is important to ensure you are using conditions. Conditions are evaluated before the rule is executed, if the condition is met, the script is evaluated and executed. If there is no condition, the system assumes that the Business Rule should be evaluated and executed for every action to a record on the specified table of the Business Rule.
  • Enclose the code in functions: By default, an advanced Business Rule will wrap your code in a function, and it is important that this guideline is followed. When the code is not enclosed in a function, variables and other objects are available to all other server-side scripts.
  • Prevent Recursive Business Rules: Do not use current.update() in a Business Rule script. The update() method triggers Business Rules to run on the same table for insert and update operations, potentially leading to a Business Rule calling itself over and over. When a recursive Business Rule is detected, ServiceNow stops it and logs the error in the system log.
  • Use BR to double check any critical inputs.
  • Use Script Includes instead of Global Business Rules: A global Business Rule is any Business Rule where the selected Table is Global. Any other script can call global Business Rules. Global Business Rules have no condition or table restrictions and load on every page in the system. There is no benefit to loading this kind of script on every page. Script includes load only when called.

Debugging Best Practices Overview

  • Server-side Debugging
    • Enter debug in the navigation filter to display all debugging modules.
    • System Diagnostics > Debug Log displays gs.debug(), gs.info(), gs.print() and gs.log() statements as well as server logging information and error messages at the bottom of the content frame. However, gs.print() and gs.log() are not available in scoped applications, whereas gs.debug() and gs.info() work in both scoped applications and global and are often used instead.
    • System Diagnostics > Debug Business Rule displays messages about business rules. These messages indicate which business rules are being run and when they are started (==>), finished (<==), or skipped (===). If a business rule is skipped, the failed condition is displayed.
    • System Security > Debug Security Rules places a debug icon on each field of a form. Point to the icon to see if there are any debug messages for the associated element. This module is very helpful when you are using ACLs to control access to records and fields.
    • System Security > Stop Debugging disables all debugging processes.
    • The recommended way to debug server-side scripts is to use gs.debug() statements controlled by system properties.
    • If the system property debug.MyUtil is set to false, nothing will be output to the log. If it is set to true, the debug message will be displayed. When combined with Debug Log or Debug Business Rule, this property can be used to enable or disable debug information without changing code and without impacting the user experiences of others on the system.
    • Using gs.log() (and alert() for client-side scripts) statements in scripts may seem fairly anonymous to other users at first. They do not show up on the screen and you have to know where to look to see them. The drawback to using gs.log() and alert() statements to output debug messages is that they often get left in the code.
  • Client-side Debugging
    • To debug processes on the client side, click the settings icon in the banner frame, select Developer from the menu and turn on JavaScript Log and Field Watcher. This will open the log viewer at the bottom of the window. Along with useful system information, you may choose to include jslog() statements in client scripts and UI policy scripts to help isolate and resolve issues.
    • Browser Debugging: If available, check the browser’s console log for additional debugging information. For example, the Firefox and Chrome console logs often display error messages that do not appear anywhere else. Using these logs can help speed up the development and troubleshooting processes by locating undefined objects.
  • Service Portal and External User Debugging
    • The Service Portal is often the only way external users access ServiceNow in certain applications (e.g., Customer Service). Currently, in the Service Portal interface, the section for Debug Output does not appear at the bottom of the content frame and therefore, debugging logging messages are not viewable except in the log.
    • Disable Debugging: Before you close out an update set or complete testing of the production instance, be sure to disable all server-side debugging to save log space in production.This is another good reason to use properties to control debugging in a script. It makes enabling or disabling debugging a simple task, such as when you need to validate use cases or data.

Logs and Queues Best Practices Overview

  • Review Warnings and Errors
    • Review queues and logs frequently throughout the development process to ensure correct operation.
    • System Logs > System Log > All shows all warnings and errors and other messages.
    • Each entry should either be corrected or documented as a known issue.
  • Checking Log File Sizes
    • Check the size of the log files regularly. Navigate to System Logs > Node Log File Download to review recent log files (files with names that start with localhost_log). If a log file you have been checking suddenly increases in size, there may be excessive errors, debugging may be enabled, or a new plugin may have been activated. Additional investigation is recommended.
    • Navigate to System Logs > Node Log File Download. Search for these messages, which may indicate potential issues:
      • Slow evaluate
      • Slow Business Rule
      • Recursive Business Rule
      • Compiler exception
      • Warning - large table limit
      • Extremely large result
    • If you find any of the above messages in the log file, determine the root cause of the issue, such as a poorly performing script, and correct it. For example, Extremely large result may be caused by a poorly designed query returning too many results. Likewise, a recursive Business Rule may be the result of a current.update() statement placed in a before or after Business Rule.
    • You may be able to diagnose potential performance issues by reviewing the Slow SQL Statements log found in System Diagnostics > Slow Queries. This table stores queries whose total execution time is longer than one second (1000ms). Use the data in the Total Execution Time and the Example columns to get an idea of which script may be triggering slow queries and look for potential performance improvement opportunities.
  • Checking the ECC Queue: The External Communication Channel (ECC) queue is a table primarily used to control the MID server. The MID Server aids in communication and movement of data between the ServiceNow platform and external applications, data sources, and services. Periodic review of the ECC queue can help determine if problems exist with the instance or MID Server.
  • Depending on your MID Server configuration, output records may be in the ready state for up to four minutes. If you see records in the ready state with creation times older than four minutes, check to ensure the MID Server is running and communicating with the instance. If necessary, restart the MID Server and review the logs.
  • Reviewing Event Logs: The events log records all system events that occur within ServiceNow. Sort the Processing duration in descending order (Z-A) to determine which events are taking the longest to process (the processing duration is listed in milliseconds). Events that take a long time to process could be the result of inefficient scripts or a system error.
  • You can improve overall system performance by removing unused events. From the Events list, right-click the Name column and select Group by Name. This view allows you to see how many times a particular event has been logged. Review the records for the events with the highest counts and determine what actions the event triggers. If there is no action responding to the event, consider disabling the script that logs the event.

Update Set and XML Data Transfer Best Practices Overview

  • A well-defined migration process is essential for successfully moving changes from one instance to another. The heart of the migration process is a document that identifies necessary steps to migrate update sets, as well as data not captured by update sets. It is also fairly common for more than one developer to maintain changes in multiple update sets, which increases the challenge of tracking details and getting the changes together in each instance. So a document detailing the migration procedure helps the team ensure that all changes operate as expected.
  • Update Set Application Order: In the migration procedure, create an ordered list which details how grouped update sets should be applied. As several update sets are completed, the order in which they are applied may become important to ensure dependencies are met.
  • Additional Data Migration: The migration procedure should include information about any additional data or configuration changes required to accompany the update sets. For example, some applications and processes, such as approval lookups, require data that is not captured in the update set.
  • You may find that certain items need to be updated before or after an update set is committed. The migration procedure should include instructions for:
    • Activating plugins
    • Configuring system properties or other instance-specific settings
    • Setting up MID Servers and identity servers
    • Ensuring that the target table is available
  • To occasionally migrate data from one instance to another, you can export the XML data from one instance and import it to another. This method ensures that all fields and values are transferred exactly. Migrating data in an XML file saves time for unscheduled data imports since there is no need to build an import set or a transform map.
  • Exporting and importing data in XML files is commonly used for records created in a development instance that must be migrated with the update sets as part of a migration procedure. If that is the case, consider adding a comment in the update set description so that the user installing the update set is aware that an XML import is required.
  • Import Records as XML Data: After you have successfully exported data from the source instance, you can import the XML file directly to the target instance. Importing XML does not trigger business rules or update the instance cache.
  • When performing an XML import, it is important to keep in mind that only the current record will be exported and not the records related to it. For instance, while exporting a User record (sys_user table), the groups it belongs to and the role it has been given will not be part of the XML file.

 

If it helps then please mark my answer Correct and Helpful.

Vishakha

Ganesh Pardhe
Kilo Guru

Hello Chandra,

As  I followed some best practices as follows

Client script:-
1) Do not use Glide Record in client script while using it should have a asynchronous call.
2)Do not use DOM operation in client script.
3)Do not used multiple dot walking in client script as it refers to another table so raised performance issue.
4)Set the Display Value as well as the Value on Reference fields
5)Use UI Policies instead of Client Scripts
6)Do not use Global client script.

Business rule:-
1)Avoid client callable business rule
2)do not used current.update in befor insert/update business rule.
3)used specific condition to execute business rule.
4)table should be specific while writing business rule.
5)Use GlideAggregate instead of getRowCount()
6)Avoid hardcoding values by using System Properties and Messages
7)Use Script Includes instead of Global Business Rules

Script Include:-
1)Do not used multiple script include insted of this you can use central script include and in that you can define multiple functions.
2)while writing script inculed for server side operation client callable always check so it can load Ajax processor if not you can not used this script include for client side in future.
3)used script include instead of global business rule because it triggers at specific condition.

ACL:-
1. Search for all the ACLs for that particular table you want to create on and categorise them for row level, field level types, never duplicate any ACL conditions which may turn irritating at later stages.

2. Use scripting if there is a similar ACL available, say your table and field with the role is already available, you can edit it instead of creating a new one.

3. You can also verify the base table (say check for task ACLs before writing a new ACL at incident level) and know things for parent child relation at ACL level.

Creating a new ACL will be easy for a new table but not for the existing ones. Recheck contradicting ACLs if any found, debug asap before going ahead. This would help you to make the process easy and no workarounds needed in future.

you can refer below link :

https://www.servicenowguru.com/showcase/servicenow-security-tips/

https://community.servicenow.com/community?id=community_question&sys_id=13968f25db1cdbc01dcaf3231f96...

https://docs.servicenow.com/bundle/geneva-servicenow-platform/page/administer/contextual_security/co...

https://community.servicenow.com/community?id=community_question&sys_id=52a08365db98dbc01dcaf3231f96...

https://docs.servicenow.com/bundle/kingston-security-management/page/product/planning-and-policy/con...

https://docs.servicenow.com/bundle/london-it-service-management/page/product/change-management/task/...

 

 

Transform map script:-

for transform map script follow the below link.

https://old.wiki/index.php/Import_Set_Performance_Best_Practices

 

After going throw this mark it as correct and helpful.

Thanks

Ganesh

 

Swapnil Soni1
Giga Guru

Hi,

Please go through the link-

For ACl

https://community.servicenow.com/community?id=community_blog&sys_id=f2cda2e9dbd0dbc01dcaf3231f96190d

Client Script Best Practices
  • Avoid using DOM (manipulating elements via the Document Object Model)
  • Use UI Policies instead of Client Scripts.
  • Use Asynchronous calls via getReference() or GlideAjax.
  • Use g_scratchpad to minimize server calls.
  • Set the Display Value as well as the Value on Reference fields.
  • Never use GlideRecord in Client Scripts.

For business Rule

https://docs.qualityclouds.com/qcd/business-rules-best-practices-3997741.html

For schedule jobs

https://community.servicenow.com/community?id=community_question&sys_id=2c830365dbd8dbc01dcaf3231f96...

for Script include

https://community.servicenow.com/community?id=community_article&sys_id=5c384744dbf0b34414d6fb2439961...

 

Please mark correct or helpful.

Thanks

Swapnil