# My Perspective Logger Component

**URL:** <https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498>\
**Category:** Ignition\
**Tags:** ignition80, perspective\
**Created:** [September 8, 2020, 10:08pm UTC](https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498 "2020-09-08T22:08:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kjordan](https://avatars.discourse-cdn.com/v4/letter/k/6f9a4e/32.png) [@kjordan](https://forum.inductiveautomation.com/u/kjordan)\
**Post date:** [September 8, 2020, 10:08pm UTC](https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498/1 "2020-09-08T22:08:54Z")

</div>

So, I’m relatively new to ignition, but have enough experience to know that logging can be difficult at times, at least in perspective apps. So, I made a logger component that I thought I’d share in case it helps someone else (or in case people can tell me how I’ve over engineered another problem 😅):

The startup script for the component instantiates a singleton object which stores a reference to the component (sort of a singleton. I used a borg pattern I found mentioned around the web in a few places. I’m new to Python _cough_ I mean Jython too). Here’s my script file, simply named `logger`:

```auto
import datetime

debugTagPath = "[default]Debug_" + system.util.getProjectName()
loggerDockName = "Logger"

class Borg:
	_shared_state = {}
	def __init__ (self):
		self. __dict__ = self._shared_state

class Logger(Borg):
	def __init__ (self, componentInstance = None):
		Borg. __init__ (self)
		if componentInstance:
			self.componentInstance = componentInstance
	def log(self, msg):
		if hasattr(self, 'componentInstance') and system.tag.exists(debugTagPath) and system.tag.readBlocking([debugTagPath])[0].value == True:
			self.componentInstance.params.text = logTimestamp() + str(msg) + "\n" + self.componentInstance.params.text
	 		system.perspective.openDock(loggerDockName)

def log(msg):
  Logger().log(msg)
  
def logTimestamp():
	return '[' + datetime.datetime.now().strftime("%m/%d/%Y %X.%f")[:-3] + ']: '

```

And here’s the startup script for the logger component:

```auto
def runAction(self):
	"""
	Method that will run whenever the selected event fires.

	Arguments:
		self: A reference to the component that is invoking this function.
	"""
	logger.Logger(self)

```

It also makes use of boolean memory tags to check if it’s in a debug environment or not. My project has several copies for versioning, some of which are dev or testing, and some are production. So the boolean memory tags are named `Debug_<project_name>`, so that a project can check if it should produce logs.

The component itself is nothing special, just a text area with text bound to `view.params.text`, as well as `Clear` and `Close` buttons

I mounted the component in the south dock, with `display: onDemand` and `handle: hide`. Then, I can place `logger.log('Hey folks!')` somewhere in a script, and Voila!:

 ![Screen Shot 2020-09-08 at 5.59.36 PM](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/f/8f38aca7fd1c894614d1372b3958c89c560dfc1e.png)

It’s still nowhere near as lean and unobtrusive as console.log statements, but it has helped me quite a bit so far, so I thought I’d share!

---

<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:** [September 8, 2020, 10:47pm UTC](https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498/2 "2020-09-08T22:47:21Z")

</div>

Not to discount the (very cool!) engineering effort, but it’s worth pointing out that `system.perspective.print` will end up as a `console.log` if you don’t specify a different target parameter.

---

<div class="post-metadata">

**Author:** ![kjordan](https://avatars.discourse-cdn.com/v4/letter/k/6f9a4e/32.png) [@kjordan](https://forum.inductiveautomation.com/u/kjordan)\
**Post date:** [September 9, 2020, 2:16pm UTC](https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498/3 "2020-09-09T14:16:34Z")

</div>

Thank you! I knew there must be something like this 😄

On that note, I feel like this command should be a little more prominent in the documentation, as console logs are the most commonly used debugging tool in web development. I may have missed it, but I didn’t see it mentioned in the Inductive University videos I watched.

Also, this command doesn’t appear in the top results for either `log`, `logging`, or even for `print` in the ignition docs. This may account for the fact that neither I nor my colleagues were aware of this command. Either that or we experienced some kind of communal blindspot 😂

I want to add that the Inductive University lessons have been a fantastic resource!

Thanks again!

---

<div class="post-metadata">

**Author:** ![scottmwyant](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/scottmwyant/32/66369_2.png) [@scottmwyant](https://forum.inductiveautomation.com/u/scottmwyant)\
**Post date:** [September 21, 2022, 4:08pm UTC](https://forum.inductiveautomation.com/t/my-perspective-logger-component/38498/4 "2022-09-21T16:08:24Z")

</div>

@kjordan, I know this is from a few years ago, but it’s exactly what I was looking to implement. Thanks for sharing.

Double cool because I haven’t spent much time looking through the `system.perspective.*` api yet.  
@paul-griffith, would you guys consider adding the ability to have a component be a log sink?
