# Scripting to read gateway logs

**URL:** <https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [September 23, 2022, 4:30am UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402 "2022-09-23T04:30:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 23, 2022, 4:30am UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/1 "2022-09-23T04:30:49Z")

</div>

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?

---

<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 23, 2022, 4:55am UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/2 "2022-09-23T04:55:22Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 23, 2022, 5:12am UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/3 "2022-09-23T05:12:40Z")

</div>

> [@paul-griffith](#):
>
> The webpage just uses the system\_logs.idb file;

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

---

<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 23, 2022, 2:20pm UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/4 "2022-09-23T14:20:05Z")

</div>

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`](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/gateway/logging/GatewayLoggingManager.html), which defines `queryLogEvents()`.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 23, 2022, 2:29pm UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/5 "2022-09-23T14:29:23Z")

</div>

> [@paul-griffith](#):
>
> you could skip the API endpoint and go directly to the ‘source’ - GatewayContext defines `getLoggingManager`, which returns a… [`GatewayLoggingManager`](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/gateway/logging/GatewayLoggingManager.html), 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)

```auto
from com.inductiveautomation.ignition.gateway.model import GatewayContext
	
loggingManager = GatewayContext.getLoggingManager()
	
system.perspective.print(loggingManager)

```

> **Stacktrace**
>
> ```auto
> 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
> 
> ```

---

<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 23, 2022, 3:11pm UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/6 "2022-09-23T15:11:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [September 23, 2022, 3:48pm UTC](https://forum.inductiveautomation.com/t/scripting-to-read-gateway-logs/64402/7 "2022-09-23T15:48:51Z")

</div>

Ahh, that does the trick.

### Code for prosperity

```python
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](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.20/com/inductiveautomation/ignition/common/logging/LogQueryConfig.html) 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()`
