taosdMonitor.py 13.6 KB
Newer Older
1 2 3 4
import taos
import sys
import time
import socket
wafwerar's avatar
wafwerar 已提交
5
# import pexpect
6 7 8 9 10
import os
import http.server
import gzip
import threading
import json
wafwerar's avatar
wafwerar 已提交
11
import pickle
12 13 14 15 16 17 18

from util.log import *
from util.sql import *
from util.cases import *
from util.dnodes import *

telemetryPort = '6043'
wafwerar's avatar
wafwerar 已提交
19 20
serverPort = '7080'
hostname = socket.gethostname()
21

wafwerar's avatar
wafwerar 已提交
22 23
class RequestHandlerImpl(http.server.BaseHTTPRequestHandler):
    hostPort = hostname + ":" + serverPort
24

wafwerar's avatar
wafwerar 已提交
25 26 27
    def telemetryInfoCheck(self, infoDict=''):
        if  "ts" not in infoDict or len(infoDict["ts"]) == 0:
            tdLog.exit("ts is null!")
28

wafwerar's avatar
wafwerar 已提交
29 30
        if "dnode_id" not in infoDict or infoDict["dnode_id"] != 1:
            tdLog.exit("dnode_id is null!")
31

wafwerar's avatar
wafwerar 已提交
32 33
        if "dnode_ep" not in infoDict:
            tdLog.exit("dnode_ep is null!")
34

wafwerar's avatar
wafwerar 已提交
35 36
        if "cluster_id" not in infoDict:
            tdLog.exit("cluster_id is null!")
37

wafwerar's avatar
wafwerar 已提交
38 39
        if "protocol" not in infoDict or infoDict["protocol"] != 1:
            tdLog.exit("protocol is null!")
40

wafwerar's avatar
wafwerar 已提交
41 42
        if "cluster_info" not in infoDict :
            tdLog.exit("cluster_info is null!")
43

wafwerar's avatar
wafwerar 已提交
44
        # cluster_info  ====================================
45

wafwerar's avatar
wafwerar 已提交
46 47
        if "first_ep" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep"] == None:
            tdLog.exit("first_ep is null!")
48

wafwerar's avatar
wafwerar 已提交
49 50
        if "first_ep_dnode_id" not in infoDict["cluster_info"] or infoDict["cluster_info"]["first_ep_dnode_id"] != 1:
            tdLog.exit("first_ep_dnode_id is null!")
51

wafwerar's avatar
wafwerar 已提交
52 53
        if "version" not in infoDict["cluster_info"] or infoDict["cluster_info"]["version"] == None:
            tdLog.exit("first_ep_dnode_id is null!")
G
Ganlin Zhao 已提交
54

wafwerar's avatar
wafwerar 已提交
55 56
        if "master_uptime" not in infoDict["cluster_info"] or infoDict["cluster_info"]["master_uptime"] == None:
            tdLog.exit("master_uptime is null!")
57

wafwerar's avatar
wafwerar 已提交
58 59
        if "monitor_interval" not in infoDict["cluster_info"] or infoDict["cluster_info"]["monitor_interval"] !=5:
            tdLog.exit("monitor_interval is null!")
60

wafwerar's avatar
wafwerar 已提交
61 62
        if "vgroups_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_total"] < 0:
            tdLog.exit("vgroups_total is null!")
63

wafwerar's avatar
wafwerar 已提交
64 65
        if "vgroups_alive" not in infoDict["cluster_info"] or infoDict["cluster_info"]["vgroups_alive"] < 0:
            tdLog.exit("vgroups_alive is null!")
66

wafwerar's avatar
wafwerar 已提交
67 68
        if "connections_total" not in infoDict["cluster_info"] or infoDict["cluster_info"]["connections_total"] < 0 :
            tdLog.exit("connections_total is null!")
69

wafwerar's avatar
wafwerar 已提交
70 71
        if "dnodes" not in infoDict["cluster_info"] or infoDict["cluster_info"]["dnodes"] == None :
            tdLog.exit("dnodes is null!")
G
Ganlin Zhao 已提交
72

wafwerar's avatar
wafwerar 已提交
73
        dnodes_info = { "dnode_id": 1,"dnode_ep": self.hostPort,"status":"ready"}
G
Ganlin Zhao 已提交
74

wafwerar's avatar
wafwerar 已提交
75 76 77
        for k ,v in dnodes_info.items():
            if k not in infoDict["cluster_info"]["dnodes"][0] or v != infoDict["cluster_info"]["dnodes"][0][k] :
                tdLog.exit("dnodes info is null!")
G
Ganlin Zhao 已提交
78

