diff --git a/extensions-builtin/clip-interrogator-ext b/extensions-builtin/clip-interrogator-ext
index 4d865c547..c0bf90052 160000
--- a/extensions-builtin/clip-interrogator-ext
+++ b/extensions-builtin/clip-interrogator-ext
@@ -1 +1 @@
-Subproject commit 4d865c5476813d304b1321c25dea8ddb1844d1bd
+Subproject commit c0bf90052a14a104b2dbfd9b7e7818aae5ca5ae1
diff --git a/javascript/dragdrop.js b/javascript/dragDrop.js
similarity index 100%
rename from javascript/dragdrop.js
rename to javascript/dragDrop.js
diff --git a/javascript/edit-attention.js b/javascript/editAttention.js
similarity index 100%
rename from javascript/edit-attention.js
rename to javascript/editAttention.js
diff --git a/javascript/imageviewer.js b/javascript/imageViewer.js
similarity index 100%
rename from javascript/imageviewer.js
rename to javascript/imageViewer.js
diff --git a/javascript/logMonitor.js b/javascript/logMonitor.js
new file mode 100644
index 000000000..f8718f0db
--- /dev/null
+++ b/javascript/logMonitor.js
@@ -0,0 +1,45 @@
+let logMonitorEl = null;
+
+async function logMonitor() {
+ setTimeout(logMonitor, opts.logmonitor_refresh_period);
+ if (logMonitorEl) logMonitorEl.parentElement.style.display = opts.logmonitor_show ? 'block' : 'none';
+ if (!opts.logmonitor_show) return;
+ const res = await fetch('/sdapi/v1/log?clear=True');
+ if (res?.ok) {
+ if (!logMonitorEl) logMonitorEl = document.getElementById('logMonitorData');
+ if (!logMonitorEl) return;
+ logMonitorEl.parentElement.style.display = 'block';
+ const lines = await res.json();
+ for (const line of lines) {
+ const l = JSON.parse(line);
+ const row = document.createElement("tr");
+ row.style = 'padding: 10px; margin: 0;';
+ row.innerHTML = `
${new Date(1000 * l.created).toISOString()} | ${l.level} | ${l.facility} | ${l.module} | ${l.msg} | `;
+ logMonitorEl.appendChild(row);
+ while (logMonitorEl.childElementCount > 100) logMonitorEl.removeChild(logMonitorEl.firstChild);
+ logMonitorEl.scrollTop = logMonitorEl.scrollHeight
+ }
+ }
+}
+
+async function logMonitorCreate() {
+ const el = document.getElementsByTagName('footer')[0];
+ if (!el) return;
+ el.classList.add('log-monitor');
+ el.innerHTML = `
+
+
+
+ | Time |
+ Level |
+ Facility |
+ Module |
+ Message |
+
+
+
+
+
+ `;
+ logMonitor();
+}
diff --git a/javascript/progressbar.js b/javascript/progressBar.js
similarity index 100%
rename from javascript/progressbar.js
rename to javascript/progressBar.js
diff --git a/javascript/prompt-bracket-checker.js b/javascript/promptBracketChecker.js
similarity index 100%
rename from javascript/prompt-bracket-checker.js
rename to javascript/promptBracketChecker.js
diff --git a/javascript/set-hints.js b/javascript/setHints.js
similarity index 97%
rename from javascript/set-hints.js
rename to javascript/setHints.js
index d62263c87..f3bcca0f5 100644
--- a/javascript/set-hints.js
+++ b/javascript/setHints.js
@@ -58,7 +58,10 @@ async function setHints() {
];
if (elements.length === 0) return;
if (Object.keys(opts).length === 0) return;
- if (!locale.el) tooltipCreate();
+ if (!locale.el) {
+ tooltipCreate();
+ logMonitorCreate();
+ }
let localized = 0;
let hints = 0;
locale.finished = true;
diff --git a/javascript/style.css b/javascript/style.css
index 15aa476fe..3f0035073 100644
--- a/javascript/style.css
+++ b/javascript/style.css
@@ -49,9 +49,6 @@ button.custom-button{
text-align: center;
}
-/* remove footer */
-footer { display: none !important; }
-
/* themes */
.theme-preview { display: none; position: fixed; border: 4px solid var(--neutral-600); box-shadow: 2px 2px 2px 2px var(--neutral-700); top: 0; bottom: 0; left: 0; right: 0; margin: auto; max-width: 75vw; z-index: 999; }
@@ -668,3 +665,14 @@ div.controlnet_main_options { display: grid; grid-template-columns: 1fr 1fr; gri
#refresh_tac_refreshTempFiles { display: none; }
#train_tab { flex-flow: row-reverse; }
#models_tab { flex-flow: row-reverse; }
+
+.log-monitor {
+ display: none;
+ justify-content: unset !important;
+ overflow: hidden;
+ padding: 0;
+ margin-top: auto;
+ font-family: monospace;
+ font-size: 0.85em;
+}
+.log-monitor td, .log-monitor th { padding-left: 1em; }
diff --git a/javascript/textualInversion.js b/javascript/trainMonitor.js
similarity index 100%
rename from javascript/textualInversion.js
rename to javascript/trainMonitor.js
diff --git a/modules/api/api.py b/modules/api/api.py
index f92c59662..2505b0891 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -25,6 +25,7 @@ from modules import devices
errors.install()
+
def upscaler_to_index(name: str):
try:
return [x.name.lower() for x in shared.sd_upscalers].index(name.lower())
@@ -157,8 +158,12 @@ class Api:
return True
raise HTTPException(status_code=401, detail="Unauthorized", headers={"WWW-Authenticate": "Basic"})
- def get_log_buffer(self):
- return shared.log.buffer
+
+ def get_log_buffer(self, req: models.LogRequest = Depends()):
+ lines = shared.log.buffer[:req.lines] if req.lines > 0 else shared.log.buffer.copy()
+ if req.clear:
+ shared.log.buffer.clear()
+ return lines
def get_selectable_script(self, script_name, script_runner):
if script_name is None or script_name == "":
diff --git a/modules/api/models.py b/modules/api/models.py
index 07813d0c2..1b3399f18 100644
--- a/modules/api/models.py
+++ b/modules/api/models.py
@@ -173,6 +173,10 @@ class PNGInfoResponse(BaseModel):
info: str = Field(title="Image info", description="A string with the parameters used to generate the image")
items: dict = Field(title="Items", description="An object containing all the info the image had")
+class LogRequest(BaseModel):
+ lines: int = Field(default=100, title="Lines", description="How many lines to return")
+ clear: bool = Field(default=False, title="Clear", description="Should the log be cleared after returning the lines?")
+
class ProgressRequest(BaseModel):
skip_current_image: bool = Field(default=False, title="Skip current image", description="Skip current image serialization")
diff --git a/modules/lycoris b/modules/lycoris
index 0b7f34c16..4c2001111 160000
--- a/modules/lycoris
+++ b/modules/lycoris
@@ -1 +1 @@
-Subproject commit 0b7f34c16bc133c4c33997364a7cdc3534319d29
+Subproject commit 4c200111133938d037c39dcc7d8481e4c1eecd20
diff --git a/modules/shared.py b/modules/shared.py
index 5328c2d6a..092ae8214 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -442,7 +442,9 @@ options_templates.update(options_section(('live-preview', "Live Previews"), {
"show_progress_every_n_steps": OptionInfo(1, "Live preview display period", gr.Slider, {"minimum": -1, "maximum": 32, "step": 1}),
"show_progress_type": OptionInfo("Approximate NN", "Live preview method", gr.Radio, {"choices": ["Full VAE", "Approximate NN", "Approximate simple", "TAESD"]}),
"live_preview_content": OptionInfo("Combined", "Live preview subject", gr.Radio, {"choices": ["Combined", "Prompt", "Negative prompt"]}),
- "live_preview_refresh_period": OptionInfo(250, "Progressbar/preview update period, in milliseconds")
+ "live_preview_refresh_period": OptionInfo(250, "Progressbar/preview update period, in milliseconds", gr.Slider, {"minimum": 0, "maximum": 5000, "step": 25}),
+ "logmonitor_show": OptionInfo(True, "Show log view"),
+ "logmonitor_refresh_period": OptionInfo(1000, "Log view update period, in milliseconds", gr.Slider, {"minimum": 0, "maximum": 5000, "step": 25}),
}))
options_templates.update(options_section(('sampler-params', "Sampler Settings"), {
diff --git a/pyproject.toml b/pyproject.toml
index ac09272ce..a1ce7ca3d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -29,6 +29,7 @@ select = [
# "PL",
]
exclude = [
+ "/usr/lib",
"extensions",
"extensions-builtin",
"modules/lora",