FujiForty - It's Logging Season

District-Tawau_Sabah_Logging-Trucks-01.jpg

As I promised, much of the FujiForty series is going to be dedicated to the new application scoping concepts. Today we’re going to look at the change to application logging. Most of what ServiceNow scripters log are for troubleshooting purposes. I’ve seen extreme cases where 30% of more of a script was just for logging so the developer could inspect variable values and decisions on “if” statements. The introduction of the JavaScript Debugger in Dublin has helped drastically reduce the need for this much logging. There are still cases where you really do want to write to the system log or just get a debug trace output.

Many developers, including myself, have built custom logging classes that can control logging levels based on a flag or property setting. This allows you to still pepper your scripts with log statements but only actually write them out when you need them. It also prevents you from flooding a log table in production constantly when no one is ever going to read it. 

Fuji provides a new logging API to do all of this for us so we don’t have to worry about writing our own.

First we need to cover the major change that will impact your existing scripts and your keyboard muscle memory. For scoped applications your friend “gs.[log | logWarning | logError | print]” no longer exist. They can still be used in the global scope. The new logging APIs will also run from the global scope so it's best to just get in the habit of always using them.

The new scoped logging API is worth a read, but I’ll provide an overview.

Replacing the legacy log methods are:

  • gs.error - critical event that should always be logged
  • gs.warn - less critical event but might be important
  • gs.info - informational events
  • gs.debug - only output when I need to troubleshoot

Each method accepts message and parameter values passed to it. This allows you to easily pass dynamic values into the message in a cleaner fashion.

Instead of:

gs.info(“This is an important message from  + myApp +  for user  + myUser);

You can use:

gs.info(“This is an important message from {0} for user {1}", myApp, myUser);

The log methods responds to the the application logging verbosity level that is defined in a system property. The name of the property is my_scope_name.logging.verbosity. You’ll notice that when you create the property while in your application, the scope name is automatically applied to the property name. I create these as choice property types with the choice options of [error, warn, info, debug]. It would be nice if ServiceNow just created the property for us whenever we create a new app so we don’t have to remember to do it manually. I’m sure they’ll get to it at some point.

I suggest that you always create this property so it's available when you need it. If you do not have the property, logging will default to the info verbosity level which could result in more logging than you expect.

Based on the verbosity property the following log methods will write to the log.

  • Error: Log only error events
  • Warn: Log error and warn events
  • Info: Log error, warn, and info events
  • Debug: Log all events (use should be restricted to troubleshooting only, then revert to info or more limited level)

Since this is a system property, all user sessions processing the scripts will log based on the property level. This can be helpful if you need to capture log events of multiple users and review them. 

There's also a module that will take you directly to application logs so you don't have to filter through the entire system log records.

 

 

Most times you just need to enable debug logging for your session. This can be accomplished by using the new “Enable Session Debug” related link from the application record. This enables console logging for the current user session only. It also captures all logging events (error, warn, info, debug) without needing to change the system verbosity property.
All log events for that application will now be displayed on screen, saving you the hassle of jumping back and forth to the log table list. 

 

As with other session debugging that have been around for a while, this also works through impersonation. Just enable the application session debugging before impersonating another user.

One last thing to note, when running a script through Background Scripts module, all events are displayed regardless of verbosity property or session debugging.