wafwerar's avatar
wafwerar 已提交
79
        mnodes_info = { "mnode_id":1, "mnode_ep": self.hostPort,"role": "leader" }
80

wafwerar's avatar
wafwerar 已提交
81 82 83
        for k ,v in mnodes_info.items():
            if k not in infoDict["cluster_info"]["mnodes"][0] or v != infoDict["cluster_info"]["mnodes"][0][k] :
                tdLog.exit("mnodes info is null!")
84

wafwerar's avatar
wafwerar 已提交
85
        # vgroup_infos  ====================================
86

wafwerar's avatar
wafwerar 已提交
87 88
        if "vgroup_infos" not in infoDict or infoDict["vgroup_infos"]== None:
            tdLog.exit("vgroup_infos is null!")
G
Ganlin Zhao 已提交
89

wafwerar's avatar
wafwerar 已提交
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
        vgroup_infos_nums = len(infoDict["vgroup_infos"])

        for  index in range(vgroup_infos_nums):
            if "vgroup_id" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vgroup_id"]<0:
                tdLog.exit("vgroup_id is null!")
            if "database_name" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["database_name"]) < 0:
                tdLog.exit("database_name is null!")
            if "tables_num" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["tables_num"]!= 0:
                tdLog.exit("tables_num is null!")
            if "status" not in infoDict["vgroup_infos"][index] or len(infoDict["vgroup_infos"][index]["status"]) < 0 :
                tdLog.exit("status is null!")
            if "vnodes" not in infoDict["vgroup_infos"][index] or infoDict["vgroup_infos"][index]["vnodes"] ==None :
                tdLog.exit("vnodes is null!")
            if "dnode_id" not in infoDict["vgroup_infos"][index]["vnodes"][0] or infoDict["vgroup_infos"][index]["vnodes"][0]["dnode_id"] < 0 :
                tdLog.exit("vnodes is null!")

        # grant_info  ====================================

        if "grant_info" not in infoDict or infoDict["grant_info"]== None:
            tdLog.exit("grant_info is null!")

        if "expire_time" not in infoDict["grant_info"] or not infoDict["grant_info"]["expire_time"] > 0:
            tdLog.exit("expire_time is null!")

        if "timeseries_used" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_used"] > 0:
            tdLog.exit("timeseries_used is null!")

        if "timeseries_total" not in infoDict["grant_info"] or not infoDict["grant_info"]["timeseries_total"] > 0:
            tdLog.exit("timeseries_total is null!")
G
Ganlin Zhao 已提交
119

wafwerar's avatar
wafwerar 已提交
120
        # dnode_info  ====================================
121

wafwerar's avatar
wafwerar 已提交
122 123
        if "dnode_info" not in infoDict or infoDict["dnode_info"]== None:
            tdLog.exit("dnode_info is null!")
124

G
Ganlin Zhao 已提交
125 126
        dnode_infos =  ['uptime', 'cpu_engine', 'cpu_system', 'cpu_cores', 'mem_engine', 'mem_system', 'mem_total', 'disk_engine',
        'disk_used', 'disk_total', 'net_in', 'net_out', 'io_read', 'io_write', 'io_read_disk', 'io_write_disk', 'req_select',
wafwerar's avatar
wafwerar 已提交
127 128 129 130 131
        'req_select_rate', 'req_insert', 'req_insert_success', 'req_insert_rate', 'req_insert_batch', 'req_insert_batch_success',
        'req_insert_batch_rate', 'errors', 'vnodes_num', 'masters', 'has_mnode', 'has_qnode', 'has_snode', 'has_bnode']
        for elem in dnode_infos:
            if elem not in infoDict["dnode_info"] or  infoDict["dnode_info"][elem] < 0:
                tdLog.exit(f"{elem} is null!")
132

wafwerar's avatar
wafwerar 已提交
133
        # dnode_info  ====================================
134

wafwerar's avatar
wafwerar 已提交
135 136
        if "disk_infos" not in infoDict or infoDict["disk_infos"]== None:
            tdLog.exit("disk_infos is null!")
G
Ganlin Zhao 已提交
137

wafwerar's avatar
wafwerar 已提交
138 139 140
        # bug for data_dir
        if "datadir" not in infoDict["disk_infos"] or len(infoDict["disk_infos"]["datadir"]) <=0 :
            tdLog.exit("datadir is null!")
141

wafwerar's avatar
wafwerar 已提交
142 143
        if "name" not in infoDict["disk_infos"]["datadir"][0] or len(infoDict["disk_infos"]["datadir"][0]["name"]) <= 0:
            tdLog.exit("name is null!")
144

wafwerar's avatar
wafwerar 已提交
145 146
        if "level" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["level"] < 0:
            tdLog.exit("level is null!")
