Skip to content

feat(config): -logs-dir flag to relocate logs.db out of the config dir#4536

Open
mickgvirtu wants to merge 1 commit into
maximhq:devfrom
mickgvirtu:pr-logs-dir-flag
Open

feat(config): -logs-dir flag to relocate logs.db out of the config dir#4536
mickgvirtu wants to merge 1 commit into
maximhq:devfrom
mickgvirtu:pr-logs-dir-flag

Conversation

@mickgvirtu

Copy link
Copy Markdown

Summary

logs.db is created as a sibling of config.db in the app dir, forcing the config and the large, churning request-log DB onto the same directory/volume. This adds a -logs-dir flag (default from BIFROST_LOGS_DIR, mirroring the -host/BIFROST_HOST precedence) so the two can live on independent mounts — useful for putting logs on separate or ephemeral storage.

Changes

  • New -logs-dir flag threaded main.go → Server.LogsDir → LoadConfig(ctx, configDir, logsDir).
  • Applies to the default SQLite logs store. When the logs store is explicitly configured in config.json or is non-SQLite, the override is ignored with a warning (not silently), so the operator gets feedback.

Type of change

  • Feature

Affected areas

  • Transports (HTTP)

How to test

go test ./transports/bifrost-http/lib/ -run TestLoadConfig_LogsDirRelocatesLogsDB

Covers relocation, the empty-default case, and explicit-config-wins.

@CLAassistant

CLAassistant commented Jun 18, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7ec53bb8-98dc-49a0-abbf-aacc203b8059

📥 Commits

Reviewing files that changed from the base of the PR and between bbeec04 and 6df1ab4.

📒 Files selected for processing (4)
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go
  • transports/bifrost-http/main.go
  • transports/bifrost-http/server/server.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • transports/bifrost-http/main.go
  • transports/bifrost-http/server/server.go
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added a -logs-dir command-line flag and BIFROST_LOGS_DIR environment variable to control where the SQLite logs.db is stored (optionally separate from config.db).
  • Bug Fixes
    • Improved handling of overridden log database locations, including warnings when custom logs_store settings prevent relocation.
  • Tests
    • Added coverage for log database relocation behavior and updated tests for the updated configuration loader signature.

Walkthrough

Adds a LogsDir field to BifrostHTTPServer and a corresponding -logs-dir CLI flag / BIFROST_LOGS_DIR environment variable. LoadConfig accepts a new logsDir parameter to compute the logs.db path separately from config.db. initStores receives a logsDirOverridden flag and conditionally relocates or warns about the stored SQLite path. Existing tests are updated to the new signature, and a new test validates the relocation logic.

Changes

logs.db Directory Override

Layer / File(s) Summary
LogsDir field, LoadConfig signature, and flag wiring
transports/bifrost-http/server/server.go, transports/bifrost-http/main.go
BifrostHTTPServer gains a LogsDir string field; main.go reads BIFROST_LOGS_DIR and registers the -logs-dir flag bound to server.LogsDir; Bootstrap passes s.LogsDir to lib.LoadConfig.
LoadConfig and initStores relocation logic
transports/bifrost-http/lib/config.go
LoadConfig computes logsDBPath from logsDir (defaulting to configDirPath), sets logsDirOverridden, and passes it to initStores. initStores warns when logs_store is explicitly configured and the override is active; for stored SQLite configs it conditionally updates Path to the override location with warnings for non-SQLite or unexpected payload types.
LoadConfig tests: signature update and relocation verification
transports/bifrost-http/lib/config_test.go
All existing LoadConfig call sites are updated to pass "" as the third argument. TestLoadConfig_LogsDirRelocatesLogsDB is added to verify default, overridden, explicit-config-precedence, and auto-creation behaviors.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐇 Hippity-hop, logs in a new spot,
A -logs-dir flag ties the knot!
config.db stays, logs.db roams free,
Overrides are warned, as good code should be.
One extra arg and the rabbit is done — 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature being added: a new -logs-dir flag for relocating logs.db outside the config directory.
Description check ✅ Passed The PR description covers all required template sections: Summary explains the problem and solution, Changes detail the implementation approach, Type is marked, Affected areas identified, How to test includes specific command, and Breaking changes confirmed as No.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

Safe to merge with low risk for first-time deployments; operators who need to change their logs directory after the first startup will find the flag has no effect.

The relocation logic works correctly on the first startup, but UpdateLogsStoreConfig persists the relocated path to config.db and the guard only allows re-relocation when the stored path equals the default. After the first run with -logs-dir /mnt/a, a subsequent -logs-dir /mnt/b is ignored — the old path is kept and re-persisted. The flag is one-shot.

transports/bifrost-http/lib/config.go lines 1009-1022 (relocation guard) and the missing change-logs-dir-between-restarts test case in config_test.go

