I would like to raise an alarm and warning inside 2 tags whenever the gateway logs have an error or warning occur, with some logic around clearing this out when no error/warnings over x time.
I'm wondering the best way to check the latest logs? I'm sure I remember a post showing how to get this through the gateway context, but haven't found it yet.
@lane.duncan I had this prepped a while ago and was going to add to it where I ended up at, but got distracted working Thanks for your reply with it though. I will update this post shortly with the above
I ended up with this, where updateGatewayLogLevelCountTags() is called every minute from a GW timer script, and the Alarm Count tag has an alarm on it for value > 0
try:
from com.inductiveautomation.ignition.gateway import IgnitionGateway
from com.inductiveautomation.ignition.common.logging import LogQueryConfig
except: pass
def getGatewayLogLevelCounts(timePeriodMin=5, logRetrievalLimit=2000):
'''Retrieves the count of each log level from the gateway logs for the last {timePeriodMin} minutes.
Queries the gateway's internal log store (the same data backing the Status > Diagnostics > Logs
page) via the unsupported/internal IgnitionGateway logging manager API, then tallies how many
events fall into each standard log level.
IMPORTANT: must run in the gateway context.
Args:
timePeriodMin (int): How many minutes back from now to query, e.g. 5 for the last 5 minutes.
logRetrievalLimit (int): Max number of log events to pull from the query. Acts as a safety
cap on a noisy window - if this limit is being hit regularly, counts will be
undercounted and the limit should be raised.
Returns:
dict: Counts keyed by level name - {'ERROR': int, 'WARN': int, 'INFO': int, 'TRACE': int, 'DEBUG': int}.
Raises:
ValueError: If the gateway log query fails for any reason (e.g. not running in gateway
scope, or the internal logging API is unavailable/changed).
'''
try:
now = system.date.now()
windowStart = system.date.addMinutes(now, -1 * timePeriodMin)
startMillis = system.date.toMillis(windowStart)
loggingManager = IgnitionGateway.get().getLoggingManager()
queryBuilder = LogQueryConfig.newBuilder()
queryBuilder.newerThan(startMillis)
queryBuilder.limitTo(logRetrievalLimit) # generous cap - raise if you're hitting the limit in a noisy 5min window
logResults = loggingManager.queryLogEvents(queryBuilder.build())
logEvents = logResults.getEvents()
logLevelCounts = {'ERROR': 0, 'WARN': 0, 'INFO': 0, 'TRACE': 0, 'DEBUG': 0}
for event in logEvents:
level = str(event.getLevel()).upper()
logLevelCounts[level] += 1
return logLevelCounts
except Exception, e:
raise ValueError("Failed to query gateway logs and update alarm count tags: %s" % str(e))
def updateGatewayLogLevelCountTags():
'''Updates the gateway alarm count tags with ERROR and WARN log counts from the last 5 minutes.
Calls getGatewayLogLevelCounts() for a 5-minute window and writes the resulting ERROR and WARN
counts to their respective alarm tags. Intended to be called on a recurring basis (e.g. from a
1-minute Gateway Timer Event) so the tags stay current with a rolling 5-minute count, dropping
back to 0 once no matching log events remain in the window.
IMPORTANT: must run in the gateway context (see getGatewayLogLevelCounts).
Tags written:
[default]System/Alarms/Gateway Application Error Count
[default]System/Alarms/Gateway Application Warn Count
'''
logLevelCounts = getGatewayLogLevelCounts(timePeriodMin=5)
errorCount = logLevelCounts['ERROR']
warnCount = logLevelCounts['WARN']
errorTagPath = "[default]System/Alarms/Gateway Application Error Count"
warnTagPath = "[default]System/Alarms/Gateway Application Warn Count"
system.tag.writeBlocking([errorTagPath, warnTagPath], [errorCount, warnCount])