Skip to content

Commit f29cb81

Browse files
author
Ryan Vogel
committed
feat(opencode): add observability logging to push relay and session status
Add structured logging to the push notification pipeline so events can be traced end-to-end when --print-logs is enabled: - push-relay map(): log every classification decision and skip reason - push-relay dedupe(): log suppressed duplicates with elapsed time - push-relay start()/stop(): log init failures and teardown - session/status: log every idle/busy/retry transition
1 parent d034a61 commit f29cb81

2 files changed

Lines changed: 66 additions & 12 deletions

File tree

packages/opencode/src/server/push-relay.ts

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,24 +230,54 @@ function map(event: Event): { type: Type; sessionID: string } | undefined {
230230
const sessionID = str(event.properties.sessionID)
231231
if (!sessionID) return
232232
const route = routeSession(sessionID)
233+
log.info("map: matched permission.asked", {
234+
eventType: event.type,
235+
sessionID: route.sessionID,
236+
originalSessionID: sessionID,
237+
subagent: route.subagent,
238+
})
233239
return { type: "permission", sessionID: route.sessionID }
234240
}
235241

236242
if (event.type === "session.error") {
237243
const sessionID = str(event.properties.sessionID)
238244
if (!sessionID) return
239-
if (routeSession(sessionID).subagent) return
240-
if (!shouldNotifyError(event.properties.error)) return
245+
const route = routeSession(sessionID)
246+
if (route.subagent) {
247+
log.info("map: skipped session.error (subagent)", { sessionID })
248+
return
249+
}
250+
if (!shouldNotifyError(event.properties.error)) {
251+
log.info("map: skipped session.error (suppressed error type)", {
252+
sessionID,
253+
errorName: obj(event.properties.error) ? str(event.properties.error.name) : undefined,
254+
})
255+
return
256+
}
257+
log.info("map: matched session.error", { sessionID })
241258
return { type: "error", sessionID }
242259
}
243260

244-
if (event.type !== "session.status") return
245-
const sessionID = str(event.properties.sessionID)
246-
if (!sessionID) return
247-
if (!obj(event.properties.status)) return
248-
if (event.properties.status.type !== "idle") return
249-
if (routeSession(sessionID).subagent) return
250-
return { type: "complete", sessionID }
261+
if (event.type === "session.status") {
262+
const sessionID = str(event.properties.sessionID)
263+
if (!sessionID) return
264+
if (!obj(event.properties.status)) return
265+
const statusType = str(event.properties.status.type)
266+
if (statusType !== "idle") {
267+
log.info("map: skipped session.status (non-idle)", { sessionID, statusType })
268+
return
269+
}
270+
const route = routeSession(sessionID)
271+
if (route.subagent) {
272+
log.info("map: skipped session.status idle (subagent)", { sessionID })
273+
return
274+
}
275+
log.info("map: matched session.status idle", { sessionID })
276+
return { type: "complete", sessionID }
277+
}
278+
279+
// not a push-eligible event type
280+
return
251281
}
252282

253283
function text(input: string) {
@@ -366,7 +396,15 @@ function dedupe(input: { type: Type; sessionID: string }) {
366396
const prev = next.seen.get(key)
367397
next.seen.set(key, now)
368398
if (!prev) return false
369-
return now - prev < 5_000
399+
const isDupe = now - prev < 5_000
400+
if (isDupe) {
401+
log.info("dedupe: suppressed duplicate", {
402+
type: input.type,
403+
sessionID: input.sessionID,
404+
elapsedMs: now - prev,
405+
})
406+
}
407+
return isDupe
370408
}
371409

372410
async function post(input: { type: Type; sessionID: string }) {
@@ -436,8 +474,14 @@ export namespace PushRelay {
436474
export function start(input: Input) {
437475
const relayURL = norm(input.relayURL.trim())
438476
const relaySecret = input.relaySecret.trim()
439-
if (!relayURL) return
440-
if (!relaySecret) return
477+
if (!relayURL) {
478+
log.warn("start: relay URL is empty, push relay disabled")
479+
return
480+
}
481+
if (!relaySecret) {
482+
log.warn("start: relay secret is empty, push relay disabled")
483+
return
484+
}
441485

442486
stop()
443487

@@ -480,6 +524,7 @@ export namespace PushRelay {
480524
export function stop() {
481525
const next = state
482526
if (!next) return
527+
log.info("stopping push relay")
483528
state = undefined
484529
next.stop()
485530
}

packages/opencode/src/session/status.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ import { BusEvent } from "@/bus/bus-event"
22
import { Bus } from "@/bus"
33
import { InstanceState } from "@/effect/instance-state"
44
import { makeRuntime } from "@/effect/run-service"
5+
import { Log } from "@/util/log"
56
import { SessionID } from "./schema"
67
import { Effect, Layer, ServiceMap } from "effect"
78
import z from "zod"
89

10+
const log = Log.create({ service: "session-status" })
11+
912
export namespace SessionStatus {
1013
export const Info = z
1114
.union([
@@ -72,6 +75,12 @@ export namespace SessionStatus {
7275

7376
const set = Effect.fn("SessionStatus.set")(function* (sessionID: SessionID, status: Info) {
7477
const data = yield* InstanceState.get(state)
78+
const prev = data.get(sessionID)
79+
log.info("session status change", {
80+
sessionID,
81+
from: prev?.type ?? "idle",
82+
to: status.type,
83+
})
7584
yield* bus.publish(Event.Status, { sessionID, status })
7685
if (status.type === "idle") {
7786
yield* bus.publish(Event.Idle, { sessionID })

0 commit comments

Comments
 (0)