# Contextual Logger Names

**URL:** <https://forum.inductiveautomation.com/t/contextual-logger-names/116848>\
**Category:** Ignition\
**Tags:** ignition81, scripting, perspective\
**Created:** [August 20, 2026, 5:04pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848 "2026-08-20T17:04:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dreeves](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dreeves](https://forum.inductiveautomation.com/u/dreeves)\
**Post date:** [August 20, 2026, 5:04pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/1 "2026-08-20T17:04:57Z")

</div>

# 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](https://inductiveautomation.com/exchange/2981)** 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 the `self` parameter 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 the `Logger`class, 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 (assuming `reference` is 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.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/d/2d19439a80f0fac46152ac2651b72e09593466ac.png)

# Logging Levels

Utilizing the `Logging`class 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_

 ![LogLevel1](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/2/32c2b80bced390faa1bf7690b78db80f43ba3ef2.png)

 ![LogLevel2](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/7/97b9a7b9e8bbcb884967390a8b78fd78161d6ad0.png)

# Perspective UI

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/7/6/76d5e6242223b513712930c1060c599780ea1ae8.png)

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!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 20, 2026, 5:16pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/2 "2026-08-20T17:16:37Z")

</div>

Your hierarchy implies that you have substantial code written directly in events. I have long advocated that event scripts be one-liners that delegate to the project library, for numerous reasons. In other words, there should be no code in any event script that needs its own logger, and I would discourage anyone from going down this path.

Each project library script can have one or more logger "constants" established outside any functions for efficient use throughout. I recommend the following at the top of each library script to automate logger names:

```python
logger = system.util.getLogger(system.util.getProjectName() + ':' + system.reflect.getModulePath())

```

That latter relies on my Integration Toolkit, but you can achieve the same accessing the Jython frame.

(My toolkit also includes efficient conversion of jython exceptions to java throwables, to produce nice backtraces with java's loggers. See my [later.py](https://www.automation-pros.com/ignition/later.py) script for a pure jython implementation.)

---

<div class="post-metadata">

**Author:** ![Lynn\_Martineau](https://avatars.discourse-cdn.com/v4/letter/l/f1d935/32.png) [@Lynn\_Martineau](https://forum.inductiveautomation.com/u/Lynn_Martineau)\
**Post date:** [August 20, 2026, 5:24pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/3 "2026-08-20T17:24:48Z")

</div>

> [@pturmel](#):
>
> I recommend the following at the top of each library script

Thanks @pturmel. standards and a little discipline go a long way to help manage and maintain applications.

---

<div class="post-metadata">

**Author:** ![dreeves](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dreeves](https://forum.inductiveautomation.com/u/dreeves)\
**Post date:** [August 20, 2026, 8:49pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/4 "2026-08-20T20:49:23Z")

</div>

> [@pturmel](#):
>
> Your hierarchy implies that you have substantial code written directly in events

Not necessarily, you can almost think of this as a short-hand stack trace. You could still have the single line in the OnStartup script example, you would just pass `self` to the library script (and subsequently the `ReferenceConstructor` class) to generate the contextual path.

For example, the OnStartup script calls a function to do "something" based on data in the view. That same function is also called by a user pressing a button after changing something. Without some additional logging to give context (or function abstraction), how do you know which call site is the culprit just looking at the logs?

> [@pturmel](#):
>
> (My toolkit also includes efficient conversion of jython exceptions to java throwables, to produce nice backtraces with java's loggers. See my [later.py](https://www.automation-pros.com/ignition/later.py) script for a pure jython implementation.)

Thanks for this BTW, I have used pieces here and there but I have never dug deep.

---

<div class="post-metadata">

**Author:** ![dreeves](https://avatars.discourse-cdn.com/v4/letter/d/f14d63/32.png) [@dreeves](https://forum.inductiveautomation.com/u/dreeves)\
**Post date:** [August 20, 2026, 8:53pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/5 "2026-08-20T20:53:22Z")

</div>

I don't disagree but it's not always that simple unfortunately. I had the "pleasure" of working with an off-shore contractor team on a big project and getting them to adhere to any kind of standard was almost impossible.

It's actually what sparked some of this, because at least they could just throw this one line in instead of having random logger names all over the place that didn't even make sense.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 20, 2026, 9:19pm UTC](https://forum.inductiveautomation.com/t/contextual-logger-names/116848/6 "2026-08-20T21:19:10Z")

</div>

> [@dreeves](#):
>
> how do you know which call site is the culprit just looking at the logs?

Perspective is heavily instrumented with MDC annotations that show up in the logs. Exposes the container hierarchy and the backtraces will show additional information.

The container hierarchy notation is not terribly user-friendly--parsing and expanding on that would be particularly useful.
