fix(observability): avoid false stopped Flynn status outside systemd

This commit is contained in:
William Valentin
2026-02-22 21:02:17 -08:00
parent 0a5972a732
commit 7206a94871
2 changed files with 78 additions and 7 deletions
@@ -253,4 +253,67 @@ describe('ObservabilityCollector', () => {
expect(typeof logs.lines[0]?.ts).toBe('number'); expect(typeof logs.lines[0]?.ts).toBe('number');
expect(logs.lines[0]?.text).toContain('queue depth high'); expect(logs.lines[0]?.text).toContain('queue depth high');
}); });
it('falls back to process-running Flynn status when not launched under systemd', async () => {
const originalInvocationId = process.env.INVOCATION_ID;
const originalJournalStream = process.env.JOURNAL_STREAM;
const originalSystemdExecPid = process.env.SYSTEMD_EXEC_PID;
delete process.env.INVOCATION_ID;
delete process.env.JOURNAL_STREAM;
delete process.env.SYSTEMD_EXEC_PID;
const runner = async (command: string, args: string[]) => {
const key = `${command} ${args.join(' ')}`;
if (key === 'systemctl show flynn.service --property=LoadState,ActiveState,SubState,Description,ExecMainPID,Result --no-pager') {
return {
stdout: 'LoadState=loaded\nActiveState=inactive\nSubState=dead\nDescription=Flynn daemon\nExecMainPID=0\nResult=success\n',
stderr: '',
};
}
if (key === 'systemctl --user show ollama.service --property=LoadState,ActiveState,SubState,UnitFileState,Description,ExecMainPID,Result --no-pager') {
return { stdout: 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nDescription=Ollama\nExecMainPID=0\nResult=not-found\n', stderr: '' };
}
if (key === 'systemctl --user show llama-server.service --property=LoadState,ActiveState,SubState,UnitFileState,Description,ExecMainPID,Result --no-pager') {
return { stdout: 'LoadState=not-found\nActiveState=inactive\nSubState=dead\nDescription=llama.cpp\nExecMainPID=0\nResult=not-found\n', stderr: '' };
}
if (key === 'docker compose -f docker-compose.yml config --profiles') {
return { stdout: '', stderr: '' };
}
if (key === 'docker compose -f docker-compose.yml config --services') {
return { stdout: 'flynn\n', stderr: '' };
}
if (key === 'docker compose -f docker-compose.yml ps --all --format json') {
return { stdout: '[]', stderr: '' };
}
throw new Error(`Unexpected command: ${key}`);
};
try {
const collector = new ObservabilityCollector({
config: createConfig(),
runner,
});
await collector.forceSample();
const sources = await collector.listSources();
const flynn = sources.find((entry) => entry.id === 'systemd:flynn');
expect(flynn?.status).toBe('running');
expect(flynn?.logCapable).toBe(false);
} finally {
if (originalInvocationId === undefined) {
delete process.env.INVOCATION_ID;
} else {
process.env.INVOCATION_ID = originalInvocationId;
}
if (originalJournalStream === undefined) {
delete process.env.JOURNAL_STREAM;
} else {
process.env.JOURNAL_STREAM = originalJournalStream;
}
if (originalSystemdExecPid === undefined) {
delete process.env.SYSTEMD_EXEC_PID;
} else {
process.env.SYSTEMD_EXEC_PID = originalSystemdExecPid;
}
}
});
}); });
+15 -7
View File
@@ -130,6 +130,10 @@ interface SampleRecord {
restartCount: number; restartCount: number;
} }
function isGatewayRunningUnderSystemd(): boolean {
return Boolean(process.env.INVOCATION_ID || process.env.JOURNAL_STREAM || process.env.SYSTEMD_EXEC_PID);
}
function defaultRunner( function defaultRunner(
command: string, command: string,
args: string[], args: string[],
@@ -665,24 +669,28 @@ export class ObservabilityCollector {
const snapshots: SourceSnapshot[] = []; const snapshots: SourceSnapshot[] = [];
const flynnMapped = mapSystemdStatus(flynnStatus.activeState, flynnStatus.error); const flynnMapped = mapSystemdStatus(flynnStatus.activeState, flynnStatus.error);
const fallbackToProcessRuntime = !isGatewayRunningUnderSystemd() && flynnMapped.status !== 'running';
const flynnStatusValue = fallbackToProcessRuntime ? 'running' : flynnMapped.status;
const flynnStateCode = fallbackToProcessRuntime ? STATE_RUNNING : flynnMapped.stateCode;
const flynnHealthCode = fallbackToProcessRuntime ? HEALTH_HEALTHY : flynnMapped.healthCode;
snapshots.push({ snapshots.push({
source: { source: {
id: 'systemd:flynn', id: 'systemd:flynn',
name: 'Flynn daemon', name: 'Flynn daemon',
kind: 'systemd_system', kind: 'systemd_system',
runtime: 'systemd_system', runtime: 'systemd_system',
status: flynnMapped.status, status: flynnStatusValue,
graphCapable: true, graphCapable: true,
logCapable: true, logCapable: !fallbackToProcessRuntime,
metadata: { metadata: {
unit: this.flynnSystemdUnit, unit: this.flynnSystemdUnit,
state: flynnStatus.activeState, state: fallbackToProcessRuntime ? 'running' : flynnStatus.activeState,
statusText: flynnStatus.statusText, statusText: fallbackToProcessRuntime ? 'running (gateway process)' : flynnStatus.statusText,
}, },
}, },
stateCode: flynnMapped.stateCode, stateCode: flynnStateCode,
healthCode: flynnMapped.healthCode, healthCode: flynnHealthCode,
hasError: Boolean(flynnStatus.error), hasError: fallbackToProcessRuntime ? false : Boolean(flynnStatus.error),
fingerprint: flynnStatus.pid ? `pid:${flynnStatus.pid}` : null, fingerprint: flynnStatus.pid ? `pid:${flynnStatus.pid}` : null,
}); });