Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

172 rindas
5.6KB

  1. import datetime
  2. import os
  3. import time
  4. import requests
  5. import logging
  6. from flask import request, send_from_directory, json
  7. from flask_classy import FlaskView, route
  8. from modules import cbpi
  9. class LogView(FlaskView):
  10. def __init__(self):
  11. self.logger = logging.getLogger(__name__)
  12. @route('/', methods=['GET'])
  13. def get_all_logfiles(self):
  14. result = []
  15. for filename in os.listdir("./logs"):
  16. if filename.endswith(".log"):
  17. result.append(filename)
  18. return json.dumps(result)
  19. @route('/actions')
  20. def actions(self):
  21. filename = "./logs/action.log"
  22. array = self.query_log(filename, "string")
  23. json_dumps = json.dumps(array)
  24. self.logger.debug("Loaded action.log [%s]", json_dumps)
  25. return json_dumps
  26. @route('/<file>', methods=["DELETE"])
  27. def clearlog(self, file):
  28. """
  29. Overload delete method to shutdown sensor before delete
  30. :param id: sensor id
  31. :return: HTTP 204
  32. """
  33. if not self.check_filename(file):
  34. return ('File Not Found', 404)
  35. filename = "./logs/%s" % file
  36. if os.path.isfile(filename) == True:
  37. os.remove(filename)
  38. cbpi.notify("log deleted succesfully", "")
  39. else:
  40. cbpi.notify("Failed to delete log", "", type="danger")
  41. return ('', 204)
  42. def query_tsdb(self, type, id):
  43. kairosdb_server = "http://127.0.0.1:" + cbpi.cache["config"]["kairos_db_port"].__dict__["value"]
  44. data = dict(metrics=[
  45. {
  46. "tags": {},
  47. "name": "cbpi.%s_%s" % (type, id),
  48. "aggregators": [
  49. {
  50. "name": "avg",
  51. "align_sampling": True,
  52. "sampling": {
  53. "value": "5",
  54. "unit": "seconds"
  55. },
  56. "align_start_time": True
  57. }
  58. ]
  59. }
  60. ],
  61. cache_time=0,
  62. start_relative={
  63. "value": "1",
  64. "unit": "days"
  65. })
  66. if cbpi.cache["active_brew"] != "none":
  67. data["metrics"][0]["tags"] = {"brew": [cbpi.cache["active_brew"]]}
  68. self.logger.debug("query: %s", json.dumps(data))
  69. response = requests.post(kairosdb_server + "/api/v1/datapoints/query", json.dumps(data))
  70. if response.ok:
  71. self.logger.debug("Fetching time series for [%s_%s] took [%s]", type, id, response.elapsed)
  72. self.logger.debug("Time series for [%s_%s] is [%s]", type, id, response.json())
  73. return response.json()["queries"][0]["results"][0]["values"]
  74. else:
  75. self.logger.warning("Failed to fetch time series for [%s_%s]. Response [%s]", type, id, response)
  76. def query_log(self, filename, value_type):
  77. array = []
  78. if not os.path.isfile(filename):
  79. self.logger.warn("File does not exist [%s]", filename)
  80. return array
  81. import csv
  82. if value_type == "float":
  83. converter = float
  84. else:
  85. converter = str
  86. with open(filename, 'rb') as f:
  87. reader = csv.reader(f)
  88. for row in reader:
  89. try:
  90. point_of_time = int((datetime.datetime.strptime(row[0], "%Y-%m-%d %H:%M:%S")
  91. - datetime.datetime(1970, 1, 1)).total_seconds()) * 1000
  92. value = converter(row[1])
  93. array.append([point_of_time, value])
  94. except:
  95. self.logger.exception("error in reading logfile [%s]", filename)
  96. pass
  97. return array
  98. def read_log_as_json(self, type, id):
  99. use_kairosdb = (cbpi.cache["config"]["kairos_db"].__dict__["value"] == "YES")
  100. if use_kairosdb:
  101. return self.query_tsdb(type, id)
  102. else:
  103. filename = "./logs/%s_%s.log" % (type, id)
  104. return self.query_log(filename, "float")
  105. def convert_chart_data_to_json(self, chart_data):
  106. return {"name": chart_data["name"],
  107. "data": self.read_log_as_json(chart_data["data_type"], chart_data["data_id"])}
  108. @route('/<t>/<int:id>', methods=["POST"])
  109. def get_logs_as_json(self, t, id):
  110. data = request.json
  111. result = []
  112. if t == "s":
  113. name = cbpi.cache.get("sensors").get(id).name
  114. result.append({"name": name, "data": self.read_log_as_json("sensor", id)})
  115. if t == "k":
  116. kettle = cbpi.cache.get("kettle").get(id)
  117. result = map(self.convert_chart_data_to_json, cbpi.get_controller(kettle.logic).get("class").chart(kettle))
  118. if t == "f":
  119. fermenter = cbpi.cache.get("fermenter").get(id)
  120. result = map(self.convert_chart_data_to_json,
  121. cbpi.get_fermentation_controller(fermenter.logic).get("class").chart(fermenter))
  122. return json.dumps(result)
  123. @route('/download/<file>')
  124. @cbpi.nocache
  125. def download(self, file):
  126. if not self.check_filename(file):
  127. return ('File Not Found', 404)
  128. return send_from_directory('../logs', file, as_attachment=True, attachment_filename=file)
  129. def check_filename(self, name):
  130. import re
  131. pattern = re.compile('^([A-Za-z0-9-_])+.log$')
  132. return True if pattern.match(name) else False
  133. @cbpi.initalizer()
  134. def init(app):
  135. """
  136. Initializer for the message module
  137. :param app: the flask app
  138. :return: None
  139. """
  140. LogView.register(cbpi.app, route_base='/api/logs')