unified logger

This commit is contained in:
Vladimir Mandic
2026-02-19 09:46:42 +01:00
parent bfe014f5da
commit a3074baf8b
315 changed files with 2507 additions and 2116 deletions
+4 -3
View File
@@ -4,6 +4,7 @@ from fastapi import FastAPI, APIRouter, Depends, Request
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from fastapi.exceptions import HTTPException
from modules import errors, shared
from modules import logger
from modules.api import models, endpoints, script, helpers, server, generate, process, control, docs, gpu
@@ -142,13 +143,13 @@ class Api:
if hasattr(self.app, 'tokens') and (self.app.tokens is not None):
if credentials.password in self.app.tokens.keys():
return True
shared.log.error(f'API authentication: user="{credentials.username}"')
logger.log.error(f'API authentication: user="{credentials.username}"')
raise HTTPException(status_code=401, detail="Unauthorized", headers={"WWW-Authenticate": "Basic"})
def get_session_start(self, req: Request, agent: str | None = None):
token = req.cookies.get("access-token") or req.cookies.get("access-token-unsecure")
user = self.app.tokens.get(token) if hasattr(self.app, 'tokens') else None
shared.log.info(f'Browser session: user={user} client={req.client.host} agent={agent}')
logger.log.info(f'Browser session: user={user} client={req.client.host} agent={agent}')
return {}
def launch(self):
@@ -165,7 +166,7 @@ class Api:
# from modules.server import HypercornServer
# server = HypercornServer(self.app, **config)
http_server.start()
shared.log.info(f'API server: Uvicorn options={config}')
logger.log.info(f'API server: Uvicorn options={config}')
return http_server
+2 -1
View File
@@ -2,6 +2,7 @@ from typing import Optional
from threading import Lock
from pydantic import BaseModel, Field # pylint: disable=no-name-in-module
from modules import errors, shared, processing_helpers
from modules import logger
from modules.api import models, helpers
from modules.control import run
@@ -156,7 +157,7 @@ class APIControl:
if req.unit_type is None:
req.unit_type = 'controlnet'
if req.unit_type not in unit_types:
shared.log.error(f'Control uknown unit type: type={req.unit_type} available={unit_types}')
logger.log.error(f'Control uknown unit type: type={req.unit_type} available={unit_types}')
return
for i in range(len(req.control)):
u = req.control[i]
+2 -1
View File
@@ -1,3 +1,4 @@
from modules import logger
from modules import shared
from modules.api import models, helpers
@@ -90,7 +91,7 @@ def get_schedulers():
from modules.sd_samplers import list_samplers
all_schedulers = list_samplers()
for s in all_schedulers:
shared.log.critical(s)
logger.log.critical(s)
return all_schedulers
def post_unload_checkpoint():
+8 -7
View File
@@ -9,10 +9,11 @@ from starlette.websockets import WebSocket, WebSocketState
from pydantic import BaseModel, Field # pylint: disable=no-name-in-module
from PIL import Image
from modules import shared, images, files_cache, modelstats
from modules import logger
from modules.paths import resolve_output_path
debug = shared.log.debug if os.environ.get('SD_BROWSER_DEBUG', None) is not None else lambda *args, **kwargs: None
debug = logger.log.debug if os.environ.get('SD_BROWSER_DEBUG', None) is not None else lambda *args, **kwargs: None
OPTS_FOLDERS = [
@@ -96,7 +97,7 @@ def register_api(app: FastAPI): # register api
}
return content
except Exception as e:
shared.log.error(f'Gallery video: file="{filepath}" {e}')
logger.log.error(f'Gallery video: file="{filepath}" {e}')
return {}
def get_image_thumbnail(filepath):
@@ -123,7 +124,7 @@ def register_api(app: FastAPI): # register api
}
return content
except Exception as e:
shared.log.error(f'Gallery image: file="{filepath}" {e}')
logger.log.error(f'Gallery image: file="{filepath}" {e}')
return {}
# @app.get('/sdapi/v1/browser/folders', response_model=List[str])
@@ -183,7 +184,7 @@ def register_api(app: FastAPI): # register api
else:
return JSONResponse(content=get_image_thumbnail(decoded))
except Exception as e:
shared.log.error(f'Gallery: {file} {e}')
logger.log.error(f'Gallery: {file} {e}')
content = { 'error': str(e) }
return JSONResponse(content=content)
@@ -199,10 +200,10 @@ def register_api(app: FastAPI): # register api
msg = msg[:1] + ":" + msg[4:] if msg[1:4] == "%3A" else msg
lines.append(msg)
t1 = time.time()
shared.log.debug(f'Gallery: type=ht folder="{folder}" files={len(lines)} time={t1-t0:.3f}')
logger.log.debug(f'Gallery: type=ht folder="{folder}" files={len(lines)} time={t1-t0:.3f}')
return lines
except Exception as e:
shared.log.error(f'Gallery: {folder} {e}')
logger.log.error(f'Gallery: {folder} {e}')
return []
shared.api.add_api_route("/sdapi/v1/browser/folders", get_folders, methods=["GET"], response_model=list[str])
@@ -228,7 +229,7 @@ def register_api(app: FastAPI): # register api
await manager.send(ws, msg)
await manager.send(ws, '#END#')
t1 = time.time()
shared.log.debug(f'Gallery: type=ws folder="{folder}" files={numFiles} time={t1-t0:.3f}')
logger.log.debug(f'Gallery: type=ws folder="{folder}" files={numFiles} time={t1-t0:.3f}')
except Exception as e:
debug(f'Browser WS error: {e}')
manager.disconnect(ws)
+1 -1
View File
@@ -1,5 +1,5 @@
import torch
from installer import log
from modules.logger import log
device = None
+5 -4
View File
@@ -5,6 +5,7 @@ import piexif
import piexif.helper
from fastapi.exceptions import HTTPException
from modules import shared, sd_samplers
from modules import logger
def validate_sampler_name(name):
@@ -25,7 +26,7 @@ def decode_base64_to_image(encoding, quiet=False):
image = Image.open(data)
return image
except Exception as e:
shared.log.warning(f'API cannot decode image: {e}')
logger.log.warning(f'API cannot decode image: {e}')
# from modules import errors
# errors.display(e, 'API cannot decode image')
if not quiet:
@@ -41,7 +42,7 @@ def encode_pil_to_base64(image):
return base64.b64encode(bytes_data)
"""
if not isinstance(image, Image.Image):
shared.log.error('API cannot encode image: not a PIL image')
logger.log.error('API cannot encode image: not a PIL image')
return ''
buffered = io.BytesIO()
save_image(image, fn=buffered, ext=shared.opts.samples_format)
@@ -66,7 +67,7 @@ def save_image(image, fn, ext):
image.save(fn, format=image_format, quality=shared.opts.jpeg_quality, pnginfo=pnginfo_data)
elif image_format == 'JPEG':
if image.mode == 'RGBA':
shared.log.warning('Save: RGBA image as JPEG - removed alpha channel')
logger.log.warning('Save: RGBA image as JPEG - removed alpha channel')
image = image.convert("RGB")
elif image.mode == 'I;16':
image = image.point(lambda p: p * 0.0038910505836576).convert("L")
@@ -87,5 +88,5 @@ def save_image(image, fn, ext):
exif_bytes = piexif.dump({ "Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(parameters or "", encoding="unicode") } })
image.save(fn, format=image_format, quality=shared.opts.jpeg_quality, lossless=shared.opts.webp_lossless, exif=exif_bytes)
else:
# shared.log.warning(f'Unrecognized image format: {extension} attempting save as {image_format}')
# logger.log.warning(f'Unrecognized image format: {extension} attempting save as {image_format}')
image.save(fn, format=image_format, quality=shared.opts.jpeg_quality)
+1 -1
View File
@@ -10,7 +10,7 @@ from starlette.responses import JSONResponse
from fastapi import FastAPI, Request, Response
from fastapi.exceptions import HTTPException
from fastapi.encoders import jsonable_encoder
from installer import log
from modules.logger import log
import modules.errors as errors
+2 -1
View File
@@ -1,5 +1,6 @@
try:
from installer import install, log
from installer import install
from modules.logger import log
except Exception:
def install(*args, **kwargs): # pylint: disable=unused-argument
pass
+1 -1
View File
@@ -5,7 +5,7 @@ from enum import IntFlag
try:
from installer import log
from modules.logger import log
except Exception:
import logging
log = logging.getLogger(__name__)
+13 -12
View File
@@ -5,11 +5,12 @@ from fastapi import Request, Depends
from fastapi.exceptions import HTTPException
from fastapi.responses import FileResponse
from modules import shared
from modules import logger
from modules.api import models, helpers
def post_shutdown():
shared.log.info('Shutdown request received')
logger.log.info('Shutdown request received')
import sys
sys.exit(0)
@@ -21,7 +22,7 @@ def get_js(request: Request):
if ext not in ['js', 'css', 'map', 'html', 'wasm', 'ttf', 'mjs', 'json']:
raise HTTPException(status_code=400, detail=f"invalid file extension: {ext}")
if not os.path.exists(file):
shared.log.error(f"API: file not found: {file}")
logger.log.error(f"API: file not found: {file}")
raise HTTPException(status_code=404, detail=f"file not found: {file}")
if ext in ['js', 'mjs']:
media_type = 'application/javascript'
@@ -50,12 +51,12 @@ def get_motd():
res = requests.get('https://vladmandic.github.io/sdnext/motd', timeout=3)
if res.status_code == 200:
msg = (res.text or '').strip()
shared.log.info(f'MOTD: {msg if len(msg) > 0 else "N/A"}')
logger.log.info(f'MOTD: {msg if len(msg) > 0 else "N/A"}')
motd += res.text
else:
shared.log.error(f'MOTD: {res.status_code}')
logger.log.error(f'MOTD: {res.status_code}')
except Exception as err:
shared.log.error(f'MOTD: {err}')
logger.log.error(f'MOTD: {err}')
return motd
def get_version():
@@ -67,18 +68,18 @@ def get_platform():
return { **installer_get_platform(), **loader_get_packages() }
def get_log(req: models.ReqGetLog = Depends()):
lines = shared.log.buffer[:req.lines] if req.lines > 0 else shared.log.buffer.copy()
lines = logger.log.buffer[:req.lines] if req.lines > 0 else logger.log.buffer.copy()
if req.clear:
shared.log.buffer.clear()
logger.log.buffer.clear()
return lines
def post_log(req: models.ReqPostLog):
if req.message is not None:
shared.log.info(f'UI: {req.message}')
logger.log.info(f'UI: {req.message}')
if req.debug is not None:
shared.log.debug(f'UI: {req.debug}')
logger.log.debug(f'UI: {req.debug}')
if req.error is not None:
shared.log.error(f'UI: {req.error}')
logger.log.error(f'UI: {req.error}')
return {}
@@ -132,8 +133,8 @@ def get_progress(req: models.ReqProgress = Depends()):
progress = min((current / total) if current > 0 and total > 0 else 0, 1)
time_since_start = time.time() - shared.state.time_start
eta_relative = (time_since_start / progress) - time_since_start if progress > 0 else 0
# shared.log.critical(f'get_progress: batch {batch_x}/{batch_y} step {step_x}/{step_y} current {current}/{total} time={time_since_start} eta={eta_relative}')
# shared.log.critical(shared.state)
# logger.log.critical(f'get_progress: batch {batch_x}/{batch_y} step {step_x}/{step_y} current {current}/{total} time={time_since_start} eta={eta_relative}')
# logger.log.critical(shared.state)
res = models.ResProgress(id=shared.state.id, progress=round(progress, 2), eta_relative=round(eta_relative, 2), current_image=current_image, textinfo=shared.state.textinfo, state=shared.state.dict(), )
return res
+1 -1
View File
@@ -1,5 +1,5 @@
try:
from installer import log
from modules.logger import log
except Exception:
import logging
log = logging.getLogger(__name__)