-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcheck_docker.py
More file actions
161 lines (127 loc) · 5.34 KB
/
check_docker.py
File metadata and controls
161 lines (127 loc) · 5.34 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python
import argparse
import json
import requests_unixsocket
import sys
nagios_output_state = {
'OK': 0,
'WARNING': 1,
'CRITICAL': 2,
'UNKNOWN': 3,
}
class Docker(object):
def __init__(self, args):
self.docker_socket = args.docker_socket.replace('/', '%2F')
self.enable_performance_data = args.enable_performance_data
self.perf_data = list()
self.summary = list()
self.check_status = 'OK'
def __request(self, path):
session = requests_unixsocket.Session()
response = session.get('http+unix://%s/%s' % (self.docker_socket, path))
return response
def get_all_container_names(self):
response = self.__request('containers/json')
names = list()
for container in response.json():
names.append(container['Names'][0].replace('/', ''))
return names
def get_all_stats_by_name(self):
stats = list()
for container in self.get_all_container_names():
response = self.__request('containers/%s/stats?stream=false' % container)
stats.append(response.json())
return stats
def get_common_stats_by_name(self):
parsed_stats = dict()
for stats in self.get_all_stats_by_name():
parsed_stats[stats['name'].replace('/', '')] = dict(
cpu_percent=self.__get_cpu_percent(stats),
memory_percent=self.__get_memory_percent(stats),
memory_usage_bytes=self.__get_memory_usage(stats),
net_input_bytes=self.__get_net_io_bytes(stats)[0],
net_output_bytes=self.__get_net_io_bytes(stats)[1],
block_input_bytes=self.__get_block_io_bytes(stats)[0],
block_output_bytes=self.__get_block_io_bytes(stats)[1],
)
return parsed_stats
def __get_cpu_percent(self, stats):
# via https://github.com/docker/docker/blob/e884a515e96201d4027a6c9c1b4fa884fc2d21a3/api/client/container/stats_helpers.go#L199-L212
cpu_stats = stats['cpu_stats']
precpu_stats = stats['precpu_stats']
cpu_delta = float(cpu_stats['cpu_usage']['total_usage'] - precpu_stats['cpu_usage']['total_usage'])
system_delta = float(cpu_stats['system_cpu_usage'] - precpu_stats['system_cpu_usage'])
percent = 0.0
if system_delta > 0.0 and cpu_delta > 0.0:
percent = (cpu_delta / system_delta) * len(cpu_stats['cpu_usage']['percpu_usage']) * 100.0
return round(percent, 2)
def __get_memory_usage(self, stats):
return stats['memory_stats']['usage']
def __get_memory_percent(self, stats):
# via https://github.com/docker/docker/blob/e884a515e96201d4027a6c9c1b4fa884fc2d21a3/api/client/container/stats_helpers.go#L109
percent = (float(stats['memory_stats']['usage']) / float(stats['memory_stats']['limit'])) * 100.0
return round(percent, 2)
def __get_net_io_bytes(self, stats):
# via https://github.com/docker/docker/blob/e884a515e96201d4027a6c9c1b4fa884fc2d21a3/api/client/container/stats_helpers.go#L226-234
if not 'networks' in stats:
return 0, 0
rx = 0
tx = 0
for interface, network in stats['networks'].items():
rx += network['rx_bytes']
tx += network['tx_bytes']
return rx, tx
def __get_block_io_bytes(self, stats):
# via https://github.com/docker/docker/blob/e884a515e96201d4027a6c9c1b4fa884fc2d21a3/api/client/container/stats_helpers.go#L214-224
read = 0
write = 0
for stat in stats['blkio_stats']['io_service_bytes_recursive']:
if stat['op'] == 'Read':
read += stat['value']
elif stat['op'] == 'Write':
write += stat['value']
return read, write
def __add_performance_data(self, docker_stats):
for container, stats in docker_stats.items():
for name, value in stats.items():
self.perf_data.insert(
0,
'%s=%s;;;;' % (
'%s.%s' % (container, name),
value
)
)
def check_stats(self):
docker_stats = self.get_common_stats_by_name()
self.summary.append(json.dumps(docker_stats, indent=4, sort_keys=True))
self.__add_performance_data(docker_stats)
self.__set_status()
self.__nagios_output()
def __set_status(self):
self.check_status = 'OK'
def __nagios_output(self):
output = self.check_status
if self.summary:
output += '\n\n%s' % '\n'.join(self.summary)
if self.enable_performance_data:
output += '\n\n|%s' % (' '.join(self.perf_data))
print(output)
sys.exit(nagios_output_state[self.check_status])
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Return result of a check to docker stats with nagios format')
parser.add_argument(
'-s', '--docker-socket',
help='path to docker socket file',
type=str,
default='/var/run/docker.sock',
)
parser.add_argument(
'-a', '--enable-performance-data',
help='enable output performance data',
action='store_true',
default=False
)
args = parser.parse_args()
docker = Docker(args)
docker.check_stats()