feat(tui): add structured logging
This commit is contained in:
parent
5b39972947
commit
cedf365674
9 changed files with 208 additions and 119 deletions
24
packages/tui/src/context/log.tsx
Normal file
24
packages/tui/src/context/log.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { createContext, useContext, type ParentProps } from "solid-js"
|
||||
|
||||
export type LogLevel = "debug" | "info" | "warn" | "error"
|
||||
export type LogTags = Readonly<Record<string, unknown>>
|
||||
export type LogSink = (level: LogLevel, message: string, tags: LogTags) => void
|
||||
|
||||
const LogContext = createContext<LogSink>()
|
||||
|
||||
export function LogProvider(props: ParentProps<{ log: LogSink }>) {
|
||||
return <LogContext.Provider value={props.log}>{props.children}</LogContext.Provider>
|
||||
}
|
||||
|
||||
export function useLog(tags: LogTags = {}) {
|
||||
const sink = useContext(LogContext)
|
||||
if (!sink) throw new Error("Log context must be used within a LogProvider")
|
||||
|
||||
const write = (level: LogLevel, message: string, extra: LogTags = {}) => sink(level, message, { ...tags, ...extra })
|
||||
return {
|
||||
debug: (message: string, extra?: LogTags) => write("debug", message, extra),
|
||||
info: (message: string, extra?: LogTags) => write("info", message, extra),
|
||||
warn: (message: string, extra?: LogTags) => write("warn", message, extra),
|
||||
error: (message: string, extra?: LogTags) => write("error", message, extra),
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import { createGlobalEmitter } from "@solid-primitives/event-bus"
|
|||
import { onCleanup, onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { useLog } from "./log"
|
||||
|
||||
export type SDKConnectionStatus = "connected" | "connecting" | "reconnecting"
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
|||
// Stops and starts the managed service; present only in service mode.
|
||||
reload?: () => Promise<void>
|
||||
}) => {
|
||||
const log = useLog()
|
||||
const abort = new AbortController()
|
||||
let client = props.client
|
||||
let api = props.api
|
||||
|
|
@ -64,7 +66,8 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
|||
return connection.signal.reason instanceof Error
|
||||
? connection.signal.reason
|
||||
: new Error("Event stream disconnected")
|
||||
if (first.value.type !== "server.connected") return new Error("Event stream did not start with server.connected")
|
||||
if (first.value.type !== "server.connected")
|
||||
return new Error("Event stream did not start with server.connected")
|
||||
clearTimeout(timeout)
|
||||
attempt = 0
|
||||
events.emit(first.value.type, first.value)
|
||||
|
|
@ -74,6 +77,12 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
|
|||
const event = await iterator.next()
|
||||
if (abort.signal.aborted || controller.signal.aborted) return
|
||||
if (event.done) return new Error("Event stream disconnected")
|
||||
if ("durable" in event.value)
|
||||
log.info("event", {
|
||||
type: event.value.type,
|
||||
aggregateID: event.value.durable.aggregateID,
|
||||
seq: event.value.durable.seq,
|
||||
})
|
||||
events.emit(event.value.type, event.value)
|
||||
}
|
||||
})()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue