Skip to content

Add runtime log level override: system/server_setting, admin UI, docs - #138

Draft
nicdavidson wants to merge 5 commits into
mainfrom
fix/df-system-65-66-df-admin-interface-552-df-docs-137
Draft

nicdavidson wants to merge 5 commits into
mainfrom
fix/df-system-65-66-df-admin-interface-552-df-docs-137

Conversation

@nicdavidson

@nicdavidson nicdavidson commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Refs dreamfactorysoftware/df-system#65, dreamfactorysoftware/df-system#66, dreamfactorysoftware/df-admin-interface#552, #137

What

  • Server settings override layer (DB-backed, allow-listed, log level first) df-system#66: DB-backed override layer for an allow-listed set of settings, starting with log_level. New server_settings table (migration included) and ServerSetting model. Overrides are applied at boot on top of config and are never written into the config:cache file. Stored overrides are cached for 60 s, so a warm boot makes no server_settings query, with or without rows. Writes clear the cache; a cache failure falls back to the DB.
  • Edit server settings (log level first) from the admin UI df-system#65: New system/server_setting resource (GET, PATCH/PUT, DELETE). Access is checked like any other system resource (cache, cors): full admins, or a role with server_setting/* on system. Everyone else gets 403. Each successful change or reset writes a Server setting changed line (setting, old value, new value, user id) to its own fixed-level log channel. No-op changes are not audited.
  • Server settings page: view source and edit log level (sys admin only) df-admin-interface#552: Server Settings page under System > Config. It shows the value, an .env / override badge, a level picker, Save, and a confirmed "Reset to .env value". After a save it links on to System Info. System Info and the overview Log Level tile get a "Change" link. The nav entry, deep link, System Info link and overview tile all use one rule: a full admin, or a restricted admin whose tabs include Config.
  • Document runtime server settings overrides (system API, precedence, config:cache, audit log) #137: New system-settings/server-settings page (allowed values, precedence, config:cache, effect timing across nodes, role-based access, curl examples with the real 403 body, audit log). basic-configuration.md and system-api.md link to it.
  • df-compliance (no separate issue): adds server_setting/* to the Config tab in RestrictedAdmin, so restricted admins created with Config get API access.

Behavior change

  • Administrators can now change the log level at runtime from the admin UI or system/server_setting, without editing .env or restarting. It applies immediately on the node that served the change. Other nodes with their own cache (file or array) pick it up within 60 seconds. Nodes with a shared cache (redis, memcached, database) pick it up on their next request. Queue and scheduler workers pick it up when restarted.
  • A stored override wins over APP_LOG_LEVEL. Removing the override restores the .env value.
  • Setting log_level changes the four channels that follow APP_LOG_LEVEL (single, daily, syslog, errorlog). stderr, slack and other channels with their own level are not changed.
  • Access to system/server_setting is role-based. A restricted admin created or re-saved with the Config tab gets server_setting/*. Restricted admins created before this release keep their Config tab but do not have server_setting/* until a root admin opens them, changes any field (for example, clears and re-ticks one access tab) and saves. Until then they see the Server Settings entry and get "Could not load server settings." (403). Saving without changing anything sends nothing.
  • No secrets or database settings can be overridden.
  • Existing installs need the new server_settings table (migration included). Until it exists, behavior is unchanged.
  • Rerouted/added flows (UI standard):
    • The Log Level value on System Info stays read-only but now has a "Change" link to the new page.
    • The overview Log Level tile links there too.
    • A new "Server Settings" entry appears in the sidenav under Config.
    • A restricted admin without Config gets no entry, and a deep link redirects Home.
    • sysAdminGuard is replaced by serverSettingsGuard, which waits for the restricted admin's real tabs.

Tests

  • df-system tests/ServerSettingsTest.php (18 tests) covers: override beats .env and reaches the channel levels; no row leaves config unchanged; disallowed keys and invalid levels are rejected; unknown rows are ignored at boot; boot without the table does not throw; API GET, PATCH and DELETE round trip; audit line written at the stock warning level; invalid PATCH and no-op reset not audited; a role with server_setting/* is allowed; a role without it gets 403; stderr stays untouched; a warm-cache boot makes no query (with and without rows); writes are visible on the next boot; a cache failure still applies the override.
  • df-compliance tests/RestrictedAdminsTest.php: a Config restricted admin's role gets server_setting/*; a role with the old Config accesses still has the Config tab; a plain re-save grants server_setting/* to an existing Config admin.
  • df-admin-interface: Jest specs for the service, the component, the guard (restricted admin with Config allowed; without Config redirected Home), the access rule (5 cases), route filtering, and the System Info link, all in jest.config.ci.js. Playwright server-settings.spec.ts covers the full-admin flow and restricted-admin cases with and without Config.
  • df-docs: site builds and the new page is generated.

Summary lines on the branch:

  • PHP (df-system, df-compliance, df-core, df-user, in the order the suites ran): Tests: 118, Assertions: 314, Errors: 2, Failures: 4, PHPUnit Deprecations: 2. | Tests: 11, Assertions: 28, Errors: 4, Failures: 1, PHPUnit Deprecations: 1. | Tests: 62, Assertions: 195, Failures: 3, PHPUnit Warnings: 1, PHPUnit Deprecations: 1, Skipped: 4, Risky: 4. | Tests: 49, Assertions: 92, Errors: 15, Failures: 2, PHPUnit Deprecations: 1, Risky: 14.
    • The new tests pass. Every remaining failure is on this item's known-failures list (AdminResourceTest, PackageTest, SystemServiceTest, ServiceManagerTest, AccessCheckMiddlewareTest, df-compliance baseline tests, df-user AlternateAuth, PasswordResource, RegisterResource and UserResource tests). They are not caused by this change.
  • df-admin-interface: Jest Tests: 332 passed, 332 total; production build OK build: 93 files; Playwright OK e2e: e2e/smoke.spec.ts e2e/server-settings.spec.ts.
  • df-docs: OK docs build (36 failures already present on base, listed in the known-failures file).

Scope

  • In: log_level only. Repos changed: df-system, df-compliance, df-admin-interface, df-docs. The four PRs belong together. df-system must merge first, and df-compliance has no effect without it.
  • Out: other settings keys, per-channel keys, writing .env, restarting workers, a history table for audit, and a df-compliance migration that backfills server_setting/* into existing Config roles (it would grant privileges on existing data, so it needs a decision).
  • Tested at small scale only (one setting, so no long-list handling is needed).

Related issues

Open questions for the team: whether to backfill existing Config restricted admins with a migration, whether a history table is wanted (the audit entry is a log line, not a durable store), and whether separate per-channel keys are wanted.

Existing bugs found but not fixed

  • df-compliance: a re-save re-adds every access of every kept tab, not only the optional ones. A hand-narrowed row (say cors/* limited to API requestors) gets a second, wider row on re-save. Fix: filter the kept-tab additions to optional entries.
  • df-admin-interface: the explanatory comment above rootAdminGuard in admin.guard.ts was deleted. The df-server-settings.service.ts docblock still says "sys admin only". The i18n hint "Applies on the next request" ignores the up-to-60 s lag on other nodes.
  • df-compliance: CHANGELOG.md is not updated.
  • df-system: testRoleWithoutServerSettingAccessForbidden only exercises df-core's role check, and testConfigCacheDoesNotBakeOverride repeats the provider's guard instead of running config:cache. Neither would fail if this change broke.
  • The audit channel is a fixed file under storage/logs, so it is not visible on installs using LOG_CHANNEL=stderr. The docs name the path.
  • The overview tile strings are hardcoded English, like the neighbouring tiles.
  • The stock test container has no JWT secret, so Session::authenticate fails there. The tests seed the admin session directly.

…onfig:cache, audit log) (df-system#65+66 + df-admin-interface#552 + df-docs#137)
…df-system#65+66 + df-admin-interface#552 + df-docs#137)
@netlify

netlify Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for dreamfactory-docs ready!

Name Link
🔨 Latest commit e376100
🔍 Latest deploy log https://app.netlify.com/projects/dreamfactory-docs/deploys/6ae2b87f5bd4798e17f3fc67
😎 Deploy Preview https://deploy-preview-138--dreamfactory-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

…er settings (df-system#65+66 + df-admin-interface#552 + df-docs#137)
…g restricted admins (df-system#65+66 + df-admin-interface#552 + df-docs#137)
…ds nothing (df-system#65+66 + df-admin-interface#552 + df-docs#137)
@nicdavidson nicdavidson changed the title Add sys-admin runtime log level override (system/server_setting + UI + docs) Add runtime log level override: system/server_setting, admin UI, docs Oct 29, 2026

This branch has not been deployed

No deployments
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.

1 participant