Skip to content

Commit 08fbd6d

Browse files
authored
[kernel-1116] rename capture session -> browser telemetry (#242)
## High Level Changes - as per design `DELETE` endpoint is gone, stop telemetry is controlled via setting all values to false -> https://onkernel.slack.com/archives/C0B10F24TG9/p1778620560896099?thread_ts=1778586830.702399&cid=C0B10F24TG9 ``` Endpoints: - GET /telemetry — get current state (TelemetryState), 404 if not active - PUT /telemetry — create/replace config (BrowserTelemetryConfig), returns 201 on start or 200 on replace - PATCH /telemetry — update active config, 404 if not active - POST /telemetry/events — publish an event into the bus - GET /telemetry/stream — SSE stream of events, supports Last-Event-ID for resumption Key schemas: - BrowserTelemetryConfig — top-level config with a browser key → BrowserTelemetryCategoriesConfig - BrowserTelemetryCategoriesConfig — four categories: console, network, page, interaction, each with { enabled: bool } - Event — { ts, type, category, source, data, truncated }, category enum: console | network | page | interaction | system - TelemetryState — { id, status (running|stopped), config, seq, created_at } - PublishedEnvelope — { seq, event } — what the SSE stream and publish response return ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate risk because it changes public API endpoints and refactors the event pipeline to rely on new OpenAPI-generated types and a new telemetry session lifecycle, which could impact event delivery/compatibility. > > **Overview** > Replaces the `capture_session` API and internal `capturesession` package with a new **browser telemetry** model (`GET/PUT/PATCH /telemetry`) where telemetry is stopped by setting all categories to `enabled:false` (no DELETE endpoint). > > Renames/relocates event ingress and streaming to `POST /telemetry/events` and `GET /telemetry/stream`, updates tests and e2e S2 storage coverage accordingly, and wires `cdpmonitor` to publish through `TelemetrySession` (stamping `telemetry_session_id`). > > Refactors the event schema to use OpenAPI-generated types (`TelemetryEventCategory`, `BrowserEventSource`, typed `data` payloads), adds `page_lcp` as a distinct event, and updates screenshot/lifecycle/computed events to emit typed payloads and process-monotonic sequencing. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 381ffa4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 151a0d1 commit 08fbd6d

32 files changed

Lines changed: 7172 additions & 3968 deletions

server/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ $(RECORDING_DIR):
1616
# 3. go mod tidy to pull deps
1717
oapi-generate:
1818
pnpm i -g @apiture/openapi-down-convert
19-
openapi-down-convert --input openapi.yaml --output openapi-3.0.yaml
19+
openapi-down-convert --input openapi.yaml --output openapi-3.0.yaml --allOf
2020
go tool oapi-codegen -config ./oapi-codegen.yaml ./openapi-3.0.yaml
2121
@echo "Fixing oapi-codegen issue https://github.com/oapi-codegen/oapi-codegen/issues/1764..."
2222
go run ./scripts/oapi/patch_sse_methods -file ./lib/oapi/oapi.go -expected-replacements 4

server/cmd/api/api/api.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import (
1010
"sync"
1111
"time"
1212

13-
"github.com/kernel/kernel-images/server/lib/capturesession"
1413
"github.com/kernel/kernel-images/server/lib/cdpmonitor"
1514
"github.com/kernel/kernel-images/server/lib/devtoolsproxy"
15+
"github.com/kernel/kernel-images/server/lib/telemetry"
1616
"github.com/kernel/kernel-images/server/lib/events"
1717
"github.com/kernel/kernel-images/server/lib/logger"
1818
"github.com/kernel/kernel-images/server/lib/nekoclient"
@@ -81,13 +81,13 @@ type ApiService struct {
8181
// when multiple CDP fast-path resizes fire in quick succession.
8282
xvfbResizeMu sync.Mutex
8383

84-
// CDP event pipeline and cdpMonitor.
85-
eventStream *events.EventStream
86-
captureSession *capturesession.CaptureSession
87-
cdpMonitor cdpMonitorController
88-
monitorMu sync.Mutex
89-
lifecycleCtx context.Context
90-
lifecycleCancel context.CancelFunc
84+
// Telemetry event pipeline and CDP monitor.
85+
eventStream *events.EventStream
86+
telemetrySession *telemetry.TelemetrySession
87+
cdpMonitor cdpMonitorController
88+
monitorMu sync.Mutex
89+
lifecycleCtx context.Context
90+
lifecycleCancel context.CancelFunc
9191
}
9292

9393
var _ oapi.StrictServerInterface = (*ApiService)(nil)
@@ -98,8 +98,8 @@ func New(
9898
upstreamMgr *devtoolsproxy.UpstreamManager,
9999
stz scaletozero.PinnedController,
100100
nekoAuthClient *nekoclient.AuthClient,
101-
captureSession *capturesession.CaptureSession,
102-
eventStream *events.EventStream,
101+
telemetrySession *telemetry.TelemetrySession,
102+
eventStream *events.EventStream,
103103
displayNum int,
104104
) (*ApiService, error) {
105105
switch {
@@ -111,18 +111,18 @@ func New(
111111
return nil, fmt.Errorf("upstreamMgr cannot be nil")
112112
case nekoAuthClient == nil:
113113
return nil, fmt.Errorf("nekoAuthClient cannot be nil")
114-
case captureSession == nil:
115-
return nil, fmt.Errorf("captureSession cannot be nil")
114+
case telemetrySession == nil:
115+
return nil, fmt.Errorf("telemetrySession cannot be nil")
116116
case eventStream == nil:
117117
return nil, fmt.Errorf("eventStream cannot be nil")
118118
}
119119

120-
mon := cdpmonitor.New(upstreamMgr, captureSession.Publish, displayNum, slog.Default())
120+
mon := cdpmonitor.New(upstreamMgr, telemetrySession.Publish, displayNum, slog.Default())
121121
ctx, cancel := context.WithCancel(context.Background())
122122

123123
return &ApiService{
124-
recordManager: recordManager,
125-
factory: factory,
124+
recordManager: recordManager,
125+
factory: factory,
126126
defaultRecorderID: "default",
127127
watches: make(map[string]*fsWatch),
128128
procs: make(map[string]*processHandle),
@@ -131,7 +131,7 @@ func New(
131131
nekoAuthClient: nekoAuthClient,
132132
policy: &policy.Policy{},
133133
eventStream: eventStream,
134-
captureSession: captureSession,
134+
telemetrySession: telemetrySession,
135135
cdpMonitor: mon,
136136
lifecycleCtx: ctx,
137137
lifecycleCancel: cancel,
@@ -357,7 +357,7 @@ func (s *ApiService) Shutdown(ctx context.Context) error {
357357
s.monitorMu.Lock()
358358
s.lifecycleCancel()
359359
s.cdpMonitor.Stop()
360-
s.captureSession.Stop()
360+
s.telemetrySession.Stop()
361361
s.monitorMu.Unlock()
362362
return s.recordManager.StopAll(ctx)
363363
}

server/cmd/api/api/api_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111

1212
"log/slog"
1313

14-
"github.com/kernel/kernel-images/server/lib/capturesession"
1514
"github.com/kernel/kernel-images/server/lib/devtoolsproxy"
15+
"github.com/kernel/kernel-images/server/lib/telemetry"
1616
"github.com/kernel/kernel-images/server/lib/events"
1717
"github.com/kernel/kernel-images/server/lib/nekoclient"
1818
oapi "github.com/kernel/kernel-images/server/lib/oapi"
@@ -305,20 +305,20 @@ func newMockNekoClient(t *testing.T) *nekoclient.AuthClient {
305305
return client
306306
}
307307

308-
func newCaptureSession(t *testing.T) (*capturesession.CaptureSession, *events.EventStream) {
308+
func newTelemetrySession(t *testing.T) (*telemetry.TelemetrySession, *events.EventStream) {
309309
t.Helper()
310310
es, err := events.NewEventStream(events.EventStreamConfig{RingCapacity: 64})
311311
if err != nil {
312312
t.Fatal(err)
313313
}
314-
return capturesession.NewCaptureSession(es), es
314+
return telemetry.NewTelemetrySession(es), es
315315
}
316316

317-
// newSvc constructs an ApiService with a fresh capture session and event stream.
317+
// newSvc constructs an ApiService with a fresh telemetry session and event stream.
318318
func newSvc(t *testing.T, mgr recorder.RecordManager) (*ApiService, error) {
319319
t.Helper()
320-
cs, es := newCaptureSession(t)
321-
return New(mgr, newMockFactory(), newTestUpstreamManager(), scaletozero.NewNoopController(), newMockNekoClient(t), cs, es, 0)
320+
ts, es := newTelemetrySession(t)
321+
return New(mgr, newMockFactory(), newTestUpstreamManager(), scaletozero.NewNoopController(), newMockNekoClient(t), ts, es, 0)
322322
}
323323

324324
func TestApiService_PatchChromiumFlags(t *testing.T) {

server/cmd/api/api/capture_session.go

Lines changed: 0 additions & 147 deletions
This file was deleted.

0 commit comments

Comments
 (0)