It is quite common when developing and troubleshooting integrations that a ServiceNow developer may need some logging around API access. This logging can be required in both directions - in outbound API access of some external service or when providing an API for an external service to integrate inward to your instance. In this blog post, we will examine strategies for outbound logging.
There are three levels of Outbound Web Service Logging: Basic, Elevated and All. Basic covers many of the attributes of the HTTP transaction including host, path, response status and such. Elevated includes all of Basic as well as all request headers, the query string and all response headers. All includes all of Elevated as well as the request body and the response body. The default on any HTTP request is Basic. For performance reasons, in production it is advisable to leave HTTP request logging at Basic unless and until you have a need for more information. In a development environment, do what you need to do to ensure proper functioning.
In order to adequately use Outbound web service logging, the first step is to configure it on the method in question. There are multiple ways to achieve this with various levels of surgical precision.
For an individual HTTP Method, from the record view of that method there is a Related Link called “Set HTTP Log Level”. As mentioned above, the default is Basic so if more information is required about headers or the bodies of the transaction, elevate the logging for that method here.
It is possible when calling a REST Method from script using the RestMessageV2 or SOAPMessageV2 APIs to change log level only for a single call. Both interfaces have a .setLogLevel() method that will set the log level for the duration of the life of that call.
The most brute force way is to do this via system properties. By setting You can override the log level for all outbound requests using the properties glide.outbound_http_log.override to true and then selecting a value for glide.outbound_http_log.override.level this will force every request to use the configured log level. As you can probably guess, this should be used very sparingly and never in production.
One thing you may need to do is to force certain domains to only use the Basic log level. This may happen because of privacy or security concerns about the data contained or for performance concerns if a domain is one with typically very large payloads.
A domain can be added by navigating to System Web Service > Outbound HTTP Log Domain Blacklist and creating a new record. Wildcards can be used, although only a single * can appear and only as the leftmost sub-domain position of the hostname.
You can view the transactions from System Logs > Outbound HTTP Requests. All of the available fields can be added to the list view but most common would be the hostname, path, and response status. In the case of the example, it is clear that some of these calls are receiving a 401 error. Clicking into the record shows more detail.
By looking at the request log, the upper portion contains some basic information such as the method, response status, time, total transaction time and URL. Underneath that are tabs with more information.
The source tab has information about what initiated the REST call. This can be extremely helpful when examining a REST message that is reused in multiple places, sometimes with success and sometimes with failure. This can be used to hone in what is and isn’t work.
The request tab shows the headers and the body. When using a GET or DELETE method, the request body doesn’t exist so there will be nothing to display.
The response tab is often the one that contains the key information. If configured it will contain the headers and the body of the response returned by the API call. In the example, it contains an error message explaining why this method is generating the 401 status.
This is particularly helpful in examples like the one in this post. The REST message is periodically called via a Scheduled Script Execution. A tricky debugging situation could occur when some but not all of the API calls fail. In this exact API at one point during promotion to production, we were running into rate limitations on our API calls. This was discovered by temporarily elevating the log level of the REST Message in question so that we could see the full transactions occurring. In that case, some information was contained in bodies but crucial information was also contained in the headers so it required examining all of these aspects to determine the exact problem.
Outbound HTTP logging is a useful tool for understanding the operation of your integrations. When API calls return unexpected results they can be examined directly via the logging. In production this technique should be used sparingly to avoid placing a runtime burden on mission critical systems. However, when a runtime error occurs and is causing a severe incident this logging may one day save your bacon.
In a future post we will discuss some of the available tools for generating statistical information and direct logging of inbound API calls. Thanks for reading and happy troubleshooting!