split instancelogreader and instancelogwriter

This commit is contained in:
Ben Allfree 2024-11-15 03:07:41 -08:00
parent eba97d2481
commit 3facc2c3f3
5 changed files with 39 additions and 32 deletions

View File

@ -12,7 +12,10 @@ import {
seqid, seqid,
} from '../../../../../common' } from '../../../../../common'
import { DATA_ROOT } from '../../../../../core' import { DATA_ROOT } from '../../../../../core'
import { InstanceLogger, InstanceLoggerApi } from '../../../../../services' import {
InstanceLogWriter,
InstanceLogWriterApi,
} from '../../../../../services'
import * as fsAsync from './fs-async' import * as fsAsync from './fs-async'
import { MAINTENANCE_ONLY_INSTANCE_ROOTS } from './guards' import { MAINTENANCE_ONLY_INSTANCE_ROOTS } from './guards'
@ -48,7 +51,7 @@ const checkBun = (
[`bun.lockb`, `package.json`].includes(maybeImportant || '')) [`bun.lockb`, `package.json`].includes(maybeImportant || ''))
if (isImportant) { if (isImportant) {
const logger = InstanceLogger(instance.id, `exec`, { ttl: 5000 }) const logger = InstanceLogWriter(instance.id, `exec`)
logger.info(`${maybeImportant} changed, running bun install`) logger.info(`${maybeImportant} changed, running bun install`)
launchBunInstall(instance, virtualPath, cwd).catch(console.error) launchBunInstall(instance, virtualPath, cwd).catch(console.error)
} }
@ -56,7 +59,7 @@ const checkBun = (
const runBun = (() => { const runBun = (() => {
const bunLimiter = new Bottleneck({ maxConcurrent: 1 }) const bunLimiter = new Bottleneck({ maxConcurrent: 1 })
return (cwd: string, logger: InstanceLoggerApi) => return (cwd: string, logger: InstanceLogWriterApi) =>
bunLimiter.schedule( bunLimiter.schedule(
() => () =>
new Promise<number | null>((resolve) => { new Promise<number | null>((resolve) => {
@ -100,7 +103,7 @@ const launchBunInstall = (() => {
runCache[cwd] = { runAgain: true } runCache[cwd] = { runAgain: true }
while (runCache[cwd]!.runAgain) { while (runCache[cwd]!.runAgain) {
runCache[cwd]!.runAgain = false runCache[cwd]!.runAgain = false
const logger = InstanceLogger(instance.id, `exec`) const logger = InstanceLogWriter(instance.id, `exec`)
logger.info(`Launching 'bun install' in ${virtualPath}`) logger.info(`Launching 'bun install' in ${virtualPath}`)
await runBun(cwd, logger) await runBun(cwd, logger)
} }

View File

@ -1,13 +1,20 @@
import * as fs from 'fs'
import { appendFile } from 'fs/promises' import { appendFile } from 'fs/promises'
import { Tail } from 'tail' import { Tail } from 'tail'
import { LoggerService, mkInstanceDataPath, stringify } from '../../../core' import {
ensureInstanceDirectoryStructure,
LoggerService,
mkInstanceDataPath,
stringify,
} from '../../../core'
type UnsubFunc = () => void type UnsubFunc = () => void
export type InstanceLoggerApi = { export type InstanceLogWriterApi = {
info: (msg: string) => void info: (msg: string) => void
error: (msg: string) => void error: (msg: string) => void
}
export type InstanceLogReaderApi = {
tail: (linesBack: number, data: (line: LogEntry) => void) => UnsubFunc tail: (linesBack: number, data: (line: LogEntry) => void) => UnsubFunc
shutdown: () => void shutdown: () => void
} }
@ -18,26 +25,11 @@ export type LogEntry = {
time: string 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: { ensureInstanceDirectoryStructure(instanceId, logger)
[key: string]: InstanceLoggerApi
} = {}
export function InstanceLogger(
instanceId: string,
target: string,
options: Partial<InstanceLoggerOptions> = {},
) {
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 })
}
const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`) const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`)
@ -61,6 +53,18 @@ export function InstanceLogger(
error(msg) error(msg)
appendLogEntry(msg, 'stderr') 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 => { tail: (linesBack: number, data: (line: LogEntry) => void): UnsubFunc => {
const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`) const logFile = mkInstanceDataPath(instanceId, `logs`, `${target}.log`)

View File

@ -25,7 +25,7 @@ import {
tryFetch, tryFetch,
} from '../../../core' } from '../../../core'
import { import {
InstanceLogger, InstanceLogWriter,
MothershipAdminClientService, MothershipAdminClientService,
PocketbaseService, PocketbaseService,
SpawnConfig, SpawnConfig,
@ -71,7 +71,7 @@ export const instanceService = mkSingleton(
`${subdomain}:${id}:${version}`, `${subdomain}:${id}:${version}`,
) )
const { dbg, warn, error, info, trace } = systemInstanceLogger const { dbg, warn, error, info, trace } = systemInstanceLogger
const userInstanceLogger = InstanceLogger(instance.id, `exec`) const userInstanceLogger = InstanceLogWriter(instance.id, `exec`)
shutdownManager.push(() => { shutdownManager.push(() => {
dbg(`Shutting down`) dbg(`Shutting down`)

View File

@ -17,7 +17,7 @@ import {
mkSingleton, mkSingleton,
} from '../../../core' } from '../../../core'
import { GobotService } from '../GobotService' import { GobotService } from '../GobotService'
import { InstanceLogger } from '../InstanceLoggerService' import { InstanceLogWriter } from '../InstanceLoggerService'
export type Env = { [_: string]: string } export type Env = { [_: string]: string }
export type SpawnConfig = { export type SpawnConfig = {
@ -85,7 +85,7 @@ export const createPocketbaseService = async (
} = _cfg } = _cfg
logger.breadcrumb({ subdomain, instanceId }) 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 _version = version || maxVersion // If _version is blank, we use the max version available
const realVersion = await bot.maxSatisfyingVersion(_version) const realVersion = await bot.maxSatisfyingVersion(_version)

View File

@ -8,7 +8,7 @@ import {
SingletonBaseConfig, SingletonBaseConfig,
stringify, stringify,
} from '../../core' } from '../../core'
import { InstanceLogger } from './InstanceLoggerService' import { InstanceLogReader } from './InstanceLoggerService'
import { proxyService } from './ProxyService' import { proxyService } from './ProxyService'
export type RealtimeLogConfig = SingletonBaseConfig & {} export type RealtimeLogConfig = SingletonBaseConfig & {}
@ -69,7 +69,7 @@ export const realtimeLog = mkSingleton(async (config: RealtimeLogConfig) => {
dbg(`Instance is `, instance) dbg(`Instance is `, instance)
/** Get a database connection */ /** Get a database connection */
const instanceLogger = InstanceLogger(instance.id, `exec`) const instanceLogger = InstanceLogReader(instance.id, `exec`)
/** Start the stream */ /** Start the stream */
res.writeHead(200, { res.writeHead(200, {