QPyLib logging and syslog

Logging overview

The QRadar App Python Library QPyLib has several functions related to logging. These functions provide a convenient wrapper around functionality provided by the standard Python logging module.

Typically, you use QPyLib logging like this:

  • Call qpylib.create_log() as part of your app initialization.
  • Then call qpylib.log() wherever you want to log a message in your Python code.

By default, QPyLib log messages have two destinations:

  • logging.handlers.RotatingFileHandler writes to a file named app.log in the app’s store/log directory.
  • logging.handlers.SysLogHandler sends messages to the QRadar syslog server.

Syslog logging

The syslog messages generated by QPyLib logging appear in the QRadar event processing pipeline. If your app does a lot of QPyLib logging, you may not want those messages to be processed as QRadar events.

If you want to prevent your app from sending QPyLib log messages to syslog, you have a number of options.

The recommended approach is to disable the creation of SysLogHandler when you initialize QPyLib logging.

QPyLib 2.0.5 added a syslog_enabled argument (default value True) to the qpylib.create_log() function. By calling qpylib.create_log(False), QPyLib logging is configured to use RotatingFileHandler only.

A problem with this approach is that the syslog_enabled argument is a new feature that is only available in versions of the app base image that contain QPyLib 2.0.5 or later. If your app is deployed on a QRadar system where the base image contains an earlier version of QPyLib, the call qpylib.create_log(False) will result in a Python TypeError when the app container is started.

In the future, older base image versions will be deprecated and removed, and all available base images will contain QPyLib 2.0.5 or later. In the meantime, by incorporating the following code snippet into your app’s initialization code, you can ensure that QPyLib logging to syslog is disabled, regardless of which version of QRadar your app is deployed on.

from packaging import version
from qpylib import qpylib, log_qpylib, __version__

def suppress_syslog():
    return None

if version.parse(__version__) >= version.parse('2.0.5'):
    qpylib.create_log(False)
else:
    log_qpylib._get_address_for_syslog = suppress_syslog
    qpylib.create_log()

The code performs a QPyLib version check using the standard Python packaging.version module.

If the version is 2.0.5 or greater, the call to qpylib.create_log(False) can proceed.

Otherwise, the code overrides a function from log_qpylib, causing the subsequent execution of qpylib.create_log() to omit the creation of SysLogHandler. Overriding another module’s function is not best practice software engineering, but it provides the simplest workaround solution for this particular problem.

Disabling syslog logging - other options

  • You can implement your own logging solution, instead of using QPyLib’s logging functions. This gives you the flexibility of a custom solution, but at the expense of writing and maintaining extra code.
  • You can bundle a 2.0.5 or later version of QPyLib with your app, which ensures that your app is built with support for qpylib.create_log(False). This approach is not recommended, because your app is tied to the bundled version of QPyLib and will not benefit from future QPyLib updates.