147

wafwerar's avatar
wafwerar 已提交
148 149
        if "avail" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["avail"] <= 0:
            tdLog.exit("avail is null!")
150

wafwerar's avatar
wafwerar 已提交
151 152
        if "used" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["used"] <= 0:
            tdLog.exit("used is null!")
153

wafwerar's avatar
wafwerar 已提交
154 155
        if "total" not in infoDict["disk_infos"]["datadir"][0] or infoDict["disk_infos"]["datadir"][0]["total"] <= 0:
            tdLog.exit("total is null!")
156 157


wafwerar's avatar
wafwerar 已提交
158 159
        if "logdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["logdir"]== None:
            tdLog.exit("logdir is null!")
160

wafwerar's avatar
wafwerar 已提交
161 162
        if "name" not in infoDict["disk_infos"]["logdir"] or len(infoDict["disk_infos"]["logdir"]["name"]) <= 0:
            tdLog.exit("name is null!")
163

wafwerar's avatar
wafwerar 已提交
164 165
        if "avail" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["avail"] <= 0:
            tdLog.exit("avail is null!")
166

wafwerar's avatar
wafwerar 已提交
167 168
        if "used" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["used"] <= 0:
            tdLog.exit("used is null!")
169

wafwerar's avatar
wafwerar 已提交
170 171
        if "total" not in infoDict["disk_infos"]["logdir"] or infoDict["disk_infos"]["logdir"]["total"] <= 0:
            tdLog.exit("total is null!")
172

wafwerar's avatar
wafwerar 已提交
173 174
        if "tempdir" not in infoDict["disk_infos"] or infoDict["disk_infos"]["tempdir"]== None:
            tdLog.exit("tempdir is null!")
175

wafwerar's avatar
wafwerar 已提交
176 177
        if "name" not in infoDict["disk_infos"]["tempdir"] or len(infoDict["disk_infos"]["tempdir"]["name"]) <= 0:
            tdLog.exit("name is null!")
178

wafwerar's avatar
wafwerar 已提交
179 180
        if "avail" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["avail"] <= 0:
            tdLog.exit("avail is null!")
181

wafwerar's avatar
wafwerar 已提交
182 183
        if "used" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["used"] <= 0:
            tdLog.exit("used is null!")
184

wafwerar's avatar
wafwerar 已提交
185 186
        if "total" not in infoDict["disk_infos"]["tempdir"] or infoDict["disk_infos"]["tempdir"]["total"] <= 0:
            tdLog.exit("total is null!")
187 188


wafwerar's avatar
wafwerar 已提交
189
        # log_infos  ====================================
G
Ganlin Zhao 已提交
190

wafwerar's avatar
wafwerar 已提交
191 192
        if "log_infos" not in infoDict or infoDict["log_infos"]== None:
            tdLog.exit("log_infos is null!")
193

wafwerar's avatar
wafwerar 已提交
194 195
        if "logs" not in infoDict["log_infos"] or len(infoDict["log_infos"]["logs"])!= 10:
            tdLog.exit("logs is null!")
196

wafwerar's avatar
wafwerar 已提交
197 198
        if "ts" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 10:
            tdLog.exit("ts is null!")
199

wafwerar's avatar
wafwerar 已提交
200 201
        if "level" not in infoDict["log_infos"]["logs"][0] or infoDict["log_infos"]["logs"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]:
            tdLog.exit("level is null!")
202

wafwerar's avatar
wafwerar 已提交
203 204
        if "content" not in infoDict["log_infos"]["logs"][0] or len(infoDict["log_infos"]["logs"][0]["ts"]) <= 1:
            tdLog.exit("content is null!")
205

wafwerar's avatar
wafwerar 已提交
206 207
        if "summary" not in infoDict["log_infos"] or len(infoDict["log_infos"]["summary"])!= 4:
            tdLog.exit("summary is null!")
208

G
Ganlin Zhao 已提交
209

wafwerar's avatar
wafwerar 已提交
210 211
        if "total" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["total"] < 0 :
            tdLog.exit("total is null!")
212

wafwerar's avatar
wafwerar 已提交
213 214
        if "level" not in infoDict["log_infos"]["summary"][0] or infoDict["log_infos"]["summary"][0]["level"] not in ["error" ,"info" , "debug" ,"trace"]:
            tdLog.exit("level is null!")
G
Ganlin Zhao 已提交
215

216 217 218 219 220 221 222 223 224 225 226 227 228 229
    def do_GET(self):
        """
        process GET request
        """

    def do_POST(self):
        """
        process POST request
        """
        contentEncoding = self.headers["Content-Encoding"]

        if contentEncoding == 'gzip':
            req_body = self.rfile.read(int(self.headers["Content-Length"]))
            plainText = gzip.decompress(req_body).decode()
