mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
cc343a4376
* Using docstrings conflicts with the standard use of docstrings * PYTHON_OPTIMIZE=2 will omit docstrings. Using docstrings makes future changes to the plugin and module code subject to the requirement that we ensure it won't be run with optimization.
94 lines
3.1 KiB
Python
94 lines
3.1 KiB
Python
# (C) 2012, Michael DeHaan, <michael.dehaan@gmail.com>
|
|
# (c) 2017 Ansible Project
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = '''
|
|
callback: log_plays
|
|
type: notification
|
|
short_description: write playbook output to log file
|
|
version_added: historical
|
|
description:
|
|
- This callback writes playbook output to a file per host in the `/var/log/ansible/hosts` directory
|
|
- "TODO: make this configurable"
|
|
requirements:
|
|
- Whitelist in configuration
|
|
- A writeable /var/log/ansible/hosts directory by the user executing Ansbile on the controller
|
|
'''
|
|
|
|
import os
|
|
import time
|
|
import json
|
|
from collections import MutableMapping
|
|
|
|
from ansible.module_utils._text import to_bytes
|
|
from ansible.plugins.callback import CallbackBase
|
|
|
|
|
|
# NOTE: in Ansible 1.2 or later general logging is available without
|
|
# this plugin, just set ANSIBLE_LOG_PATH as an environment variable
|
|
# or log_path in the DEFAULTS section of your ansible configuration
|
|
# file. This callback is an example of per hosts logging for those
|
|
# that want it.
|
|
|
|
|
|
class CallbackModule(CallbackBase):
|
|
"""
|
|
logs playbook results, per host, in /var/log/ansible/hosts
|
|
"""
|
|
CALLBACK_VERSION = 2.0
|
|
CALLBACK_TYPE = 'notification'
|
|
CALLBACK_NAME = 'log_plays'
|
|
CALLBACK_NEEDS_WHITELIST = True
|
|
|
|
TIME_FORMAT = "%b %d %Y %H:%M:%S"
|
|
MSG_FORMAT = "%(now)s - %(category)s - %(data)s\n\n"
|
|
|
|
def __init__(self):
|
|
|
|
super(CallbackModule, self).__init__()
|
|
|
|
if not os.path.exists("/var/log/ansible/hosts"):
|
|
os.makedirs("/var/log/ansible/hosts")
|
|
|
|
def log(self, host, category, data):
|
|
if isinstance(data, MutableMapping):
|
|
if '_ansible_verbose_override' in data:
|
|
# avoid logging extraneous data
|
|
data = 'omitted'
|
|
else:
|
|
data = data.copy()
|
|
invocation = data.pop('invocation', None)
|
|
data = json.dumps(data)
|
|
if invocation is not None:
|
|
data = json.dumps(invocation) + " => %s " % data
|
|
|
|
path = os.path.join("/var/log/ansible/hosts", host)
|
|
now = time.strftime(self.TIME_FORMAT, time.localtime())
|
|
|
|
msg = to_bytes(self.MSG_FORMAT % dict(now=now, category=category, data=data))
|
|
with open(path, "ab") as fd:
|
|
fd.write(msg)
|
|
|
|
def runner_on_failed(self, host, res, ignore_errors=False):
|
|
self.log(host, 'FAILED', res)
|
|
|
|
def runner_on_ok(self, host, res):
|
|
self.log(host, 'OK', res)
|
|
|
|
def runner_on_skipped(self, host, item=None):
|
|
self.log(host, 'SKIPPED', '...')
|
|
|
|
def runner_on_unreachable(self, host, res):
|
|
self.log(host, 'UNREACHABLE', res)
|
|
|
|
def runner_on_async_failed(self, host, res, jid):
|
|
self.log(host, 'ASYNC_FAILED', res)
|
|
|
|
def playbook_on_import_for_host(self, host, imported_file):
|
|
self.log(host, 'IMPORTED', imported_file)
|
|
|
|
def playbook_on_not_import_for_host(self, host, missing_file):
|
|
self.log(host, 'NOTIMPORTED', missing_file)
|