[Tree-wide] Make chart build process predictible
[oom.git] / kubernetes / sdnc / components / sdnc-prom / resources / bin / sdnc.monitor
1 #!/usr/bin/env python2
2 # encoding: utf-8
3
4 # Copyright © 2018 Amdocs
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #       http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 import sys
19 import os
20 import json
21 import requests
22 from datetime import datetime
23
24 consul_server = "consul-server:8500"
25 message_router = "message-router:3904"
26 topic = '{{.Values.config.messageRouterTopic}}'
27 log_file='/app/monitor.log'
28 status_file='/app/.health'
29 logEnabled=False
30
31 siteName='sdnc01'
32 if os.environ.get('SDNC_IS_PRIMARY_CLUSTER', 'true') == 'false':
33     siteName='sdnc02'
34
35 debug=False
36 if len(sys.argv) > 1 and sys.argv[1] == '--debug':
37     debug=True
38
39 def get_state(healthcheck):
40     response = requests.get("http://" + consul_server + "/v1/health/checks/" + healthcheck)
41     if response.status_code != 200:
42         raise RuntimeError("HTTP " + str(response.status_code))
43     data = response.json()
44     if len(data) == 0:
45         raise RuntimeError(healthcheck + " not found")
46     if len(data) > 1:
47         raise RuntimeError("Multiple states for " + healthcheck + " found")
48
49     return data[0]
50
51
52 def log(message):
53     if logEnabled:
54         with open(log_file, 'a') as f:
55             f.write(str(datetime.now()) + " " + message + "\n")
56
57 def healthcheck(checks, failFirst=True):
58     if len(checks) == 0:
59         return True
60
61     for check in checks:
62         if type(check) is list:
63             passing = healthcheck(check, False)
64         else:
65             state = get_state(check)
66             status = state['Status']
67             passing = status == "passing" or status == "warning"
68             log(check + " " + status)
69             if debug:
70                 if status == "passing":
71                     color = "\033[32m" # green
72                 elif status == "warning":
73                     color = "\033[33m" # yellow
74                 else:
75                     color = "\033[31m" # red
76                 print check, color + status + "\033[0m"
77                 if not passing:
78                     print "\tCause:", state['Output']
79
80
81         if passing:
82             if not failFirst:
83                 # found a passing check so can stop here
84                 return True
85         else:
86             if failFirst:
87                 # found a failing check so can stop here
88                 return False
89
90     return failFirst
91
92
93 try:
94     with open("/app/config/healthchecks.json") as f:
95         checks = json.load(f)
96
97     try:
98         with open(status_file) as f:
99            previous_result = f.read()
100     except IOError:
101         # file doesn't exist
102         previous_result = 'unknown'
103
104     if healthcheck(checks):
105         result = "healthy"
106     else:
107         result = "unhealthy"
108
109     print result
110
111     # save current result to file
112     with open(status_file, 'w') as f:
113         f.write(result)
114
115     if previous_result != 'unknown' and result != previous_result:
116         payload = { 'type' : 'health-change', 'status': result, 'site': siteName, 'deployment': '{{.Values.config.deployment}}', 'timestamp': str(datetime.now())  }
117         log("Posting event " + str(payload))
118         try:
119             requests.post("http://" + message_router + "/events/" + topic, data=json.dumps(payload), headers={ 'Content-Type' : 'application/json' } )
120         except Exception:
121             # events are best-effort
122             pass
123
124 except Exception as e:
125     sys.exit(str(e))