This repository has been archived by the owner on Jul 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonitor.py
130 lines (113 loc) · 4.07 KB
/
monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Monitor to report on all blockchain docker controllers"""
import copy
import json
import logging
import os
import socket
import time
import daemonize
import docker
import yaml
from websocket import create_connection
PID = "./status_monitor.pid"
CONFIG = {}
HOSTNAME = socket.gethostname()
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.WARN)
LOGGER.propagate = False
FH = logging.FileHandler("./monitor.log", "w")
FORMATTER = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")
FH.setLevel(logging.WARN)
FH.setFormatter(FORMATTER)
LOGGER.addHandler(FH)
CONFIG_FILE = open(os.path.join(os.path.dirname(__file__), 'config.yaml'))
CONFIG_FILE_ID = CONFIG_FILE.fileno()
KEEP_FDS = [FH.stream.fileno(), CONFIG_FILE_ID]
# pylint: disable=broad-except
# pylint: disable=global-statement
# pylint: disable=too-many-nested-blocks
def start_socket():
"""Start the websocket and connect to the API Server."""
reconnect = 0
while reconnect < 20:
try:
LOGGER.debug('Create connection')
web_socket = create_connection(CONFIG["url"])
LOGGER.debug('Connection established')
global HOSTNAME
LOGGER.debug('Hostname: %s', HOSTNAME)
reconnect = 0
LOGGER.debug('Register with Server')
LOGGER.debug('Registration completed')
check_docker_state(web_socket)
except Exception as exception:
LOGGER.error('Connection error occured')
LOGGER.error(exception)
LOGGER.exception("message")
reconnect += 1
LOGGER.warn('Lost connection to server')
time.sleep(5)
LOGGER.warn('Try to reconnect')
def check_docker_state(web_socket):
"""Check the current state of all supported docker
containers and report them to the websocket"""
LOGGER.info('Start check_docker_state')
client = docker.from_env()
LOGGER.info(client.containers.list())
current_docker_state = {}
previous_docker_state = {}
empty_docker_state = {
"ethereum": {
"miners": 0,
"hosts": 0,
},
"xain": {
"miners": 0,
"hosts": 0,
},
"multichain": {
"miners": 0,
"hosts": 0,
},
}
while True:
current_docker_state = copy.deepcopy(empty_docker_state)
LOGGER.debug("Checking docker containers:")
for container in client.containers.list():
LOGGER.debug(container.name)
if CONFIG["chainContainerNames"]["ethereum"] in container.name:
current_docker_state["ethereum"]["miners"] += 1
current_docker_state["ethereum"]["hosts"] += 1
if CONFIG["chainContainerNames"]["xain"] in container.name:
current_docker_state["xain"]["miners"] += 1
current_docker_state["xain"]["hosts"] += 1
if CONFIG["chainContainerNames"]["multichain"] in container.name:
current_docker_state["multichain"]["miners"] += 1
current_docker_state["multichain"]["hosts"] += 1
LOGGER.debug(str(current_docker_state))
if current_docker_state == previous_docker_state:
LOGGER.debug('Docker state stayed the same')
else:
LOGGER.debug('Docker state changed')
LOGGER.debug('Send new state to Server')
global HOSTNAME
web_socket.send(json.dumps({
"monitor": HOSTNAME,
"state": current_docker_state,
}))
previous_docker_state = copy.deepcopy(current_docker_state)
time.sleep(10)
LOGGER.info('End check_docker_state')
def main():
"""Main method to init the monitor and start the websocket."""
try:
global CONFIG
CONFIG = yaml.safe_load(CONFIG_FILE)
except Exception as exception:
LOGGER.error('Error occured while parsing config.yaml')
LOGGER.error(exception)
start_socket()
DAEMON = daemonize.Daemonize(
app="blockchainMonitor", pid=PID, action=main, keep_fds=KEEP_FDS, chdir='./')
DAEMON.start()