plugin logging/debug output

plugin debug/log output

i’m trying to figure out what options are there to produce debug/log output of a custom (python) plugin. And control the amount of logging during playbook execution

display
My understanding is that action plugin is executed on the controller.
An action plugin could use display and the verbosity level

from ansible.utils.display import Display
display = Display()
display.v('this is a verbose message')
display.vv('this is a very verbose message')

Output will end up on in the controller output.
Verbosity level can be controlled by the number of -v flags (-vv, -vvv, …)

module
an module plugin is executed on the client. Interaction with the controller is via json on stdout. If verbosity is high enough, stderr is also captured and logged.

It has no access to display.

If writing a python based plugin it is advised to use

from ansible.module_utils.basic import AnsibleModule
module = AnsibleModule(...)

module has a few methods.

# this will end in journald/syslog on the client
module.log('this is a module log message') 

# this will end in journald/syslog on the client if environment variable ANSIBLE_DEBUG=1 is set
module.debug('this a module debug message')

# this will be in the controller output
module.warn('this is a module warning message')  # stored in _global_warnings
module.exit_json()  # adds warnings from _global_warnings to the returned json
# will be parsed by the controller and displayed in the output
# it will not end up in journald/syslog

Personal remark: it’s not very intuitive that log/debug is on the client and warn on the controller

logging
standard python logging is to stderr.

For module plugins, if verbosity level is high enough it is captured and logged on the controller.

the current verbosity level can be found at module._verbosity

return
a module plugin can capture all its logs and return them with the final exit_json. To control the amount of logging check module._verbosity (which is a private variable, but i found community modules that accessing it, lx_container.py)

Something along

logs = []
module = AnsibleModule(...)

def debug(msg):
  if module._verbosity > 3:
    logs.append(f"[DEBUG] {msg}")

def info(msg):
  if module._verbosity > 2:
    logs.append(f"[INFO] {msg}")

debug('debug message')
info('info message')
module.exit_json({'logs': logs})

questions
did i miss an option? What is the most ansible way?