Important Files Changed

Filename Overview
transports/bifrost-http/lib/config.go Adds logsDir parameter to LoadConfig and relocation logic in initStores; the MkdirAll guard and first-run relocation work correctly, but the stored-path check in the relocation block makes the flag one-shot — changing -logs-dir on a second startup is silently ignored
transports/bifrost-http/lib/config_test.go All existing LoadConfig call sites updated to pass empty logsDir; new TestLoadConfig_LogsDirRelocatesLogsDB covers first-run relocation, directory auto-creation, explicit-config-wins; missing a change-logs-dir-between-restarts subtest that would expose the one-shot bug
transports/bifrost-http/main.go Adds -logs-dir flag with BIFROST_LOGS_DIR env-var default, mirroring the -host/BIFROST_HOST precedence pattern; wiring is correct
transports/bifrost-http/server/server.go Adds LogsDir field to BifrostHTTPServer and threads it into the LoadConfig call; directory creation is handled inside LoadConfig, not here

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant main as main.go
    participant server as BifrostHTTPServer
    participant lc as LoadConfig
    participant is as initStores
    participant cs as ConfigStore (config.db)
    participant ls as LogStore (logs.db)

    main->>server: flag.StringVar(-logs-dir, BIFROST_LOGS_DIR)
    server->>lc: LoadConfig(ctx, configDir, LogsDir)
    lc->>lc: if LogsDir empty use configDir
    lc->>lc: "if LogsDir != configDir os.MkdirAll(LogsDir)"
    lc->>is: initStores(..., logsDBPath, logsDirOverridden)
    is->>cs: GetLogsStoreConfig()
    cs-->>is: storedConfig (nil on first run)
    alt logsDirOverridden and storedConfig not nil
        is->>is: check storedPath empty or default
        note over is: storedPath not default, warn appears explicitly configured
    end
    is->>ls: NewLogStore(logsDBPath)
    ls-->>is: LogsStore
    is->>cs: UpdateLogsStoreConfig(logsDBPath)
    note over cs: persists path for next run
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant main as main.go
    participant server as BifrostHTTPServer
    participant lc as LoadConfig
    participant is as initStores
    participant cs as ConfigStore (config.db)
    participant ls as LogStore (logs.db)

    main->>server: flag.StringVar(-logs-dir, BIFROST_LOGS_DIR)
    server->>lc: LoadConfig(ctx, configDir, LogsDir)
    lc->>lc: if LogsDir empty use configDir
    lc->>lc: "if LogsDir != configDir os.MkdirAll(LogsDir)"
    lc->>is: initStores(..., logsDBPath, logsDirOverridden)
    is->>cs: GetLogsStoreConfig()
    cs-->>is: storedConfig (nil on first run)
    alt logsDirOverridden and storedConfig not nil
        is->>is: check storedPath empty or default
        note over is: storedPath not default, warn appears explicitly configured
    end
    is->>ls: NewLogStore(logsDBPath)
    ls-->>is: LogsStore
    is->>cs: UpdateLogsStoreConfig(logsDBPath)
    note over cs: persists path for next run
Loading

Reviews (2): Last reviewed commit: "config: add -logs-dir flag to relocate l..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
transports/bifrost-http/lib/config_test.go (1)

19348-19369: ⚡ Quick win

Add one non-SQLite explicit logs_store precedence subtest.

This new test covers explicit SQLite precedence, but the stack behavior also includes explicit non-SQLite config ignoring logsDir. Adding that case here would lock the full contract and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@transports/bifrost-http/lib/config_test.go` around lines 19348 - 19369, The
existing test subtest only covers explicit SQLite logs_store configuration
taking precedence over the logsDir override. Add a new subtest using t.Run after
the current one that tests a non-SQLite explicit logs_store type (replace
logstore.LogStoreTypeSQLite with an alternative type) to verify that non-SQLite
explicit configurations also take precedence over the logsDir parameter. Use
similar test structure and assertions as the SQLite case to ensure the explicit
non-SQLite config is honored and the logsDir override is ignored.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@transports/bifrost-http/lib/config.go`:
- Around line 995-1009: The current logic in the else if block that compares
sqliteConfig.Path with logsDBPath and updates the path always overrides stored
SQLite paths when logsDirOverridden is true, but this should only apply to
implicit default paths. To fix this, add an additional check before the
assignment sqliteConfig.Path = logsDBPath to determine whether the stored path
is an explicitly configured operator-defined path versus the implicit default
path. Only apply the override if the stored path matches the implicit default,
allowing explicit logs_store configuration to take precedence over the -logs-dir
override.

---

