taosdMonitor.py 13.8 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
        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!")
S
Shengliang Guan 已提交
97
            if "tables_num" not in infoDict["vgroup_infos"][index]:
wafwerar's avatar
wafwerar 已提交
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
                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!")

M
Minglei Jin 已提交
114
        if "timeseries_used" not in infoDict["grant_info"]:# or not infoDict["grant_info"]["timeseries_used"] > 0:
wafwerar's avatar
wafwerar 已提交
115 116 117 118
            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
        'req_select_rate', 'req_insert', 'req_insert_success', 'req_insert_rate', 'req_insert_batch', 'req_insert_batch_success',
S
Shengliang Guan 已提交
128
        'req_insert_batch_rate', 'errors', 'vnodes_num', 'masters', 'has_mnode', 'has_qnode', 'has_snode']
wafwerar's avatar
wafwerar 已提交
129 130 131
        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

M
Minglei Jin 已提交
194
        if "logs" not in infoDict["log_infos"] or len(infoDict["log_infos"]["logs"]) < 8:#!= 10:
wafwerar's avatar
wafwerar 已提交
195
            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
    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)
S
Shengliang Guan 已提交
297 298 299 300
        sql = "create table db3.stb (ts timestamp, f int) tags (t int)"
        tdSql.query(sql)
        sql = "create table db3.tb using db3.stb tags (1)"
        tdSql.query(sql)
301

wafwerar's avatar
wafwerar 已提交
302 303 304 305 306 307 308 309
        # 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()
310 311 312 313 314 315 316 317

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

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