fix var log

This commit is contained in:
Raven Scott
2026-04-21 23:13:19 -04:00
parent d9bf332f07
commit 477de96c4b
3 changed files with 114 additions and 7 deletions
+1
View File
@@ -630,6 +630,7 @@ async function executeKernel(disk, store, swarm, initSource) {
'BARE_OS_SHELL_NOUNSET',
'BARE_OS_TELEMETRY_NDJSON',
'BARE_OS_TELEMETRY_OTEL_JSONL',
'BARE_OS_VAR_LOG_DEBUG',
'BARE_OS_PROC_POLL_MS',
'BARE_OS_TIMER_EVERY_MS_MONOTONIC',
'BARE_OS_TRACE_ID',
+70 -7
View File
@@ -1,11 +1,50 @@
/**
* Append-only UTF-8 logs under logical `/var/log/…` (VFS maps to the personal Hyperdrive).
*
* Until the first successful `mkdir`/`writeFile`, `readdir('/var/log')` may be empty even though
* `lstat('/var/log')` looks like a directory — logs live under `/var/log/bare-os/` on the logical
* tree and on the personal drive under `/.bare-os/…/var/log/<HOME-seg>/` (see `vfs.js` routing).
*
* Failures are best-effort silent unless **`BARE_OS_VAR_LOG_DEBUG=1`** (or `true`): then messages
* go to **`process.stderr`** and **`ctx.console.error`**. Kernel metrics: `varlog.append.*`,
* `varlog.ensure.*` (see `bareOsKernelMetricsSnapshot()`).
*/
import {
BARE_OS_LIFECYCLE_SCHEMA_VERSION,
BARE_OS_TELEMETRY_SCHEMA_VERSION
} from './bare-os-lifecycle-schema.js'
import { bareOsKernelMetricInc } from './bare-os-kernel-metrics.js'
/**
* @param {Record<string, unknown>} ctx
* @param {string} msg
*/
function varLogDebug(ctx, msg) {
try {
const env =
ctx && ctx.env && typeof ctx.env === 'object'
? /** @type {Record<string, string | undefined>} */ (ctx.env)
: /** @type {Record<string, string | undefined>} */ ({})
const on =
env.BARE_OS_VAR_LOG_DEBUG === '1' ||
env.BARE_OS_VAR_LOG_DEBUG === 'true'
if (!on) return
const line = `[bare-os:var-log] ${msg}`
try {
globalThis.process?.stderr?.write?.(line + '\n')
} catch {
/* ignore */
}
try {
ctx?.console?.error?.(line)
} catch {
/* ignore */
}
} catch {
/* ignore */
}
}
export const BARE_OS_VAR_LOG_DIR = '/var/log/bare-os'
@@ -69,18 +108,29 @@ const LOG_KEEP_BYTES = 256 * 1024
export async function ensureBareOsVarLogTree(ctx) {
try {
const vfs = ctx.vfs
if (!vfs || typeof vfs.mkdir !== 'function') return
if (!vfs || typeof vfs.mkdir !== 'function') {
bareOsKernelMetricInc('varlog.ensure.skip_no_vfs_mkdir')
varLogDebug(ctx, 'ensureBareOsVarLogTree: no ctx.vfs.mkdir')
return
}
await vfs.mkdir(BARE_OS_VAR_LOG_DIR, { recursive: true })
if (
typeof vfs.readFile !== 'function' ||
typeof vfs.writeFile !== 'function'
)
) {
bareOsKernelMetricInc('varlog.ensure.skip_no_vfs_rw')
varLogDebug(ctx, 'ensureBareOsVarLogTree: missing vfs.readFile/writeFile')
return
}
const existing = await vfs.readFile(README_REL)
if (existing && ctx.b4a.from(existing).length > 0) return
await vfs.writeFile(README_REL, ctx.b4a.from(README_TEXT))
} catch {
/* ignore */
} catch (e) {
bareOsKernelMetricInc('varlog.ensure.error')
varLogDebug(
ctx,
`ensureBareOsVarLogTree: ${e && e.message ? e.message : String(e)}`
)
}
}
@@ -94,7 +144,14 @@ export async function ensureBareOsVarLogTree(ctx) {
export async function appendVarLog(ctx, logicalFilePath, kind, line) {
try {
const vfs = ctx.vfs
if (!vfs || typeof vfs.readFile !== 'function') return
if (!vfs || typeof vfs.readFile !== 'function') {
bareOsKernelMetricInc('varlog.append.skip_no_vfs_readfile')
varLogDebug(
ctx,
'appendVarLog: no vfs.readFile for ' + String(logicalFilePath)
)
return
}
const prev = await vfs.readFile(logicalFilePath)
const ts = new Date().toISOString()
const chunk = ctx.b4a.from(`[${ts}] [${kind}] ${line}\n`)
@@ -119,8 +176,14 @@ export async function appendVarLog(ctx, logicalFilePath, kind, line) {
kind,
line: String(line).slice(0, 4000)
})
} catch {
/* ignore */
} catch (e) {
bareOsKernelMetricInc('varlog.append.error')
varLogDebug(
ctx,
`appendVarLog(${String(logicalFilePath)}): ${
e && e.message ? e.message : String(e)
}`
)
}
}
+43
View File
@@ -119,6 +119,15 @@ import {
stopBareInitd,
getLastBareInitdDagSnapshotJson
} from './lib/bare-initd.js'
import {
appendVarLog,
ensureBareOsVarLogTree,
KERNEL_CONSOLE_LOG
} from './lib/bare-os-var-log.js'
import {
bareOsKernelMetricsReset,
bareOsKernelMetricsSnapshot
} from './lib/bare-os-kernel-metrics.js'
import { parseUnitDropInText } from './lib/bare-initd-user.js'
import { bareOsProcessTableSnapshot } from './lib/bare-os-process-table.js'
import { buildBareOsSyscallsProcJson } from './lib/bare-os-syscalls-proc-json.js'
@@ -2835,6 +2844,40 @@ test('vfs chdir /var/log from home', async (t) => {
rmSync(dir, { recursive: true, force: true })
})
test('appendVarLog increments skip metric when vfs.readFile missing', async (t) => {
bareOsKernelMetricsReset()
await appendVarLog(
{ b4a, env: {}, vfs: { async writeFile() {} } },
KERNEL_CONSOLE_LOG,
'x',
'line'
)
const snap = bareOsKernelMetricsSnapshot()
t.is(snap['varlog.append.skip_no_vfs_readfile'], 1)
bareOsKernelMetricsReset()
})
test('ensureBareOsVarLogTree + appendVarLog populate personal backing', async (t) => {
const dir = testCorestoreDir('varlogpop')
const store = new Corestore(dir)
const sys = new Hyperdrive(store)
const personal = new Hyperdrive(store.namespace('pvlog'))
await sys.ready()
await personal.ready()
const ctx = testCtx(sys, personal)
await ensureBareOsVarLogTree(ctx)
await appendVarLog(ctx, KERNEL_CONSOLE_LOG, 't', 'hello-var-log')
const backing = await personal.get(
'/.bare-os/var/log/user/bare-os/kernel-console.log'
)
t.ok(backing)
t.ok(b4a.toString(backing).includes('hello-var-log'))
const readme = await personal.get('/.bare-os/var/log/user/bare-os/README')
t.ok(readme && b4a.toString(readme).includes('kernel-console'))
await store.close()
rmSync(dir, { recursive: true, force: true })
})
test('tokenize handles quotes and ops', async (t) => {
const tok = tokenize('ls -la | cat > out')
t.ok(tok.some((x) => x.type === 'op' && x.value === '|'))