> ## Documentation Index
> Fetch the complete documentation index at: https://kernel.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Observe

> Watch your agent work, debug what went wrong

Browser agents fail in ways that don't show up in logs. Kernel gives you several ways to see what's actually happening: live, after the fact, frame by frame, line by line, and event by event.

## Live view

Every browser exposes a `browser_live_view_url` you can open in a browser tab or embed in an iframe. Use it to watch an agent run in real time, hand a session off to a human-in-the-loop, or surface the browser as part of your own UI.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  import Kernel from '@onkernel/sdk';

  const kernel = new Kernel();

  const kernelBrowser = await kernel.browsers.create();
  console.log(kernelBrowser.browser_live_view_url);
  ```

  ```python Python theme={null}
  from kernel import Kernel

  kernel = Kernel()

  kernel_browser = kernel.browsers.create()
  print(kernel_browser.browser_live_view_url)
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"fmt"

  	"github.com/kernel/kernel-go-sdk"
  )

  func main() {
  	ctx := context.Background()
  	client := kernel.NewClient()

  	kernelBrowser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{})
  	if err != nil {
  		panic(err)
  	}

  	fmt.Println(kernelBrowser.BrowserLiveViewURL)
  }
  ```

  ```bash CLI theme={null}
  kernel browsers view <session-id>
  ```
</CodeGroup>

Add `?readOnly=true` for a non-interactive view, or enable [kiosk mode](/browsers/live-view#kiosk-mode) at creation for a fullscreen, cinematic experience. Full reference: [Live View](/browsers/live-view).

## Replays

Replays are MP4 recordings you start and stop on demand - capture as many clips per session as you need. They're the right tool for post-hoc debugging: a failed run gives you one or more videos to scrub through, share, or attach to a bug report.

Replays can also be enabled on managed auth sessions, so you can [debug failed logins](https://www.kernel.sh/docs/auth/configuration#record-sessions-for-debugging) the same way.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const replay = await kernel.browsers.replays.start(kernelBrowser.session_id);

  // ...run the agent...

  await kernel.browsers.replays.stop(replay.replay_id, {
    id: kernelBrowser.session_id,
  });
  ```

  ```python Python theme={null}
  replay = kernel.browsers.replays.start(kernel_browser.session_id)

  # ...run the agent...

  kernel.browsers.replays.stop(
      replay.replay_id,
      id=kernel_browser.session_id,
  )
  ```

  ```go Go theme={null}
  replay, err := client.Browsers.Replays.Start(ctx, kernelBrowser.SessionID, kernel.BrowserReplayStartParams{})
  if err != nil {
  	panic(err)
  }

  // ...run the agent...

  if err := client.Browsers.Replays.Stop(
  	ctx,
  	replay.ReplayID,
  	kernel.BrowserReplayStopParams{ID: kernelBrowser.SessionID},
  ); err != nil {
  	panic(err)
  }
  ```

  ```bash CLI theme={null}
  # Start recording
  kernel browsers replays start <session-id>

  # ...run the agent...

  # Stop and download
  kernel browsers replays stop <session-id> <replay-id>
  kernel browsers replays download <session-id> <replay-id> -o replay.mp4
  ```
</CodeGroup>

Full reference: [Replays](/browsers/replays).

## Screenshots

Pull a frame at any moment with computer controls - useful for snapshotting state at decision points, attaching to traces, or feeding back into a vision model.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const screenshot = await kernel.browsers.computer.captureScreenshot(
    kernelBrowser.session_id,
  );
  ```

  ```python Python theme={null}
  screenshot = kernel.browsers.computer.capture_screenshot(
      id=kernel_browser.session_id,
  )
  ```

  ```go Go theme={null}
  screenshot, err := client.Browsers.Computer.CaptureScreenshot(
  	ctx,
  	kernelBrowser.SessionID,
  	kernel.BrowserComputerCaptureScreenshotParams{},
  )
  if err != nil {
  	panic(err)
  }
  defer screenshot.Body.Close()
  ```

  ```bash CLI theme={null}
  kernel browsers computer screenshot <session-id> --to screenshot.png
  ```
</CodeGroup>

For full-page captures, use [Playwright execution](/browsers/playwright-execution#screenshots) instead.

## Invocation logs

If you're running an agent on Kernel's [app platform](/apps/develop), every invocation produces a streaming log feed. Tail it live while the agent runs, or pull it after the fact for debugging.

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const logs = await kernel.invocations.follow(invocationId);

  for await (const event of logs) {
    console.log(event);
  }
  ```

  ```python Python theme={null}
  logs = kernel.invocations.follow(invocation_id)

  for event in logs:
      print(event)
  ```

  ```go Go theme={null}
  stream := client.Invocations.FollowStreaming(
  	ctx,
  	invocationID,
  	kernel.InvocationFollowParams{},
  )
  defer stream.Close()

  for stream.Next() {
  	fmt.Println(stream.Current())
  }
  if err := stream.Err(); err != nil {
  	panic(err)
  }
  ```
</CodeGroup>

Full reference: [Logs](/apps/logs).

## Telemetry

Telemetry is a real-time, structured stream of what happens inside a session: console output, network activity, page lifecycle, interactions, and operational signals like crashes. Unlike a video or screenshot, it's machine-readable, so it's the right tool for feeding session activity into your own observability pipeline or reacting to events programmatically. Enable it at creation, then stream the events:

<CodeGroup>
  ```typescript Typescript/Javascript theme={null}
  const browser = await kernel.browsers.create({ telemetry: { enabled: true } });

  const stream = await kernel.browsers.telemetry.stream(browser.session_id);
  for await (const { seq, event } of stream) {
    console.log(`#${seq} [${event.category}] ${event.type}`);
  }
  ```

  ```python Python theme={null}
  browser = kernel.browsers.create(telemetry={"enabled": True})

  with kernel.browsers.telemetry.stream(browser.session_id) as stream:
      for envelope in stream:
          print(f"#{envelope.seq} [{envelope.event.category}] {envelope.event.type}")
  ```

  ```go Go theme={null}
  stream := client.Browsers.Telemetry.StreamStreaming(
  	ctx,
  	kernelBrowser.SessionID,
  	kernel.BrowserTelemetryStreamParams{},
  )
  defer stream.Close()

  for stream.Next() {
  	fmt.Println(stream.Current())
  }
  if err := stream.Err(); err != nil {
  	panic(err)
  }
  ```

  ```bash CLI theme={null}
  kernel browsers telemetry stream <session-id>
  ```
</CodeGroup>

Full reference: [Telemetry](/browsers/telemetry/overview).

## Picking the right tool

* **Building the agent?** Keep a [live view](/browsers/live-view) tab open while you iterate.
* **Debugging a failure?** Capture a [replay](/browsers/replays) for the run, then watch the video.
* **Instrumenting the agent itself?** Drop [screenshots](/browsers/computer-controls#take-screenshots) and [logs](/apps/logs) into your traces at the points that matter.
* **Feeding an observability pipeline?** Stream [telemetry](/browsers/telemetry/overview) events and route them wherever you collect signals.
* **Putting a human in the loop?** Embed the [live view](/browsers/live-view#embedding-in-an-iframe) in your own UI.
