Skip to content

Commit

Permalink
Merge pull request #63 from jubnl/main
Browse files Browse the repository at this point in the history
Debug console: Implement log "buffer" handling in client socket handler
  • Loading branch information
Aurelius7309 authored Apr 4, 2024
2 parents d4b5c3e + c942f0d commit 4e87662
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
2 changes: 1 addition & 1 deletion debug/debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function sendMessageToConsole(level, logger, message)
logger = logger or "DefaultLogger"
message = message or "Default log message"
-- naive way to separate the logs if the console receive multiple logs at the same time
client:send(level .. " :: " .. logger .. " :: " .. message .. "ENDOFLOG")
client:send(os.date('%Y-%m-%d %H:%M:%S') .. " :: " .. level .. " :: " .. logger .. " :: " .. message .. "ENDOFLOG")
end
end

Expand Down
84 changes: 73 additions & 11 deletions debug/tk_debug_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import threading
import tkinter as tk
from datetime import datetime
from tkinter import filedialog

log_levels = {
"TRACE": 0,
Expand Down Expand Up @@ -69,18 +70,23 @@ def _proxy(self, *args):

class Log:
def __init__(self, log: str):
self.timestamp_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
self.log_level = "DEBUG"
self.logger = "DefaultLogger"
self.log_str = ""
self.parse_error = False
log_parts = log.split(" :: ")
if len(log_parts) == 3:
self.log_level = log_parts[0]
self.logger = log_parts[1]
if len(log_parts) == 4:
self.timestamp_str = log_parts[0]
self.log_level = log_parts[1]
self.logger = log_parts[2]
self.log_str = log_parts[3]
elif len(log_parts) == 3:
self.timestamp_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
self.logger = log_parts[0]
self.log_str = log_parts[1]
self.log_str = log_parts[2]
else:
self.parse_error = True
self.timestamp_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
self.log_level = "DEBUG"
self.logger = "DefaultLogger"
self.log_str = log

def __str__(self):
Expand Down Expand Up @@ -458,13 +464,54 @@ def apply_logger_entry_var(self):
self.after_id = None


class ExportMenuBar(tk.Menu):
def __init__(self, parent, console: Console, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.parent = parent
self.initialize_menu()
self.console = console

def initialize_menu(self):
# Create a File menu
file_menu = tk.Menu(self, tearoff=0)
file_menu.add_command(label="All logs", command=self.export_all_logs)
file_menu.add_separator()
file_menu.add_command(label="Filtered logs", command=self.export_filtered_logs)

# Adding the "File" menu to the menubar
self.add_cascade(label="Export", menu=file_menu)

def export_all_logs(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".log",
filetypes=[("Log files", "*.log"), ("All files", "*.*")],
initialfile=f"Balatro-AllLogs-{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log"
)
if file_path:
with open(file_path, "w") as f:
for log in self.console.all_logs:
f.write(str(log))

def export_filtered_logs(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".log",
filetypes=[("Log files", "*.log"), ("All files", "*.*")],
initialfile=f"Balatro-FilteredLogs-{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log"
)
if file_path:
with open(file_path, "w") as f:
for log in self.console.shown_logs:
f.write(str(log))


class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
self.title("Steamodded Debug Console")
self.options_frame = OptionsFrame(self)
self.console = Console(self, self.options_frame)
self.options_frame.inject_console(self.console)
self.menu_bar = ExportMenuBar(self, self.console)
self.create_widgets()

self.bind('<Control-f>', self.focus_search)
Expand All @@ -473,6 +520,7 @@ def __init__(self):
def create_widgets(self):
self.console.pack(side=tk.TOP, expand=True, fill='both')
self.options_frame.pack(side=tk.BOTTOM, fill='x', expand=False)
self.config(menu=self.menu_bar)

def get_console(self):
return self.console
Expand All @@ -482,18 +530,32 @@ def focus_search(self, event):


def client_handler(client_socket, console: Console):
buffer = []
while True:
# Traceback can fit in a single log now
data = client_socket.recv(8192)
data = client_socket.recv(1024)
if not data:
break

decoded_data = data.decode()
logs = decoded_data.split("ENDOFLOG")
buffer.append(decoded_data) # Append new data to the buffer list

# Join the buffer and split by "ENDOFLOG"
# This handles cases where "ENDOFLOG" is spread across multiple recv calls
combined_data = ''.join(buffer)
logs = combined_data.split("ENDOFLOG")

# The last element might be an incomplete log; keep it in the buffer
buffer = [logs.pop()] if logs[-1] else []

# Append each complete log to the console
for log in logs:
if log:
console.append_log(log)

# Handle any remaining data in the buffer after the connection is closed
if ''.join(buffer):
console.append_log(''.join(buffer))


def listen_for_clients(console: Console):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand All @@ -507,4 +569,4 @@ def listen_for_clients(console: Console):
if __name__ == "__main__":
root = MainWindow()
threading.Thread(target=listen_for_clients, daemon=True, args=(root.get_console(),)).start()
root.mainloop()
root.mainloop()

0 comments on commit 4e87662

Please sign in to comment.