From 9e22d91245ac36e5f48162cfee943b21b72aaf34 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 25 May 2023 07:41:40 -0400 Subject: [PATCH] update logging and temp file handling --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/extension_report.yml | 2 +- .gitignore | 2 +- README.md | 2 +- cli/train.py | 19 ++++++++----- extensions-builtin/sd-webui-controlnet | 2 +- installer.py | 30 ++++++++++++--------- javascript/black-orange.css | 2 +- launch.py | 3 +-- modules/ui_tempdir.py | 27 +++++++++++++------ 10 files changed, 56 insertions(+), 35 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 28fbd4296..add464bca 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -28,7 +28,7 @@ body: - type: markdown attributes: value: | - If issue is setup, installation or startup related, please check `setup.log` before reporting + If issue is setup, installation or startup related, please check `webui.log` before reporting And when posting console logs, please use code blocks ( \`\`\` ) to format them insead of uploading screenshots - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/extension_report.yml b/.github/ISSUE_TEMPLATE/extension_report.yml index cacdb16d3..21e95688a 100644 --- a/.github/ISSUE_TEMPLATE/extension_report.yml +++ b/.github/ISSUE_TEMPLATE/extension_report.yml @@ -29,5 +29,5 @@ body: - type: markdown attributes: value: | - If issue is extension installation or startup related, please check `setup.log` before reporting + If issue is extension installation or startup related, please check `webui.log` before reporting And when posting console logs, please use code blocks ( \`\`\` ) to format them insead of uploading screenshots diff --git a/.gitignore b/.gitignore index 078ec543c..19aed4141 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # defaults __pycache__ -setup.log /cache.json /config.json /params.txt @@ -17,6 +16,7 @@ package-lock.json venv # all models and temp files +*.log *.bak *.ckpt *.safetensors diff --git a/README.md b/README.md index c8109a61a..10cae8fdd 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Individual features are not listed here, instead check [Changelog](CHANGELOG.md) *Note*: **nVidia/CUDA** and **AMD/ROCm** are auto-detected is present and available, but for any other use case specify required parameter explicitly or wrong packages may be installed as installer will assume CPU-only environment -Full startup sequence is logged in `setup.log`, so if you encounter any issues, please check it first +Full startup sequence is logged in `webui.log`, so if you encounter any issues, please check it first Below is partial list of all available parameters, run `webui --help` for the full list: diff --git a/cli/train.py b/cli/train.py index a2507660b..14ef28d6a 100755 --- a/cli/train.py +++ b/cli/train.py @@ -33,19 +33,19 @@ # globals args = None -log = logging.getLogger(__name__) +log = logging.getLogger('train') valid_steps = ['original', 'face', 'body', 'blur', 'range', 'upscale', 'restore', 'interrogate', 'resize', 'square', 'segment'] +log_file = os.path.join(os.path.dirname(__file__), 'train.log') # methods def setup_logging(clean=False): try: - if clean and os.path.isfile('setup.log'): - os.remove('setup.log') + if clean and os.path.isfile(log_file): + os.remove(log_file) time.sleep(0.1) # prevent race condition except: pass - logging.basicConfig(level=logging.DEBUG, format='%(asctime)s | %(levelname)s | %(pathname)s | %(message)s', filename='setup.log', filemode='a', encoding='utf-8', force=True) from rich.theme import Theme from rich.logging import RichHandler from rich.console import Console @@ -56,10 +56,17 @@ def setup_logging(clean=False): "traceback.border.syntax_error": "black", "inspect.value.border": "black", })) + # logging.getLogger("urllib3").setLevel(logging.ERROR) + # logging.getLogger("httpx").setLevel(logging.ERROR) + level = logging.DEBUG if args.debug else logging.INFO + logging.basicConfig(level=logging.ERROR, format='%(asctime)s | %(name)s | %(levelname)s | %(module)s | %(message)s', filename=log_file, filemode='a', encoding='utf-8', force=True) + log.setLevel(logging.DEBUG) # log to file is always at level debug for facility `sd` pretty_install(console=console) traceback_install(console=console, extra_lines=1, width=console.width, word_wrap=False, indent_guides=False, suppress=[]) - rh = RichHandler(show_time=True, omit_repeated_times=False, show_level=True, show_path=False, markup=False, rich_tracebacks=True, log_time_format='%H:%M:%S-%f', level=logging.DEBUG if args.debug else logging.INFO, console=console) - rh.set_name(logging.DEBUG if args.debug else logging.INFO) + rh = RichHandler(show_time=True, omit_repeated_times=False, show_level=True, show_path=False, markup=False, rich_tracebacks=True, log_time_format='%H:%M:%S-%f', level=level, console=console) + rh.set_name(level) + while log.hasHandlers() and len(log.handlers) > 0: + log.removeHandler(log.handlers[0]) log.addHandler(rh) diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 54f7c64b4..a8bf0c390 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 54f7c64b4dc4a4206e76a152651d5f0b0fac248f +Subproject commit a8bf0c3901c8c37f8ffc921f0345a86c922f7a58 diff --git a/installer.py b/installer.py index b701803c9..b40ac765b 100644 --- a/installer.py +++ b/installer.py @@ -20,6 +20,7 @@ class Dot(dict): # dot notation access to dictionary attributes log = logging.getLogger("sd") +log_file = os.path.join(os.path.dirname(__file__), 'webui.log') quick_allowed = True errors = 0 opts = {} @@ -48,12 +49,11 @@ class Dot(dict): # dot notation access to dictionary attributes # setup console and file logging def setup_logging(clean=False): try: - if clean and os.path.isfile('setup.log'): - os.remove('setup.log') + if clean and os.path.isfile(log_file): + os.remove(log_file) time.sleep(0.1) # prevent race condition except: pass - logging.basicConfig(level=logging.DEBUG, format='%(asctime)s | %(levelname)s | %(pathname)s | %(message)s', filename='setup.log', filemode='a', encoding='utf-8', force=True) from rich.theme import Theme from rich.logging import RichHandler from rich.console import Console @@ -64,10 +64,15 @@ def setup_logging(clean=False): "traceback.border.syntax_error": "black", "inspect.value.border": "black", })) + # logging.getLogger("urllib3").setLevel(logging.ERROR) + # logging.getLogger("httpx").setLevel(logging.ERROR) + level = logging.DEBUG if args.debug else logging.INFO + logging.basicConfig(level=logging.ERROR, format='%(asctime)s | %(name)s | %(levelname)s | %(module)s | %(message)s', filename=log_file, filemode='a', encoding='utf-8', force=True) + log.setLevel(logging.DEBUG) # log to file is always at level debug for facility `sd` pretty_install(console=console) traceback_install(console=console, extra_lines=1, width=console.width, word_wrap=False, indent_guides=False, suppress=[]) - rh = RichHandler(show_time=True, omit_repeated_times=False, show_level=True, show_path=False, markup=False, rich_tracebacks=True, log_time_format='%H:%M:%S-%f', level=logging.DEBUG if args.debug else logging.INFO, console=console) - rh.set_name(logging.DEBUG if args.debug else logging.INFO) + rh = RichHandler(show_time=True, omit_repeated_times=False, show_level=True, show_path=False, markup=False, rich_tracebacks=True, log_time_format='%H:%M:%S-%f', level=level, console=console) + rh.set_name(level) while log.hasHandlers() and len(log.handlers) > 0: log.removeHandler(log.handlers[0]) log.addHandler(rh) @@ -152,7 +157,7 @@ def git(arg: str, folder: str = None, ignore: bool = False): errors += 1 log.error(f'Error running git: {folder} / {arg}') if 'or stash them' in txt: - log.error('Local changes detected: check setup.log for details') + log.error(f'Local changes detected: check log for details: {log_file}') log.debug(f'Git output: {txt}') return txt @@ -528,7 +533,6 @@ def check_version(offline=False, reset=True): # pylint: disable=unused-argument import requests except ImportError: return - logging.getLogger("urllib3").setLevel(logging.ERROR) commits = None try: commits = requests.get('https://api.github.com/repos/vladmandic/automatic/branches/master', timeout=10).json() @@ -569,13 +573,13 @@ def update_wiki(): # check if we can run setup in quick mode def check_timestamp(): - if not quick_allowed or not os.path.isfile('setup.log'): + if not quick_allowed or not os.path.isfile(log_file): return False if args.skip_git: return True ok = True setup_time = -1 - with open('setup.log', 'r', encoding='utf8') as f: + with open(log_file, 'r', encoding='utf8') as f: lines = f.readlines() for line in lines: if 'Setup complete without errors' in line: @@ -633,8 +637,8 @@ def parse_args(): def extensions_preload(force = False): setup_time = 0 if not force: - if os.path.isfile('setup.log'): - with open('setup.log', 'r', encoding='utf8') as f: + if os.path.isfile(log_file): + with open(log_file, 'r', encoding='utf8') as f: lines = f.readlines() for line in lines: if 'Setup complete without errors' in line: @@ -672,7 +676,7 @@ def read_options(): # entry method when used as module def run_setup(): - setup_logging(args.upgrade) + # setup_logging(args.upgrade) log.info('Starting SD.Next') read_options() check_python() @@ -700,7 +704,7 @@ def run_setup(): log.debug(f'Setup complete without errors: {round(time.time())}') else: log.warning(f'Setup complete with errors: {errors}') - log.warning('See log file for more details: setup.log') + log.warning(f'See log file for more details: {log_file}') if __name__ == "__main__": diff --git a/javascript/black-orange.css b/javascript/black-orange.css index dab54760b..0feee14b3 100644 --- a/javascript/black-orange.css +++ b/javascript/black-orange.css @@ -102,7 +102,7 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_seed_row { padding: 0; margin-top: 8px; } #txt2img_settings { min-width: var(--left-column); max-width: var(--left-column); background-color: #111111; padding-top: 16px; } #txt2img_subseed_row { padding: 0; margin-top: 16px; } -#txt2img_subseed_show { min-width: 74px; padding: 8px 0 0 0 } +#txt2img_subseed_show, #img2img_subseed_show { display: None } #txt2img_subseed_strength { margin-top: 0; } #txt2img_tools, #img2img_tools { margin-top: 54px; scale: 120%; margin-left: 26px; } #txtimg_hr_finalres { max-width: 200px; } diff --git a/launch.py b/launch.py index c52096bbb..d0cd53467 100644 --- a/launch.py +++ b/launch.py @@ -10,9 +10,9 @@ import installer installer.ensure_base_requirements() -installer.setup_logging(False) installer.add_args() installer.parse_args() +installer.setup_logging(False) installer.extensions_preload(force=False) import modules.cmd_args @@ -130,7 +130,6 @@ def start_server(immediate=True, server=None): if __name__ == "__main__": if args.version: installer.add_args() - installer.setup_logging(clean=False) installer.log.info('SD.Next version information') installer.check_python() installer.check_version() diff --git a/modules/ui_tempdir.py b/modules/ui_tempdir.py index 7e5849ba5..f8d80d63e 100644 --- a/modules/ui_tempdir.py +++ b/modules/ui_tempdir.py @@ -35,28 +35,39 @@ def check_tmp_file(gradio, filename): return ok -def save_pil_to_file(pil_image, dir=None): # pylint: disable=redefined-builtin - already_saved_as = getattr(pil_image, 'already_saved_as', None) +def pil_to_temp_file(self, img, dir: str, format="png") -> str: # pylint: disable=redefined-builtin,unused-argument + """ + # original gradio implementation + bytes_data = gr.processing_utils.encode_pil_to_bytes(img, format) + temp_dir = Path(dir) / self.hash_bytes(bytes_data) + temp_dir.mkdir(exist_ok=True, parents=True) + filename = str(temp_dir / f"image.{format}") + img.save(filename, pnginfo=gr.processing_utils.get_pil_metadata(img)) + """ + already_saved_as = getattr(img, 'already_saved_as', None) if already_saved_as and os.path.isfile(already_saved_as): register_tmp_file(shared.demo, already_saved_as) file_obj = Savedfile(already_saved_as) - return file_obj + name = file_obj.name + return name if shared.opts.temp_dir != "": dir = shared.opts.temp_dir use_metadata = False metadata = PngImagePlugin.PngInfo() - for key, value in pil_image.info.items(): + for key, value in img.info.items(): if isinstance(key, str) and isinstance(value, str): metadata.add_text(key, value) use_metadata = True file_obj = tempfile.NamedTemporaryFile(delete=False, suffix=".png", dir=dir) - pil_image.save(file_obj, pnginfo=(metadata if use_metadata else None)) - return file_obj + img.save(file_obj, pnginfo=(metadata if use_metadata else None)) + name = file_obj.name + shared.log.debug(f'Saving temp image: {name}') + return name # override save to file function so that it also writes PNG info -gr.processing_utils.save_pil_to_file = save_pil_to_file - +# gr.processing_utils.save_pil_to_file = save_pil_to_file # gradio <=3.31.0 +gr.components.IOComponent.pil_to_temp_file = pil_to_temp_file # gradio >=3.32.0 def on_tmpdir_changed(): if shared.opts.temp_dir == "":