G
Ganlin Zhao 已提交
230
        else:
231
            plainText = self.rfile.read(int(self.headers["Content-Length"])).decode()
G
Ganlin Zhao 已提交
232

233 234
        print(plainText)
        # 1. send response code and header
G
Ganlin Zhao 已提交
235
        self.send_response(200)
236 237
        self.send_header("Content-Type", "text/html; charset=utf-8")
        self.end_headers()
G
Ganlin Zhao 已提交
238

239 240
        # 2. send response content
        #self.wfile.write(("Hello World: " + req_body + "\n").encode("utf-8"))
G
Ganlin Zhao 已提交
241

242 243 244 245
        # 3. check request body info
        infoDict = json.loads(plainText)
        #print("================")
        # print(infoDict)
wafwerar's avatar
wafwerar 已提交
246
        self.telemetryInfoCheck(infoDict)
247

G
Ganlin Zhao 已提交
248
        # 4. shutdown the server and exit case
wafwerar's avatar
wafwerar 已提交
249
        assassin = threading.Thread(target=self.server.shutdown)
250 251 252 253 254
        assassin.daemon = True
        assassin.start()
        print ("==== shutdown http server ====")

class TDTestCase:
wafwerar's avatar
wafwerar 已提交
255 256 257 258 259 260 261 262
    global hostname
    global serverPort
    if (platform.system().lower() == 'windows' and not tdDnodes.dnodes[0].remoteIP == ""):
        try:
            config = eval(tdDnodes.dnodes[0].remoteIP )
            hostname = config["host"]
        except Exception:
            hostname = tdDnodes.dnodes[0].remoteIP
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    rpcDebugFlagVal = '143'
    clientCfgDict = {'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''}
    clientCfgDict["serverPort"]    = serverPort
    clientCfgDict["firstEp"]       = hostname + ':' + serverPort
    clientCfgDict["secondEp"]      = hostname + ':' + serverPort
    clientCfgDict["rpcDebugFlag"]  = rpcDebugFlagVal
    clientCfgDict["fqdn"]          = hostname

    updatecfgDict = {'clientCfg': {}, 'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''}
    updatecfgDict["clientCfg"]  = clientCfgDict
    updatecfgDict["serverPort"] = serverPort
    updatecfgDict["firstEp"]    = hostname + ':' + serverPort
    updatecfgDict["secondEp"]   = hostname + ':' + serverPort
    updatecfgDict["fqdn"]       = hostname

    updatecfgDict["monitorFqdn"]       = hostname
    updatecfgDict["monitorPort"]          = '6043'
    updatecfgDict["monitor"]            = '1'
    updatecfgDict["monitorInterval"]        = "5"
    updatecfgDict["monitorMaxLogs"]        = "10"
    updatecfgDict["monitorComp"]        = "1"

    print ("===================: ", updatecfgDict)

    def init(self, conn, logSql):
        tdLog.debug(f"start to excute {__file__}")
        tdSql.init(conn.cursor())
G
Ganlin Zhao 已提交
290

291 292 293 294 295 296 297
    def run(self):  # sourcery skip: extract-duplicate-method, remove-redundant-fstring
        tdSql.prepare()
        # time.sleep(2)
        vgroups = "30"
        sql = "create database db3 vgroups " + vgroups
        tdSql.query(sql)

wafwerar's avatar
wafwerar 已提交
298 299 300 301 302 303 304 305
        # create http server: bing ip/port , and  request processor
        if (platform.system().lower() == 'windows' and not tdDnodes.dnodes[0].remoteIP == ""):
            RequestHandlerImplStr = base64.b64encode(pickle.dumps(RequestHandlerImpl)).decode()
            cmdStr = "import pickle\nimport http\nRequestHandlerImpl=pickle.loads(base64.b64decode(\"%s\".encode()))\nclass NewRequestHandlerImpl(RequestHandlerImpl):\n    hostPort = \'%s\'\nhttp.server.HTTPServer((\"\", %s), NewRequestHandlerImpl).serve_forever()"%(RequestHandlerImplStr,hostname+":"+serverPort,telemetryPort)
            tdDnodes.dnodes[0].remoteExec({}, cmdStr)
        else:
            serverAddress = ("", int(telemetryPort))
            http.server.HTTPServer(serverAddress, RequestHandlerImpl).serve_forever()
306 307 308 309 310 311 312 313

    def stop(self):
        tdSql.close()
        tdLog.success(f"{__file__} successfully executed")

tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())