About
After getting tired of wasting time finding and naming loggers, I embarked on a project to standardize and contextualize logger names. The overall goal was to have a standard naming convention to quickly pinpoint where the logs were coming from. Alas, I have finally dedicated time to creating a proper project to share with the community. You can find the exchange resource here and a detailed explanation below.
It should be noted this is a fairly brittle implementation due to heavy reliance on stack traces. Ignition 8.3 stack traces had slight syntactical differences compared to 8.1. This project was built using 8.3.2 with modified scripts from my original 8.1 version. I have not fully tested it with 8.1, but I made modifications with the intent of being backwards compatible.
Verified scopes
The scripts have been tested against the following categories and are included in the project:
- Gateway events
- Message handler
- Scheduled script
- Tag change
- Timer script
- Shutdown
- Startup
- Update
- Perspective session events
- SessionKeyEvent
- Session message
- Authentication challenge
- Page Startup
- Shutdown
- Startup
- Perspective views and components
- OnStartup*
- OnShutdown*
- Properties*
- Property change event*
- Message handler*
- WebDev endpoints
- Get/Post/Put/Delete/Head/Options/Patch/Trace
- Project library scripts
- Function
- Class
- Class Method
Anything denoted with '*' is a special case where sometimes there is no way to determine an exact path based off a reference object and stack trace. This is especially important for perspective due to the call stack. For example, if additional context is not passed to the ReferenceConstructor class, a view's OnStartup script would only resolve to the view's name. There is no way to know we are in the view's OnStartup scope.
Perspective Accelerometer, Barcode, Bluetooth, NFC events should be identifiable by the stack trace method name, but I did not have a mobile device to test with at the time.
Classes
ReferenceConstructor - Used to construct the path based off a reference object and/or stack trace. The init parameters are described below:
reference- A reference to the object to be used for introspection. This should be theselfparameter when called from perspective or a class.context- Additional context to be appended to the end of the generated path as a new node.offsetStack- The number of stacks that will be ignored at the end of the stack trace. Use this to account for any inheritance/misdirection patterns. For example, when calling theLoggerclass, it automatically offsets the stack by 1 because of the call chain.expandPerspectivePath- Retrieves the full designer path for both the view and the component it was called from (assumingreferenceis the perspective object)
Logger- Wrapper class on the built-in system.util.getLogger object. It also inherits the ReferenceConstructor class to generate the logger's name. Additional parameters outside the inherited class are described below:
echo- If true, will print the log to the console (useful for script console debugging)
Path Generation
Below is the expected return format for the different reference object source types.
Any white space will be replaced with a "_" in the returned path to make it play nice with the log viewer.
- Perspective View -
{ProjectName}.Perspective.{ViewName} - Perspective Component -
{ProjectName}.Perspective.{ViewName}.{Component} - Project Script Function -
{ProjectName}.Scripting.{ScriptPath}.{ScriptName} - Project Script Class -
{ProjectName}.Scripting.{ScriptPath}.{ClassName} - Gateway Event -
{ProjectName}.Scripting.{event type}_{ResourceName} - Session Event -
{ProjectName}.Perspective.{event type} - WebDev -
{ProjectName}.WebDev.{WebDevPath}_{method} - String -
{ProjectName}.{reference}
Here is an example of what it looks like on the gateway logs page. Hoving over the name will give you the full path, in this case, to the view.

Logging Levels
Utilizing the Loggingclass provides some additional benefits when configuring loggers in the gateway. Since the names are structured, you can easily change the log levels based on the hierarchy. In the example below, I changed the logging level for all the children by just changing the parent contextual-logger-names.Perspective.Views.ContextualLoggerNames
Perspective UI
I built this simple interface to do my testing in 8.3. It uses a couple of methods and message handlers to capture the context and capture the log. You can expand the sub view to easily see what name it generated, and the FULL stack trace.
I will do my best to keep this updated and look forward to the community's feedback and ideas!


