# How to track which views a Designer user opens without modifying them?

**URL:** <https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [June 25, 2026, 9:13am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146 "2026-06-25T09:13:17Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![prasoon](https://avatars.discourse-cdn.com/v4/letter/p/ecb155/32.png) [@prasoon](https://forum.inductiveautomation.com/u/prasoon)\
**Post date:** [June 25, 2026, 9:13am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/1 "2026-06-25T09:13:17Z")

</div>

We are tracking user activity in our audit log `idaa_t_audit_event`. We have successfully implemented page visit tracking for Perspective sessions using a custom prop on the Header view with an onChange script. We can also see `resources modified` events in the audit log when a Designer user saves/edits a view.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/1/f1ab579ffcd2b27201fcc09418a6e68cde53add1.png)

When a Designer user simply **opens a view to read it** without making any changes, nothing gets logged in the audit table. We need to capture this read-only access as well.  
Is it possible ?  
Thanks.

---

<div class="post-metadata">

**Author:** ![gnguyen](https://avatars.discourse-cdn.com/v4/letter/g/41988e/32.png) [@gnguyen](https://forum.inductiveautomation.com/u/gnguyen)\
**Post date:** [June 25, 2026, 9:42am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/2 "2026-06-25T09:42:13Z")

</div>

maybe [system.util.audit | Ignition User Manual](https://www.docs.inductiveautomation.com/docs/8.3/appendix/scripting-functions/system-util/system-util-audit) when open?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 25, 2026, 2:53pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/3 "2026-06-25T14:53:32Z")

</div>

You cannot capture this. There's no event emitted by any system at any layer that you could watch for.

---

<div class="post-metadata">

**Author:** ![prasoon](https://avatars.discourse-cdn.com/v4/letter/p/ecb155/32.png) [@prasoon](https://forum.inductiveautomation.com/u/prasoon)\
**Post date:** [June 26, 2026, 2:42am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/4 "2026-06-26T02:42:53Z")

</div>

ok Thanks.

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [June 26, 2026, 3:59am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/5 "2026-06-26T03:59:36Z")

</div>

You could log this using Periscope's Client Resource feature.

> [@Musson Industrial's Embr-Periscope Module](https://forum.inductiveautomation.com/t/musson-industrials-embr-periscope-module/99047/89):
>
> Release Notice [Embr v8.1 - 2026.5.28](https://github.com/mussonindustrial/embr/releases/tag/releases%2F8.1%2F2026.5.28)[Embr v8.3 - 2026.5.28](https://github.com/mussonindustrial/embr/releases/tag/releases%2F8.3%2F2026.5.28)Client Resources + React Component Client Resources are files compiled to JavaScript that are loaded by the Perspective client on launch. There are currently two supported types: TypeScript (supports JavaScript, TypeScript, JSX, and TSX) CSS Modules All Client Resources loaded and run on page load/refresh, serving as a direct, robust alternative to Markdown Injection. They can also provide React components, which can be used via a …

All Client Resources loaded and run on page load/refresh (including in the designer).

You could create a Client Resource module that calls an API on every page load (initial load + listen for future changes) and passes Page/Session telemetry information.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 26, 2026, 8:54am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/6 "2026-06-26T08:54:01Z")

</div>

I was thinking you might also be able to hook into the designer via java to do it... We're back to hacking at things again.. haha

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 26, 2026, 9:41am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/7 "2026-06-26T09:41:11Z")

</div>

This seems to work. Run this in the script console. To roll this out automatically, call the script from a Vision Client Tag's value change script event handler; set it to an expression tag with expresion: `now(0)` to make it change once on load. You need to have Vision module installed but it doesn't need to be licensed.

Note: Claude.ai wasn't able to get it working with events, so this periodically checks every 500ms for new views opened.

```python
try:
	timer.stop()
except: pass

from java.awt import Window
from javax.swing import Timer
from java.awt.event import ActionListener

ctx = None
for window in Window.getWindows():
    if 'Designer' in window.getTitle():
        ctx = window.getContext()
        break

rem = ctx.getResourceEditManager()

# Get the openResources field
openResourcesField = None
for f in rem. __class__.getDeclaredFields():
    if f.getName() == 'openResources':
        f.setAccessible(True)
        openResourcesField = f
        break

previousPaths = set()

class OpenViewWatcher(ActionListener):
    def actionPerformed(self, e):
        try:
            current = openResourcesField.get(rem)
            currentPaths = set(str(p) for p in current)
            
            newlyOpened = currentPaths - previousPaths
            for p in newlyOpened:
                if 'perspective' in p.lower() or 'views' in p.lower():
                    print "View opened:", p
                    system.util.audit(
                    	action='designer view opened',
                    	actionTarget=p,
                    	actionValue=None,
                    	auditProfile='TestAudit',
                    	actor=system.vision.getUsername(),
                    	actorHost=system.vision.getExternalIpAddress()
                    )
            
            previousPaths.clear()
            previousPaths.update(currentPaths)
        except Exception as ex:
            print "Watcher error:", ex

watcher = OpenViewWatcher()
timer = Timer(500, watcher)
timer.setRepeats(True)
timer.start()
print "Watching for opened views (500ms poll). Run timer.stop() to cancel."

```

---

<div class="post-metadata">

**Author:** ![prasoon](https://avatars.discourse-cdn.com/v4/letter/p/ecb155/32.png) [@prasoon](https://forum.inductiveautomation.com/u/prasoon)\
**Post date:** [June 26, 2026, 11:18am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/8 "2026-06-26T11:18:51Z")

</div>

Wow, that really works thank you! This is exactly the kind of solution I was looking for.

I have one follow-up question. My goal is to understand Designer usage across our organization. We have around **52 Ignition projects** and **1,000+ Designer users** , and I'd like to track which Perspective views each user opens.

Would it be possible to capture the **Designer username** along with the view path, so the audit (or database) records something like:

- User A → Perspective/Views/Main
- User A → Perspective/Views/Reports/Daily
- User B → Perspective/Views/Production/Overview

Ultimately, I'd like to generate a report showing **which users are opening which views** and how frequently, on a per-user, per-view basis.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 26, 2026, 11:25am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/9 "2026-06-26T11:25:01Z")

</div>

This should already do exactly this. Ignore the system. **vision** functions. Imo these shouldn't be hidden in the Vision module since these equally apply to the designer. They are just Java environment functions, which the designer is itself. I assume that's where your questions come from? Ie  
`system.vision.getUsername()` gets the user logged into the designer if it's run inside the designer

Unless your 52 projects inherit from the same global project where you can add the vision client tag to (and you're not using Vision - if you're using Vision then the client tags would most certainly be overridden in each leaf project), you would have to add the vision client tag to each project indivudally

Note: I didn't check if the project name the audit record logged under was correct, it should come through properly, but you need to check that

Note also that the script would capture multiple opens while the designer is open. As in 2 records for the same view if a user opens it, closes it, and reopens it

---

<div class="post-metadata">

**Author:** ![prasoon](https://avatars.discourse-cdn.com/v4/letter/p/ecb155/32.png) [@prasoon](https://forum.inductiveautomation.com/u/prasoon)\
**Post date:** [June 26, 2026, 11:37am UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/10 "2026-06-26T11:37:57Z")

</div>

Thanks a ton, man! I really appreciate the time and effort you put into this. Your solution works perfectly.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 26, 2026, 5:30pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/11 "2026-06-26T17:30:00Z")

</div>

> [@Ignition Best Practices](https://forum.inductiveautomation.com/t/ignition-best-practices/53078/2):
>
> 1. In general, lean on the tools that are available to you, and practice saying 'no' to feature requests. Ignition is a flexible enough platform that the answer is often "yes, technically", but maintaining that one-off (that turns out to not be very important after all) is often a huge pile of technical debt that wasn't worth it.

Points at sign.  
OP, can _you_ maintain this shiny new pile of technical debt if (when) it breaks across a major or minor Ignition upgrade?

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 26, 2026, 5:55pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/12 "2026-06-26T17:55:02Z")

</div>

Maybe not, but Claude can 😛 but really, this particular thing sounds more something to gain insight from in the short term. I doubt it's of significant importance particularly over the long term.

---

<div class="post-metadata">

**Author:** ![Nol](https://avatars.discourse-cdn.com/v4/letter/n/8e8cbc/32.png) [@Nol](https://forum.inductiveautomation.com/u/Nol)\
**Post date:** [June 26, 2026, 6:00pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/13 "2026-06-26T18:00:15Z")

</div>

> [@nminchin](#):
>
> Maybe not, but Claude can

You've exceeded your token usage limit. Resets in 4hrs 59 min.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 26, 2026, 6:04pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/14 "2026-06-26T18:04:12Z")

</div>

OP's multiple threads about auditing lead me to the exact opposite impression. I feel like they've got a higher up breathing down their neck with a bunch of requirements, and they're building a house of cards inadvertently. 🤷

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 29, 2026, 6:50pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/15 "2026-06-29T18:50:12Z")

</div>

3 posts were split to a new topic: [Designer quality of life "mods"](https://forum.inductiveautomation.com/t/designer-quality-of-life-mods/116195)

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [June 29, 2026, 11:55pm UTC](https://forum.inductiveautomation.com/t/how-to-track-which-views-a-designer-user-opens-without-modifying-them/116146/16 "2026-06-29T23:55:35Z")

</div>

Nick's code is already wrapped in exception handling, so I doubt it would ever make the designer unusable if something failed, but even so, I'd recommend modifying the client tag that applies this to include some sort of way out just in case somebody expands this later and accidentally introduces a breaking change. I could imagine scenarios where faulty initial change scripts of this nature could brick the designer.

On the client tag, it could be as simple as:

```python
# Exclude at least one admin account
# ...so it can access an unmodified version of the designer if need be.
if username not in ["recoveryAdmin", ...]:
    # Apply patches

```

...and hopefully the management team that is pushing for these kinds of metrics doesn't end up using them to lay off those who understand how this client tag patch is applied.
