fix(logs): capture backend logs by default in single mode (#10742)

Backend log capture into the per-model BackendLogStore (which feeds the
UI "Backend Logs" page and /api/backend-logs) was opt-in and off by
default in single mode, while worker/distributed mode force-enables it
via SetBackendLoggingEnabled(true). There was no CLI flag either, so the
only way to populate the store was the Settings UI toggle - and the page
was silently empty out of the box. Distributed "just worked"; single
mode looked broken.

Default EnableBackendLogging to true in NewApplicationConfig so single
mode matches worker mode. The store is a small in-memory ring buffer, so
the cost is negligible.

Now that the default is on, loadRuntimeSettingsFromFile's usual
"only flip false->true" merge would ignore a persisted false and revert
the UI toggle-off on every restart. There is no env var/CLI flag for
this setting, so an explicit persisted value is now authoritative in
both directions, letting the toggle-off survive a restart.

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
LocalAI [bot]
2026-07-08 14:13:52 +02:00
committed by GitHub
parent 0aaf7cce76
commit 40c29db8c4
3 changed files with 46 additions and 6 deletions

View File

@@ -261,4 +261,35 @@ var _ = Describe("loadRuntimeSettingsFromFile", func() {
Expect(cfg.AgentPool.AgentHubURL).To(Equal("https://hub.acme.io"))
})
})
// Backend logging capture. Worker/distributed mode force-enables it
// (core/services/worker.SetBackendLoggingEnabled(true)); single mode used
// to leave it off by default with no CLI flag, so the UI "Backend Logs"
// page was silently empty unless the operator found the Settings toggle.
// It now defaults on in single mode too. Because the default is on, the
// loader must let a persisted enable_backend_logging=false (the UI
// toggle-off) win over the default - the sticky "only flip false->true"
// merge used for env-backed flags would otherwise ignore it and revert
// the toggle on every restart.
Describe("backend logging capture", func() {
It("captures backend logs by default in single mode", func() {
cfg := config.NewApplicationConfig()
Expect(cfg.EnableBackendLogging).To(BeTrue(),
"single mode should capture backend logs out of the box, matching worker mode")
})
It("honors a persisted enable_backend_logging=false across restart (toggle-off wins over default-on)", func() {
cfg := config.NewApplicationConfig() // default-on boot state
cfg.DynamicConfigsDir = seedSettings(`{"enable_backend_logging": false}`)
loadRuntimeSettingsFromFile(cfg)
Expect(cfg.EnableBackendLogging).To(BeFalse(),
"a UI toggle-off persisted to runtime_settings.json must survive a restart")
})
It("loads a persisted enable_backend_logging=true", func() {
cfg := &config.ApplicationConfig{DynamicConfigsDir: seedSettings(`{"enable_backend_logging": true}`)}
loadRuntimeSettingsFromFile(cfg)
Expect(cfg.EnableBackendLogging).To(BeTrue())
})
})
})

View File

@@ -698,10 +698,12 @@ func loadRuntimeSettingsFromFile(options *config.ApplicationConfig) {
}
}
// Backend logging defaults on in single mode (NewApplicationConfig), so
// the usual "only flip false->true" merge would ignore a persisted false
// and revert the UI toggle-off on every restart. There is no env var/CLI
// flag for it, so an explicit persisted value is authoritative here.
if settings.EnableBackendLogging != nil {
if !options.EnableBackendLogging {
options.EnableBackendLogging = *settings.EnableBackendLogging
}
options.EnableBackendLogging = *settings.EnableBackendLogging
}
// Tracing settings

View File

@@ -246,9 +246,16 @@ type AppOption func(*ApplicationConfig)
func NewApplicationConfig(o ...AppOption) *ApplicationConfig {
opt := &ApplicationConfig{
Context: context.Background(),
UploadLimitMB: 15,
Debug: true,
Context: context.Background(),
UploadLimitMB: 15,
Debug: true,
// Capture backend process stdout/stderr into the per-model
// BackendLogStore by default so the UI "Backend Logs" page works out
// of the box in single mode, matching worker/distributed mode (which
// force-enables it). It's a small in-memory ring buffer; the Settings
// toggle can still turn it off (a persisted false wins - see
// loadRuntimeSettingsFromFile).
EnableBackendLogging: true,
AgentJobRetentionDays: 30, // Default: 30 days
LRUEvictionMaxRetries: 30, // Default: 30 retries
LRUEvictionRetryInterval: 1 * time.Second, // Default: 1 second