log_reporter.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. '''
  2. Created on 25.06.2018
  3. @author: Bernhard
  4. Should read all log*.log-files and output
  5. -) Server
  6. -) Computer
  7. -) Start-Time
  8. -) End-Time
  9. -) Duration (according to file)
  10. -) finished (yes/no)
  11. -) Mode (recycling or allnew)
  12. -) Products
  13. -) Users
  14. -) Average of all API-Calls (basically multiply each average * number and build an average by dividing this number
  15. '''
  16. import codecs
  17. import csv
  18. import glob, os
  19. import datetime
  20. import getopt
  21. import sys
  22. def args_read(l_search_parameter):
  23. l_args = sys.argv[1:]
  24. try:
  25. opts, args = getopt.getopt(l_args,"d:;",["dir=",
  26. "mode="
  27. ])
  28. except getopt.GetoptError as err_det:
  29. print ("Error in reading parameters:" + str(err_det))
  30. print ("Call with --dir= or without any parameters")
  31. print ("--mode=recycle|allnew|nginx to ignore files <> this mode")
  32. sys.exit("Abgebrochen wegen Fehler in Aufrufparametern")
  33. if opts:
  34. for opt, arg in opts:
  35. if l_search_parameter == opt: #in ("-u", "--usage"):
  36. return arg
  37. def f_get_logfiles_from_dir(l_dir):
  38. l_files = []
  39. os.chdir(l_dir)
  40. for file in glob.glob("log*.log"):
  41. l_files.append (file)
  42. return l_files
  43. class read_csv():
  44. def __init__(self, csv):
  45. self.csv = csv
  46. self.attribs = {}
  47. self.attribs["file"] = csv.split("\\")[-1]
  48. self.attribs["start"] = ""
  49. self.attribs["end"] = ""
  50. self.attribs["duration"] = ""
  51. self.attribs["server"] = ""
  52. self.attribs["computer"] = ""
  53. self.attribs["users"] = 0
  54. self.attribs["products"] = 0
  55. self.attribs["mode"] = ""
  56. self.attribs["linecount"] = 0
  57. self.attribs["info"] = 0
  58. self.attribs["warning"] = 0
  59. self.attribs["critical"] = 0
  60. self.attribs["debug"] = 0
  61. self.attribs["error"] = 0
  62. # Default values for All-Calls, All-Duration, Absolute Min, Absolute Max)
  63. self.attribs["API-AVG"] = [0,0,0,9999,0]
  64. self.attribs["API-Calls"] = []
  65. # They're used later to create the variable header of all API-Calls, that were executed
  66. # so that we can print Headers for them
  67. self.api_detail_headers={}
  68. def load(self):
  69. with codecs.open(filename=self.csv, mode='r', encoding="utf-8", errors="ignore") as l_csvfile:
  70. l_reader = csv.reader(l_csvfile)
  71. for l_row in l_reader:
  72. # Start the interpretation of the file
  73. l_string = ""
  74. for n in range(0, len(l_row)):
  75. l_string = l_string + ":" + l_row[n]
  76. # Set Start time
  77. l_string = l_string[1:]
  78. if l_string[0:4] != "2018":
  79. continue
  80. if len(self.attribs["start"]) == 0:
  81. self.attribs["start"] = l_string[0:23]
  82. # Any record can be the last :)
  83. self.attribs["end"] = l_string[0:23]
  84. self.attribs["linecount"] += 1
  85. l_string = l_string[24:]
  86. # Now determine message-type (Info, warn, etc.)
  87. l_msgty = l_string.split(" ")[0]
  88. if len(l_msgty) > 0:
  89. l_msgty = l_msgty.lower()
  90. self.attribs[l_msgty] += 1
  91. # Find "Products"
  92. if "f_products_import: Products:" in l_string:
  93. self.attribs["products"] = int(l_string.split(" ")[-1])
  94. # Server:
  95. if "set_default: Server:" in l_string:
  96. self.attribs["server"] = l_string.split(" ")[-1]
  97. elif "Server: " in l_string:
  98. self.attribs["server"] = l_string.split(" ")[-1]
  99. if "get_l_users: Users: " in l_string:
  100. self.attribs["users"] = int(l_string.split(" ")[-1])
  101. if "f_daily_recycle: Mode Recycling!" in l_string:
  102. self.attribs["mode"] = "recycling"
  103. if "f_nginx: Starting load test on nginx" in l_string:
  104. self.attribs["mode"] = "nginx"
  105. if "printreport: Computer:" in l_string:
  106. self.attribs["computer"] = l_string.split(" ")[-1]
  107. if "printreport" in l_string:
  108. self.__printreport(l_string)
  109. if len(self.attribs["end"]) > 13 and len(self.attribs["start"]) > 13:
  110. self.attribs["duration"] = ( datetime.datetime.strptime(self.attribs["end"], '%Y-%m-%d %H:%M:%S:%f')
  111. - datetime.datetime.strptime(self.attribs["start"], '%Y-%m-%d %H:%M:%S:%f') )
  112. if self.attribs["mode"] == "":
  113. self.attribs["mode"] = "allnew"
  114. def report(self):
  115. for n, x in self.attribs.items():
  116. print (n + ":" + str(x))
  117. def __printreport(self, l_string):
  118. l_line = l_string.split("printreport:")[-1]
  119. if "# Avg" in l_line:
  120. return
  121. if "-------" in l_line:
  122. return
  123. if "Server" in l_line:
  124. return
  125. if "Computer" in l_line:
  126. return
  127. if "zzmake" in l_line:
  128. return
  129. if len(l_line) < 20:
  130. return
  131. l_array = l_line.split("|")
  132. l_array[0] = l_array[0].lstrip().rstrip()
  133. l_api = l_array[0].split(" ")[0]
  134. l_count = int(l_array[0].split(" ")[-1])
  135. # Now the AVG, Sum, Min, Max, Last
  136. l_avg = float(l_array[1])
  137. l_total = float(l_array[2])
  138. l_min = float(l_array[3])
  139. l_max = float(l_array[4])
  140. l_last = float(l_array[5])
  141. self.attribs["API-Calls"].append([l_api, l_count, l_avg, l_total, l_min, l_max, l_last])
  142. self.api_detail_headers[l_api] = ""
  143. self.attribs["API-AVG"][0] = self.attribs["API-AVG"][0] + l_count
  144. self.attribs["API-AVG"][1] = round(self.attribs["API-AVG"][1] + ( l_count * l_avg ),2)
  145. self.attribs["API-AVG"][2] = round(self.attribs["API-AVG"][1] / self.attribs["API-AVG"][0],4)
  146. if l_min < self.attribs["API-AVG"][3]:
  147. self.attribs["API-AVG"][3] = l_min
  148. if l_max > self.attribs["API-AVG"][4]:
  149. self.attribs["API-AVG"][4] = l_max
  150. def get_all_attribs(self):
  151. return self.attribs
  152. def get_all_api_names(self):
  153. return self.api_detail_headers
  154. def l_export_csvs(l_csvs, l_export_filename):
  155. with codecs.open(filename=l_export_filename, mode='wb', encoding='utf-8-sig') as l_csv:
  156. # write header
  157. l_csv_writer = csv.writer(l_csv, delimiter=";", quoting = csv.QUOTE_ALL)
  158. l_header = []
  159. l_api_header = {}
  160. # read all files to get attribs for header:
  161. for l_csv_item in l_csvs.values():
  162. # If this is not one of the file-modes we're searching for, then ignore also the header
  163. if args_read(l_search_parameter="--mode"):
  164. l_temp = l_csv_item.get_all_attribs()
  165. if args_read(l_search_parameter="--mode") != l_temp["mode"]:
  166. continue
  167. for key in l_csv_item.get_all_api_names().keys():
  168. l_api_header[key] = ""
  169. # Write header to CSV
  170. for l_key in l_csv_item.get_all_attribs().keys():
  171. if l_key == "API-AVG":
  172. l_header.append("Total Calls")
  173. l_header.append("Total Duration")
  174. l_header.append("Total Average")
  175. l_header.append("Total Min")
  176. l_header.append("Total Max")
  177. elif l_key == "API-Calls":
  178. # That's the last column - enter here all our collected Headers:
  179. for h_key in l_api_header.keys():
  180. # append to Header-Line and save position within the header-array, so that we can
  181. # later find the position for a specific API-Name and write into this column and the next ones
  182. l_header.append(h_key+" #")
  183. l_api_header[h_key] = len(l_header)-1
  184. l_header.append(h_key + " Avg")
  185. l_header.append(h_key + " Tot")
  186. else:
  187. l_header.append(l_key)
  188. l_csv_writer.writerow(l_header)
  189. # Write all concatenated infos to CSV
  190. for l_csv_in in l_csvs.values():
  191. # If this is not one of the file-modes we're searching for, then ignore also the header
  192. if args_read(l_search_parameter="--mode"):
  193. l_temp = l_csv_in.get_all_attribs()
  194. if args_read(l_search_parameter="--mode") != l_temp["mode"]:
  195. continue
  196. l_row_out = []
  197. l_pos = 0
  198. for l_row_key, l_row_item in l_csv_in.get_all_attribs().items():
  199. if l_row_key == "API-AVG":
  200. for n in range(0, 5):
  201. l_row_out.append(str(l_row_item[n]).replace(".", ","))
  202. l_pos += 1
  203. elif l_row_key == "API-Calls":
  204. if len(l_row_item) > 0:
  205. # We need to find our destination column (hopefully in dictionary)
  206. # find out, now many columns we must skip and place the value there
  207. for l_api_row in l_row_item:
  208. for n in range(0,l_api_header[l_row_item[0][0]] - l_pos):
  209. l_row_out.append(";")
  210. l_row_out.append(l_api_row[1]) # Number of calls
  211. l_row_out.append(str(l_api_row[2]).replace(".", ",")) # AVG / call
  212. l_row_out.append(str(l_api_row[3]).replace(".", ",")) # Total duration
  213. l_pos+=3
  214. else:
  215. l_row_out.append(l_row_item)
  216. l_pos+=1
  217. l_csv_writer.writerow(l_row_out)
  218. l_dir = args_read("--dir")
  219. if not l_dir:
  220. l_dir = "C:\\Users\\Bernhard\\cs_earthsquad\\CloudStation\\pwa\\Testcases\\API\\ES_API_TEST\\pyAPITest\\dist\\log\\"
  221. else:
  222. l_dir = l_dir + "\\"
  223. l_csvs = {}
  224. for l_logfile in f_get_logfiles_from_dir(l_dir):
  225. print("File " + l_logfile)
  226. l_test_csv = read_csv(l_dir + l_logfile)
  227. l_test_csv.load()
  228. #l_test_csv.report()
  229. l_csvs[l_logfile] = l_test_csv
  230. l_export_csvs(l_csvs, "log_summary.csv")
  231. print("----")
  232. print("Log_summary.csv created")