Nitpick comments:
In `@transports/bifrost-http/lib/config_test.go`:
- Around line 19348-19369: The existing test subtest only covers explicit SQLite
logs_store configuration taking precedence over the logsDir override. Add a new
subtest using t.Run after the current one that tests a non-SQLite explicit
logs_store type (replace logstore.LogStoreTypeSQLite with an alternative type)
to verify that non-SQLite explicit configurations also take precedence over the
logsDir parameter. Use similar test structure and assertions as the SQLite case
to ensure the explicit non-SQLite config is honored and the logsDir override is
ignored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 80654b3f-3962-4767-9374-67576c09447c

📥 Commits

Reviewing files that changed from the base of the PR and between 96bb2bd and bbeec04.

📒 Files selected for processing (4)
  • transports/bifrost-http/lib/config.go
  • transports/bifrost-http/lib/config_test.go
  • transports/bifrost-http/main.go
  • transports/bifrost-http/server/server.go

Comment thread transports/bifrost-http/lib/config.go Outdated
logs.db is derived as a sibling of config.db (Join(configDirPath, "logs.db")), forcing the
config and the large, churning request-log DB onto one directory. Add a -logs-dir flag
(default from BIFROST_LOGS_DIR env, matching the -host/BIFROST_HOST precedence) threaded
through Server.LogsDir -> LoadConfig. Applies to the default SQLite logs store; when the logs
store is explicitly configured in config.json or is non-SQLite the override is ignored with a
warning rather than silently. Adds a test for relocation and the empty-default case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mickgvirtu

Copy link
Copy Markdown
Author

Thanks for the review. Addressed in the latest push:

  • Startup crash when -logs-dir points at a non-existent path (greptile): LoadConfig now os.MkdirAlls the logs dir before opening logs.db (SQLite won't create the parent). Added a logs dir created when it does not exist subtest.
  • Over-aggressive override of an explicitly-configured stored SQLite path (coderabbit): the relocation now only applies when the stored path is the implicit default (next to config.db, or empty). An operator-configured stored path is left unchanged with a warning, so -logs-dir never silently switches an explicitly-chosen logs DB.
  • Explicit-config precedence test: covered for SQLite (explicit logs store config wins over logs dir override). I left out the non-SQLite explicit-config case because initializing a non-SQLite (e.g. Postgres) logstore in a unit test needs a live DB connection — the non-SQLite path is already guarded by the LogStoreType != SQLite warn branch, which is exercised at runtime.

go test ./transports/bifrost-http/lib/ -run TestLoadConfig_LogsDirRelocatesLogsDB passes (relocation, empty-default, explicit-config-wins, auto-created dir).

Comment on lines +1009 to +1022
if logsDirOverridden && logStoreConfig != nil {
if logStoreConfig.Type != logstore.LogStoreTypeSQLite {
logger.Warn("logs dir override ignored: stored logs store is %s, not SQLite (-logs-dir / BIFROST_LOGS_DIR only relocates the SQLite logs.db)", logStoreConfig.Type)
} else if sqliteConfig, ok := logStoreConfig.Config.(*logstore.SQLiteConfig); !ok {
logger.Warn("logs dir override ignored: stored SQLite logs store has an unexpected config payload; cannot relocate logs.db")
} else if sqliteConfig.Path == "" || sqliteConfig.Path == defaultSQLiteLogsDBPath {
if sqliteConfig.Path != logsDBPath {
logger.Info("logs dir override: relocating logs.db from stored path %s to %s", sqliteConfig.Path, logsDBPath)
sqliteConfig.Path = logsDBPath
}
} else if sqliteConfig.Path != logsDBPath {
logger.Warn("logs dir override ignored: stored SQLite path %s appears explicitly configured; keeping it unchanged", sqliteConfig.Path)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 -logs-dir is silently one-shot after the first startup

On the first startup with -logs-dir /mnt/a, logStoreConfig is nil (nothing in DB yet), so the relocation block is skipped and a new config with Path: /mnt/a/logs.db is created and then persisted to config.db via UpdateLogsStoreConfig at line 1069. On the second startup with -logs-dir /mnt/b, GetLogsStoreConfig returns {Path: "/mnt/a/logs.db"}. The guard at line 1014 only permits relocation when the stored path is empty or equals defaultSQLiteLogsDBPath (i.e. $configDir/logs.db). Since /mnt/a/logs.db matches neither, control falls to line 1019 and logs a warning: "stored SQLite path appears explicitly configured; keeping it unchanged". The flag has no effect and /mnt/a/logs.db is persisted back again.

The code cannot distinguish "this path was written by a previous -logs-dir invocation" from "this path was explicitly set by the operator via the dashboard/API". The simplest fix is: when logsDirOverridden is true, always replace the stored path with logsDBPath — the flag is the operator's explicit runtime intent. Operators who want a pinned path via config.json are already protected by the explicit-config-wins branch earlier in this function. A subtest for "second startup with a changed logs dir" would catch this regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants