TraceViewer.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #
  2. # Copyright (c) Contributors to the Open 3D Engine Project.
  3. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. #
  5. # SPDX-License-Identifier: Apache-2.0 OR MIT
  6. #
  7. #
  8. from EventLogger.Reader import Reader
  9. from EventLogger.Utils import EventNameHash, PrologId
  10. from tkinter import filedialog
  11. from tkinter import ttk
  12. from tkinter import *
  13. import tkinter
  14. import struct
  15. AssertId = EventNameHash("Assert")
  16. ErrorId = EventNameHash("Error")
  17. MessageId = EventNameHash("Message")
  18. PrintfId = EventNameHash("Printf")
  19. WarningId = EventNameHash("Warning")
  20. class TraceViewer(object):
  21. def __init__(self):
  22. self._tab_content = {}
  23. self._window = window = tkinter.Tk()
  24. window.title('Trace Viewer')
  25. window.minsize(640, 480)
  26. # file menu
  27. self._file_menu = file_menu = Menubutton(window, text='File')
  28. file_menu.menu = Menu(file_menu, tearoff=0)
  29. file_menu['menu'] = file_menu.menu
  30. file_menu.pack(side=TOP, anchor=W)
  31. file_menu.menu.add_command(label='Open...', command=self._open_file)
  32. file_menu.menu.add_command(label='Exit', command=window.quit)
  33. # main content
  34. self._main_view = main_view = ttk.Notebook(window)
  35. main_view.pack(fill=BOTH, expand=1)
  36. # setup a debug tab for internal logging
  37. self._add_new_tab('Debug')
  38. def run(self):
  39. self._window.mainloop()
  40. def _reset(self):
  41. for tab in self._main_view.winfo_children():
  42. tab.destroy()
  43. self._add_new_tab('Debug')
  44. def _add_new_tab(self, name):
  45. tab = ttk.Frame(self._main_view)
  46. vscrollbar = Scrollbar(tab)
  47. hscrollbar = Scrollbar(tab, orient='horizontal')
  48. text_box = Text(tab, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set, wrap=NONE)
  49. text_box.tag_config('Assert', foreground='red3', background='gray80')
  50. text_box.tag_config('Error', foreground='red2')
  51. text_box.tag_config('Warning', foreground='SteelBlue3')
  52. vscrollbar.config(command=text_box.yview)
  53. hscrollbar.config(command=text_box.xview)
  54. vscrollbar.pack(side=RIGHT, fill=Y)
  55. hscrollbar.pack(side=BOTTOM, fill=X)
  56. text_box.pack(fill=BOTH, expand=1)
  57. self._main_view.add(tab, text=name)
  58. self._tab_content[name] = text_box
  59. self._active_content = text_box
  60. def _append_debug_message(self, message):
  61. debug_content = self._tab_content['Debug']
  62. debug_content.insert(END, f'{message}\n')
  63. def _append_current_message(self, message):
  64. if self._active_content:
  65. self._active_content.insert(END, f'{message}\n')
  66. def _append_current_tagged_message(self, message, tag):
  67. if self._active_content:
  68. start = self._active_content.index('insert linestart')
  69. self._active_content.insert(END, f'{message}\n')
  70. self._active_content.tag_add(tag, start, 'insert lineend')
  71. def _open_file(self):
  72. log_file_types = [
  73. ('log files','*.azel'),
  74. ('log files','*.bin'),
  75. ('all files','*.*')
  76. ]
  77. log_file = filedialog.askopenfilename(initialdir='../../', title='Select log file', filetypes=log_file_types)
  78. if not log_file:
  79. self._append_debug_message('Invalid file')
  80. return
  81. self._reset()
  82. log_reader = Reader()
  83. status = log_reader.read_log_file(log_file)
  84. if status == Reader.ReadStatus_InsufficientFileSize:
  85. self._append_debug_message('File size too small to contain Event Logger information')
  86. return
  87. elif status == Reader.ReadStatus_InvalidFormat:
  88. self._append_debug_message('Invalid Event Logger format detected')
  89. return
  90. log_header = log_reader.get_log_header()
  91. self._append_debug_message(f'Log File: {log_file}')
  92. self._append_debug_message(f'Format: {log_header.get_format()}')
  93. self._append_debug_message(f'Version: {log_header.get_version()}')
  94. tagged_messages = { AssertId : 'Assert', ErrorId : 'Error', WarningId : 'Warning' }
  95. has_event = (status == Reader.ReadStatus_Success)
  96. while has_event:
  97. event_id = log_reader.get_event_name()
  98. if event_id == PrologId:
  99. tab_name = f'Thread {log_reader.get_thread_id()}'
  100. if tab_name in self._tab_content:
  101. self._active_content = self._tab_content[tab_name]
  102. else:
  103. self._add_new_tab(tab_name)
  104. elif event_id in tagged_messages:
  105. self._append_current_tagged_message(log_reader.get_event_string(), tagged_messages[event_id])
  106. elif event_id in (PrintfId, MessageId):
  107. self._append_current_message(log_reader.get_event_string())
  108. else:
  109. self._append_current_message(f'Event ID {event_id}, Size {log_reader.get_event_size()}')
  110. has_event = log_reader.next()
  111. def main():
  112. trace_viewer = TraceViewer()
  113. trace_viewer.run()
  114. if __name__ == '__main__':
  115. main()