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:
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:
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!:
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!


