[Shuan.zhao@bil_ta_jumphost ~]$ cat /opt/monitor.py
!/opt/python3.9/bin/python3
-- coding:utf-8 --
“”"
@File : ``
@Author : huan.zhao
@Date : 2020-10-10 16:05
@About : ‘Port monitor’
@Software: PyCharm
@Phone : +8618616803290
“”"
from future import (absolute_import, division, print_function)
metaclass = type
import boto3
import threading
import queue
import logging
import json
import shutil
import os
import sys
import ansible.constants as C
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.module_utils.common.collections import ImmutableDict
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play
from ansible.plugins.callback import CallbackBase
from ansible.vars.manager import VariableManager
from ansible import context
class ResultsCollectorJSONCallback(CallbackBase):
def init(self, *args, **kwargs):
super(ResultsCollectorJSONCallback, self).init(*args, **kwargs)
self.host_ok = {}
self.host_unreachable = {}
self.host_failed = {}
def v2_runner_on_unreachable(self, result):
host = result._host
self.host_unreachable[host.get_name()] = result
def v2_runner_on_ok(self, result, *args, **kwargs):
host = result._host
self.host_ok[host.get_name()] = result
print(json.dumps({host.name: result._result}, indent=4))
def v2_runner_on_failed(self, result, *args, **kwargs):
host = result._host
self.host_failed[host.get_name()] = result
class Monitor(object):
def init(self):
self._HostList = [
{
“Hostname”: “web01”,
“IP”: “172.16.3.10”,
“Ports”: [443, 4118, 8089]
}, {
“Hostname”: “web02”,
“IP”: “172.16.4.10”,
“Ports”: [443, 4118, 8089]
}, {
“Hostname”: “was01”,
“IP”: “172.16.3.20”,
“Ports”: [8980, 8180, 9080, 8080, 8089]
}, {
“Hostname”: “was02”,
“IP”: “172.16.4.20”,
“Ports”: [8980, 8180, 9080, 8080, 8089]
}, {
“Hostname”: “bat01”,
“IP”: “172.16.3.100”,
“Ports”: [8089]
}, {
“Hostname”: “adm01”,
“IP”: “172.16.4.150”,
“Ports”: [443, 9570, 5000, 57900, 4118, 3000, 8089]
}
]
self._q = queue.Queue()
self._result = 0
for items in self._HostList:
for Port in items["Ports"]:
self._q.put({"IP": items["IP"], "Hostname": items["Hostname"], "Port": Port})
def monitor_result(self, server, command):
context.CLIARGS = ImmutableDict(connection='smart', module_path=['/home/Shuan.zhao/ansible'], forks=1,
become=None,
become_method=None, become_user=None, check=False, diff=False, verbosity=0)
loader = DataLoader()
results_callback = ResultsCollectorJSONCallback()
inventory = InventoryManager(loader=loader, sources='/home/Shuan.zhao/ansible/myhost')
variable_manager = VariableManager(loader=loader, inventory=inventory)
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords={},
stdout_callback=results_callback,
)
play_source = dict(
name="monitor",
hosts=server,
gather_facts='no',
tasks=[
dict(action=dict(module='shell', args=command), register='shell_out')
]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
try:
tqm.run(play)
finally:
tqm.cleanup()
if loader:
loader.cleanup_all_tmp_files()
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
if results_callback.host_ok.items():
for host, result in results_callback.host_ok.items():
self._result = int(result._result['stdout'])
if results_callback.host_failed.items() or results_callback.host_unreachable.items():
logger.info("%s %s %s" % (hm, port, "connection fail"))
self._result = -1
return self._result
def post_state(self):
while True:
try:
host_info = self._q.get(block=True, timeout=1)
hm = host_info["Hostname"]
port = host_info["Port"]
ip = host_info["IP"]
cloudwatch = boto3.client('cloudwatch')
command = "netstat -tlnp|grep ':%s '|wc -l" % port
result = self.monitor_result(ip, command)
logger.info("%s %s %s" % (hm, port, result))
cloudwatch.put_metric_data(
MetricData=[
{
'MetricName': 'PortStatus',
'Dimensions': [
{
'Name': 'Instance',
'Value': '%s' % hm
},
{
'Name': 'Port',
'Value': '%s' % port
}
],
'Unit': 'None',
'Value': result
},
],
Namespace='Custom'
)
if self._q.empty():
break
except queue.Empty:
break
except Exception as e:
logger.warning(e)
break
if name == “main”:
logger = logging.getLogger()
fh = logging.FileHandler(’/tmp/monitor_port.log’)
formatter = logging.Formatter(’%(asctime)s - %(name)s - %(levelname)s - %(message)s’)
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.setLevel(logging.INFO)
count = len(os.popen('ps aux|grep monitor.py').readlines())
if count >4:
message = ','.join(os.popen('ps aux|grep monitor.py').readlines())
logger.info("%s" % message)
sys.exit(1)
threads = []
m = Monitor()
for i in range(5):
threads.append(threading.Thread(target=m.post_state()))
for t in threads:
t.start()
for t in threads:
t.join()