chart.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #-*- coding:utf-8 -*-
  2. # Copyright 2017 Xiaomi, Inc.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import urllib
  16. import json
  17. from flask import request, g, abort, render_template
  18. from rrd import app
  19. from rrd.consts import GRAPH_TYPE_KEY, GRAPH_TYPE_HOST
  20. from rrd.utils.rrdgraph import merge_list
  21. from rrd.utils.rrdgraph import graph_history
  22. from rrd.model.tmpgraph import TmpGraph
  23. @app.route("/chart", methods=["POST",])
  24. def chart():
  25. endpoints = request.form.getlist("endpoints[]") or []
  26. counters = request.form.getlist("counters[]") or []
  27. graph_type = request.form.get("graph_type") or GRAPH_TYPE_HOST
  28. id_ = TmpGraph.add(endpoints, counters)
  29. ret = {
  30. "ok": False,
  31. "id": id_,
  32. "params": {
  33. "graph_type": graph_type,
  34. },
  35. }
  36. if id_: ret['ok'] = True
  37. return json.dumps(ret)
  38. @app.route("/chart/big", methods=["GET",])
  39. def chart_big():
  40. return render_template("chart/big_ng.html", **locals())
  41. @app.route("/chart/embed", methods=["GET",])
  42. def chart_embed():
  43. w = request.args.get("w")
  44. w = int(w) if w else 600
  45. h = request.args.get("h")
  46. h = int(h) if h else 200
  47. return render_template("chart/embed.html", **locals())
  48. @app.route("/chart/h", methods=["GET"])
  49. def multi_endpoints_chart_data():
  50. if not g.id:
  51. abort(400, "no graph id given")
  52. j = TmpGraph.get(g.id)
  53. if not j:
  54. abort(400, "no such tmp_graph where id=%s" %g.id)
  55. counters = j.counters
  56. if not counters:
  57. abort(400, "no counters of %s" %g.id)
  58. counters = sorted(set(counters))
  59. endpoints = j.endpoints
  60. if not endpoints:
  61. abort(400, "no endpoints of %s" %(g.id,))
  62. endpoints = sorted(set(endpoints))
  63. ret = {
  64. "units": "",
  65. "title": "",
  66. "series": []
  67. }
  68. c = counters[0]
  69. ret['title'] = c
  70. query_result = graph_history(endpoints, counters[:1], g.cf, g.start, g.end)
  71. series = []
  72. for i in range(0, len(query_result)):
  73. x = query_result[i]
  74. try:
  75. xv = [(v["timestamp"]*1000, v["value"]) for v in x["Values"]]
  76. serie = {
  77. "data": xv,
  78. "name": query_result[i]["endpoint"],
  79. "cf": g.cf,
  80. "endpoint": query_result[i]["endpoint"],
  81. "counter": query_result[i]["counter"],
  82. }
  83. series.append(serie)
  84. except:
  85. pass
  86. sum_serie = {
  87. "data": [],
  88. "name": "sum",
  89. "cf": g.cf,
  90. "endpoint": "sum",
  91. "counter": c,
  92. }
  93. if g.sum == "on" or g.sumonly == "on":
  94. sum = []
  95. tmp_ts = []
  96. max_size = 0
  97. for serie in series:
  98. serie_vs = [x[1] for x in serie["data"]]
  99. if len(serie_vs) > max_size:
  100. max_size = len(serie_vs)
  101. tmp_ts = [x[0] for x in serie["data"]]
  102. sum = merge_list(sum, serie_vs)
  103. sum_serie_data = []
  104. for i in range(0, max_size):
  105. sum_serie_data.append((tmp_ts[i], sum[i]))
  106. sum_serie['data'] = sum_serie_data
  107. series.append(sum_serie)
  108. if g.sumonly == "on":
  109. ret['series'] = [sum_serie,]
  110. else:
  111. ret['series'] = series
  112. return json.dumps(ret)
  113. @app.route("/chart/k", methods=["GET"])
  114. def multi_counters_chart_data():
  115. if not g.id:
  116. abort(400, "no graph id given")
  117. j = TmpGraph.get(g.id)
  118. if not j:
  119. abort(400, "no such tmp_graph where id=%s" %g.id)
  120. counters = j.counters
  121. if not counters:
  122. abort(400, "no counters of %s" %g.id)
  123. counters = sorted(set(counters))
  124. endpoints = j.endpoints
  125. if not endpoints:
  126. abort(400, "no endpoints of %s" % g.id)
  127. endpoints = sorted(set(endpoints))
  128. ret = {
  129. "units": "",
  130. "title": "",
  131. "series": []
  132. }
  133. e = endpoints[0]
  134. ret['title'] = e
  135. query_result = graph_history(endpoints[:1], counters, g.cf, g.start, g.end)
  136. series = []
  137. for i in range(0, len(query_result)):
  138. x = query_result[i]
  139. try:
  140. xv = [(v["timestamp"]*1000, v["value"]) for v in x["Values"]]
  141. serie = {
  142. "data": xv,
  143. "name": query_result[i]["counter"],
  144. "cf": g.cf,
  145. "endpoint": query_result[i]["endpoint"],
  146. "counter": query_result[i]["counter"],
  147. }
  148. series.append(serie)
  149. except:
  150. pass
  151. sum_serie = {
  152. "data": [],
  153. "name": "sum",
  154. "cf": g.cf,
  155. "endpoint": e,
  156. "counter": "sum",
  157. }
  158. if g.sum == "on" or g.sumonly == "on":
  159. sum = []
  160. tmp_ts = []
  161. max_size = 0
  162. for serie in series:
  163. serie_vs = [x[1] for x in serie["data"]]
  164. if len(serie_vs) > max_size:
  165. max_size = len(serie_vs)
  166. tmp_ts = [x[0] for x in serie["data"]]
  167. sum = merge_list(sum, serie_vs)
  168. sum_serie_data = []
  169. for i in range(0, max_size):
  170. sum_serie_data.append((tmp_ts[i], sum[i]))
  171. sum_serie['data'] = sum_serie_data
  172. series.append(sum_serie)
  173. if g.sumonly == "on":
  174. ret['series'] = [sum_serie,]
  175. else:
  176. ret['series'] = series
  177. return json.dumps(ret)
  178. @app.route("/chart/a", methods=["GET"])
  179. def multi_chart_data():
  180. if not g.id:
  181. abort(400, "no graph id given")
  182. j = TmpGraph.get(g.id)
  183. if not j:
  184. abort(400, "no such tmp_graph where id=%s" %g.id)
  185. counters = j.counters
  186. if not counters:
  187. abort(400, "no counters of %s" %g.id)
  188. counters = sorted(set(counters))
  189. endpoints = j.endpoints
  190. if not endpoints:
  191. abort(400, "no endpoints of %s, and tags:%s" %(g.id, g.tags))
  192. endpoints = sorted(set(endpoints))
  193. ret = {
  194. "units": "",
  195. "title": "",
  196. "series": []
  197. }
  198. query_result = graph_history(endpoints, counters, g.cf, g.start, g.end)
  199. series = []
  200. for i in range(0, len(query_result)):
  201. x = query_result[i]
  202. try:
  203. xv = [(v["timestamp"]*1000, v["value"]) for v in x["Values"]]
  204. serie = {
  205. "data": xv,
  206. "name": "%s %s" %(query_result[i]["endpoint"], query_result[i]["counter"]),
  207. "cf": g.cf,
  208. "endpoint": "",
  209. "counter": "",
  210. }
  211. series.append(serie)
  212. except:
  213. pass
  214. sum_serie = {
  215. "data": [],
  216. "name": "sum",
  217. "cf": g.cf,
  218. "endpoint": "",
  219. "counter": "",
  220. }
  221. if g.sum == "on" or g.sumonly == "on":
  222. sum = []
  223. tmp_ts = []
  224. max_size = 0
  225. for serie in series:
  226. serie_vs = [x[1] for x in serie["data"]]
  227. if len(serie_vs) > max_size:
  228. max_size = len(serie_vs)
  229. tmp_ts = [x[0] for x in serie["data"]]
  230. sum = merge_list(sum, serie_vs)
  231. sum_serie_data = []
  232. for i in range(0, max_size):
  233. sum_serie_data.append((tmp_ts[i], sum[i]))
  234. sum_serie['data'] = sum_serie_data
  235. series.append(sum_serie)
  236. if g.sumonly == "on":
  237. ret['series'] = [sum_serie,]
  238. else:
  239. ret['series'] = series
  240. return json.dumps(ret)
  241. @app.route("/charts", methods=["GET"])
  242. def charts():
  243. if not g.id:
  244. abort(400, "no graph id given")
  245. j = TmpGraph.get(g.id)
  246. if not j:
  247. abort(400, "no such tmp_graph where id=%s" %g.id)
  248. counters = j.counters
  249. if not counters:
  250. abort(400, "no counters of %s" %g.id)
  251. counters = sorted(set(counters))
  252. endpoints = j.endpoints
  253. if not endpoints:
  254. abort(400, "no endpoints of %s" %g.id)
  255. endpoints = sorted(set(endpoints))
  256. chart_urls = []
  257. chart_ids = []
  258. p = {
  259. "id": "",
  260. "legend": g.legend,
  261. "cf": g.cf,
  262. "sum": g.sum,
  263. "graph_type": g.graph_type,
  264. "nav_header": g.nav_header,
  265. "start": g.start,
  266. "end": g.end,
  267. }
  268. if g.graph_type == GRAPH_TYPE_KEY:
  269. for x in endpoints:
  270. id_ = TmpGraph.add([x], counters)
  271. if not id_:
  272. continue
  273. p["id"] = id_
  274. chart_ids.append(int(id_))
  275. src = "/chart/h?" + urllib.urlencode(p)
  276. chart_urls.append(src)
  277. elif g.graph_type == GRAPH_TYPE_HOST:
  278. for x in counters:
  279. id_ = TmpGraph.add(endpoints, [x])
  280. if not id_:
  281. continue
  282. p["id"] = id_
  283. chart_ids.append(int(id_))
  284. src = "/chart/h?" + urllib.urlencode(p)
  285. chart_urls.append(src)
  286. else:
  287. id_ = TmpGraph.add(endpoints, counters)
  288. if id_:
  289. p["id"] = id_
  290. chart_ids.append(int(id_))
  291. src = "/chart/a?" + urllib.urlencode(p)
  292. chart_urls.append(src)
  293. return render_template("chart/multi_ng.html", **locals())