diff --git a/packages/pockethost/src/cli/commands/EdgeCommand/FtpCommand/FtpService/PhFs.ts b/packages/pockethost/src/cli/commands/EdgeCommand/FtpCommand/FtpService/PhFs.ts index 0e099d0d..25b68c4d 100644 --- a/packages/pockethost/src/cli/commands/EdgeCommand/FtpCommand/FtpService/PhFs.ts +++ b/packages/pockethost/src/cli/commands/EdgeCommand/FtpCommand/FtpService/PhFs.ts @@ -12,7 +12,10 @@ import { seqid, } from '../../../../../common' import { DATA_ROOT } from '../../../../../core' -import { InstanceLogger, InstanceLoggerApi } from '../../../../../services' +import { + InstanceLogWriter, + InstanceLogWriterApi, +} from '../../../../../services' import * as fsAsync from './fs-async' import { MAINTENANCE_ONLY_INSTANCE_ROOTS } from './guards' @@ -48,7 +51,7 @@ const checkBun = ( [`bun.lockb`, `package.json`].includes(maybeImportant || '')) if (isImportant) { - const logger = InstanceLogger(instance.id, `exec`, { ttl: 5000 }) + const logger = InstanceLogWriter(instance.id, `exec`) logger.info(`${maybeImportant} changed, running bun install`) launchBunInstall(instance, virtualPath, cwd).catch(console.error) } @@ -56,7 +59,7 @@ const checkBun = ( const runBun = (() => { const bunLimiter = new Bottleneck({ maxConcurrent: 1 }) - return (cwd: string, logger: InstanceLoggerApi) => + return (cwd: string, logger: InstanceLogWriterApi) => bunLimiter.schedule( () => new Promise((resolve) => { @@ -100,7 +103,7 @@ const launchBunInstall = (() => { runCache[cwd] = { runAgain: true } while (runCache[cwd]!.runAgain) { runCache[cwd]!.runAgain = false - const logger = InstanceLogger(instance.id, `exec`) + const logger = InstanceLogWriter(instance.id, `exec`) logger.info(`Launching 'bun install' in ${virtualPath}`) await runBun(cwd, logger) } diff --git a/packages/pockethost/src/services/InstanceLoggerService/index.ts b/packages/pockethost/src/services/InstanceLoggerService/index.ts index d262cbcb..4c97539b 100644 --- a/packages/pockethost/src/services/InstanceLoggerService/index.ts +++ b/packages/pockethost/src/services/InstanceLoggerService/index.ts @@ -1,13 +1,20 @@ -import * as fs from 'fs' import { appendFile } from 'fs/promises' import { Tail } from 'tail' -import { LoggerService, mkInstanceDataPath, stringify } from '../../../core' +import { + ensureInstanceDirectoryStructure, + LoggerService, + mkInstanceDataPath, + stringify, +} from '../../../core' type UnsubFunc = () => void -export type InstanceLoggerApi = { +export type InstanceLogWriterApi = { info: (msg: string) => void error: (msg: string) => void +} + +export type InstanceLogReaderApi = { tail: (linesBack: number, data: (line: LogEntry) => void) => UnsubFunc shutdown: () => void } @@ -18,26 +25,11 @@ export type LogEntry = { time: string } -export type InstanceLoggerOptions = {} +export function InstanceLogWriter(instanceId: string, target: string) { + const logger = LoggerService().create(instanceId).breadcrumb({ target }) + const { dbg, info, error, warn } = logger -const loggers: { - [key: string]: InstanceLoggerApi -} = {} - -export function InstanceLogger( - instanceId: string, - target: string, - options: Partial = {}, -) { - const { dbg, info, error, warn } = LoggerService() - .create(instanceId) - .breadcrumb({ target }) - - const logDirectory = mkInstanceDataPath(instanceId, `logs`) - if (!fs.existsSync(logDirectory)) { - dbg(`Creating ${logDirectory}`) - fs.mkdirSync(logDirectory, { recursive: true }) - } + ensureInstanceDirectoryStructure(instanceId, logger) const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`) @@ -61,6 +53,18 @@ export function InstanceLogger( error(msg) appendLogEntry(msg, 'stderr') }, + } + + return api +} + +export function InstanceLogReader(instanceId: string, target: string) { + const logger = LoggerService().create(instanceId).breadcrumb({ target }) + const { dbg, info, error, warn } = logger + + ensureInstanceDirectoryStructure(instanceId, logger) + + const api = { tail: (linesBack: number, data: (line: LogEntry) => void): UnsubFunc => { const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`) diff --git a/packages/pockethost/src/services/InstanceService/index.ts b/packages/pockethost/src/services/InstanceService/index.ts index 3f9c2c8b..7e9a8ddf 100644 --- a/packages/pockethost/src/services/InstanceService/index.ts +++ b/packages/pockethost/src/services/InstanceService/index.ts @@ -25,7 +25,7 @@ import { tryFetch, } from '../../../core' import { - InstanceLogger, + InstanceLogWriter, MothershipAdminClientService, PocketbaseService, SpawnConfig, @@ -71,7 +71,7 @@ export const instanceService = mkSingleton( `${subdomain}:${id}:${version}`, ) const { dbg, warn, error, info, trace } = systemInstanceLogger - const userInstanceLogger = InstanceLogger(instance.id, `exec`) + const userInstanceLogger = InstanceLogWriter(instance.id, `exec`) shutdownManager.push(() => { dbg(`Shutting down`) diff --git a/packages/pockethost/src/services/PocketBaseService/index.ts b/packages/pockethost/src/services/PocketBaseService/index.ts index 22c7e248..c535bfbf 100644 --- a/packages/pockethost/src/services/PocketBaseService/index.ts +++ b/packages/pockethost/src/services/PocketBaseService/index.ts @@ -17,7 +17,7 @@ import { mkSingleton, } from '../../../core' import { GobotService } from '../GobotService' -import { InstanceLogger } from '../InstanceLoggerService' +import { InstanceLogWriter } from '../InstanceLoggerService' export type Env = { [_: string]: string } export type SpawnConfig = { @@ -85,7 +85,7 @@ export const createPocketbaseService = async ( } = _cfg logger.breadcrumb({ subdomain, instanceId }) - const iLogger = InstanceLogger(instanceId, 'exec') + const iLogger = InstanceLogWriter(instanceId, 'exec') const _version = version || maxVersion // If _version is blank, we use the max version available const realVersion = await bot.maxSatisfyingVersion(_version) diff --git a/packages/pockethost/src/services/RealtimeLog.ts b/packages/pockethost/src/services/RealtimeLog.ts index 03f97967..d70fa225 100644 --- a/packages/pockethost/src/services/RealtimeLog.ts +++ b/packages/pockethost/src/services/RealtimeLog.ts @@ -8,7 +8,7 @@ import { SingletonBaseConfig, stringify, } from '../../core' -import { InstanceLogger } from './InstanceLoggerService' +import { InstanceLogReader } from './InstanceLoggerService' import { proxyService } from './ProxyService' export type RealtimeLogConfig = SingletonBaseConfig & {} @@ -69,7 +69,7 @@ export const realtimeLog = mkSingleton(async (config: RealtimeLogConfig) => { dbg(`Instance is `, instance) /** Get a database connection */ - const instanceLogger = InstanceLogger(instance.id, `exec`) + const instanceLogger = InstanceLogReader(instance.id, `exec`) /** Start the stream */ res.writeHead(200, {