Scripting to read gateway logs

In order to populate the gateway log webpage I am sure there has to be some builtin method for parsing the first wrapper.log file into a easier data structure than the pure text file.

I am curious if its exposed and I can get to it in scripting?

The webpage just uses the system_logs.idb file; it doesn’t know or care about the wrapper log. It should be possible to configure logback to send everything (including stdout) to a file or other buffer in a format you know how to parse.

Kindling also has some code you could follow to parse Ignition’s standard wrapper log formatting.

Ah, I started going the approach of hitting the http://localhost/data/status/logs endpoint, but was struggling with getting a JSESSIONID. Any ideas on how to get that with the builtin Ignition IDP enabled?

In regards to configuring logback, you can actually configure it to push straight into a database as well with a database appender. I am just looking for something to hit the internal logs directly through a project script.

Is there any reason you would say to go with the approach of parsing the wrapper log vs the logs endpoint? Other than the fact that's probably an implementation detail lol

Parsing the wrapper log will get you more events (technically: all stdout and stderr logging from the Gateway process; practically: any bare print statements in gateway scoped scripts); however, you also face other restrictions with e.g. logger names (unless you change the formatting and write your own parsing logic). It’s really a tradeoff.

If you’re inside of Ignition already in a scripting context, you could skip the API endpoint and go directly to the ‘source’ - GatewayContext defines getLoggingManager, which returns a… GatewayLoggingManager, which defines queryLogEvents().

It looks like getLoggingManager is expecting an argument, but the javadocs only show a version with no args.

Is there potentially something I have wrong here? (Executing on a perspective button to ensure scope)

from com.inductiveautomation.ignition.gateway.model import GatewayContext
	
loggingManager = GatewayContext.getLoggingManager()
	
system.perspective.print(loggingManager)
Stacktrace
07:28:45.009 [AWT-EventQueue-0] ERROR com.inductiveautomation.ignition.client.util.gui.ErrorUtil - Error running action 'dom.onClick' on Test@D/root/Icon: Traceback (most recent call last):
  File "<function:runAction>", line 4, in runAction
TypeError: getLoggingManager(): expected 1 args; got 0

com.inductiveautomation.ignition.common.GenericTransferrableException: Traceback (most recent call last):
  File "<function:runAction>", line 4, in runAction
TypeError: getLoggingManager(): expected 1 args; got 0

	at org.python.core.Py.TypeError(Py.java:236)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:213)
	at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java:266)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:323)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:171)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
	at org.python.core.PyObject.__call__(PyObject.java:446)
	at org.python.core.PyObject.__call__(PyObject.java:450)
	at org.python.pycode._pyx110.runAction$1(<function:runAction>:6)
	at org.python.pycode._pyx110.call_function(<function:runAction>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
	at org.python.core.PyFunction.function___call__(PyFunction.java:474)
	at org.python.core.PyFunction.__call__(PyFunction.java:469)
	at org.python.core.PyFunction.__call__(PyFunction.java:464)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:839)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:821)
	at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:828)
	at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:1002)
	at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:893)
	at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:147)
	at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:74)
	at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:263)
	at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)
	at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:252)
	at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:221)
	at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at com.inductiveautomation.perspective.gateway.threading.BlockingWork$BlockingWorkRunnable.run(BlockingWork.java:58)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.common.GenericTransferrableException: TypeError: getLoggingManager(): expected 1 args; got 0
	... 33 common frames omitted

You need an instance of GatewayContext. Easiest way to do that is the IgnitionGateway.get() snippet that’s floating around on the forums.

Ahh, that does the trick.

Code for prosperity

from com.inductiveautomation.ignition.gateway import IgnitionGateway
from com.inductiveautomation.ignition.common.logging import LogQueryConfig
	
loggingManager = IgnitionGateway.get().getLoggingManager()
	
queryFilter = LogQueryConfig.newBuilder().build()
	
logResults = loggingManager.queryLogEvents(queryFilter)
	
events = logResults.getEvents()
	
system.perspective.print(events)

I did notice this documentation error for the LogQueryConfig it states the following:

A set of parameters for querying the logging system. Can be created by hand, or with LogQueryConfigBuilder.newBuilder() (the preferred method)

But it seems that the newBuilder method isn't valid for LogQueryConfigBuilder, instead it should be LogQueryConfig.newBuilder()

4 Likes