From e2222dae5e53797d2f460a5a40b0c14158cfda2a Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 21 Jun 2026 12:34:09 +0200 Subject: [PATCH] server: mirror console output to a text log under logs/ The codebase logs everything via plain print() scattered across tasks/ws/components - rather than touch every call site, stdout/stderr are now duplicated (Tee) into logs/brewpi..log alongside the existing tracer .mat files, line-buffered so a crash doesn't lose the tail of the log. --- server/brewpi.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/server/brewpi.py b/server/brewpi.py index 573a5e3..51e1f98 100755 --- a/server/brewpi.py +++ b/server/brewpi.py @@ -1,6 +1,9 @@ #!/usr/bin/env python3 import asyncio import json +import os +import sys +import time from utils import ChangedFloat from ws.message import MessageDispatcher from ws.server.ws_server_multi_user import WsServerMultiUser @@ -23,7 +26,33 @@ DEFAULT_PLANT_PARAMS = { "Td": 30 } + +class Tee: + """Duplicates writes to multiple streams - used to mirror stdout/stderr + (everything the rest of the codebase already reaches via print()) into + a log file under logs/ as well as the console, without having to touch + every print() call site.""" + + def __init__(self, *streams): + self.streams = streams + + def write(self, data): + for stream in self.streams: + stream.write(data) + + def flush(self): + for stream in self.streams: + stream.flush() + + if __name__ == '__main__': + os.makedirs("logs", exist_ok=True) + log_path = "logs/brewpi.{}.log".format(time.strftime("%Y%m%d%H%M%S", time.localtime())) + log_file = open(log_path, "a", buffering=1) + sys.stdout = Tee(sys.stdout, log_file) + sys.stderr = Tee(sys.stderr, log_file) + print("Logging to {}".format(log_path)) + parser = ap.ArgumentParser() parser.add_argument("-d", "--debug", action="store_true") parser.add_argument("-c", "--config", default="config.json")