debugging-local-replay

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Debugging local session replay

调试本地会话重放

When a developer says "local replay isn't working" or "recordings aren't showing up", work through these layers in order. The local replay pipeline has several moving parts and failures are usually silent.
当开发者反馈「本地重放无法工作」或「录制内容不显示」时,请按以下层级逐步排查。本地重放流水线包含多个组件,故障通常不会有明显提示。

Quick symptom guide

快速症状指南

SymptomLikely cause
No
/s
calls in Network tab
SDK not recording — triggers, settings, or recorder script issue (Step 1)
/s
calls return 200 but no recordings in list
Ingestion pipeline broken — capture-replay, Kafka, or ingestion-sessionreplay (Steps 2-3)
Recordings listed but playback stuck on "Buffering..."
recording-api
(port 6741) not running (Step 2)
Recorder script MIME type or CORS error in consoleFrontend build stale — need
pnpm build
+
pnpm copy-scripts
(Step 1)
症状可能原因
网络面板中无
/s
请求
SDK未录制——触发器、设置或录制脚本问题(步骤1)
/s
请求返回200但录制列表中无内容
摄入流水线故障——capture-replay、Kafka或ingestion-sessionreplay问题(步骤2-3)
录制内容已列出但播放时卡在「缓冲中...」
recording-api
(端口6741)未运行(步骤2)
控制台中出现录制脚本MIME类型或CORS错误前端构建内容过时——需执行
pnpm build
+
pnpm copy-scripts
(步骤1)

The local replay pipeline

本地重放流水线

text
Browser SDK  →  /s endpoint (Caddy proxy :8000)
             →  capture-replay (Rust, :3306)
             →  Kafka (session_recording_snapshot_item_events topic)
             →  ingestion-sessionreplay (Node, :6740, PLUGIN_SERVER_MODE=recordings-blob-ingestion-v2)
             →  SeaweedFS (blob storage, :8333)
             →  recording-api (Node, :6741, PLUGIN_SERVER_MODE=recording-api)
             →  Frontend
A break at any point in this chain means no recordings in the UI. The diagnostic approach is to find where the chain breaks.
text
Browser SDK  →  /s endpoint (Caddy proxy :8000)
             →  capture-replay (Rust, :3306)
             →  Kafka (session_recording_snapshot_item_events topic)
             →  ingestion-sessionreplay (Node, :6740, PLUGIN_SERVER_MODE=recordings-blob-ingestion-v2)
             →  SeaweedFS (blob storage, :8333)
             →  recording-api (Node, :6741, PLUGIN_SERVER_MODE=recording-api)
             →  Frontend
流水线中任意环节中断都会导致UI中无录制内容。诊断思路是找出链条中断的位置。

Step 1 — Is the SDK even trying to record?

步骤1 — SDK是否尝试录制?

Ask the developer to open browser DevTools Network tab and filter for
/s
.
If no
/s
calls at all:
The SDK isn't attempting to send recording data. Investigate client-side causes:
  • Triggers configured in project settings. If URL triggers, event triggers, or linked flag triggers are set up, recording won't start until a trigger fires. This is the most common cause for developers who've been testing trigger features. Check Session replay settings in the local UI (Project settings > Session replay). Remove or adjust triggers to allow recording to start.
  • Recording disabled in project settings. Session replay may be toggled off.
  • Sample rate set too low. If
    $replay_sample_rate
    is < 1.0, sessions may be sampled out.
  • SDK not initialized with recording. Check the local app's PostHog initialization —
    session_recording
    must not be explicitly disabled.
  • Wrong PostHog host. The local app must point to
    http://localhost:8000
    (or wherever the local Caddy proxy is running).
  • Ad blocker. Even in local dev, browser extensions can block the recorder script or
    /s
    endpoint.
  • Recorder script failed to load (MIME type / CORS error). The browser console may show
    MIME type ('text/html') is not executable
    for
    posthog-recorder.js
    or a CORS error for
    lazy-recorder.js
    . This means Django is serving an HTML page (usually the login redirect) instead of the JS file — the static recorder scripts are stale or missing. See recorder script build failure.
If
/s
calls are happening with 200 responses:
The SDK is recording and capture is receiving data. The break is downstream — proceed to Step 2.
If
/s
calls are returning errors (4xx/5xx):
The capture service may be down or misconfigured. Check
capture-replay
in phrocs.
请开发者打开浏览器DevTools的网络面板,过滤
/s
请求。
如果完全无
/s
请求:
SDK未尝试发送录制数据,需排查客户端原因:
  • 项目设置中的触发器配置:若设置了URL触发器、事件触发器或关联标志触发器,录制需等待触发条件满足才会启动。这是测试触发器功能的开发者遇到的最常见问题。请在本地UI的会话重放设置中(项目设置 > 会话重放)检查相关配置,移除或调整触发器以允许录制启动。
  • 项目设置中录制已禁用:会话重放可能被关闭。
  • 采样率设置过低:若
    $replay_sample_rate
    < 1.0,部分会话可能被采样排除。
  • SDK初始化未启用录制:检查本地应用的PostHog初始化配置——
    session_recording
    不能被显式禁用。
  • PostHog主机地址错误:本地应用必须指向
    http://localhost:8000
    (或本地Caddy代理运行的地址)。
  • 广告拦截器:即使在本地开发环境,浏览器扩展也可能阻止录制脚本或
    /s
    端点。
  • 录制脚本加载失败(MIME类型/CORS错误):浏览器控制台可能显示
    posthog-recorder.js
    MIME类型('text/html')不可执行
    错误,或
    lazy-recorder.js
    的CORS错误。这说明Django返回的是HTML页面(通常是登录重定向)而非JS文件——静态录制脚本已过时或缺失。 请查看录制脚本构建失败
如果
/s
请求返回200响应:
SDK正在录制且捕获服务已接收数据,故障出现在下游环节——继续步骤2。
如果
/s
请求返回错误(4xx/5xx):
捕获服务可能已停止或配置错误,请检查phrocs中的
capture-replay

Step 2 — Are the required processes running?

步骤2 — 必要进程是否在运行?

Check that these phrocs processes are running and healthy. A "running" process that never produced output after
tsx watch src/index.ts
is effectively dead.
检查以下phrocs进程是否正常运行。若某个进程显示「运行中」但在执行
tsx watch src/index.ts
后从未输出任何内容,实际上已处于僵死状态。

Key processes and their ports

关键进程及其端口

ProcessPortWhat it does
capture-replay
3306Rust service receiving
/s
, writes to Kafka
ingestion-sessionreplay
6740Node consumer processing recordings from Kafka
recording-api
6741Node service serving replay data to the frontend
Verify with:
bash
lsof -nP -i :3306 -i :6740 -i :6741
If ports are not listening: The processes haven't started or are stuck. See common failures.
If ports are listening: The pipeline processes are running. Proceed to Step 3.
进程名称端口功能描述
capture-replay
3306接收
/s
请求的Rust服务,将数据写入Kafka
ingestion-sessionreplay
6740从Kafka处理录制数据的Node消费者服务
recording-api
6741向前端提供重放数据的Node服务
验证命令:
bash
lsof -nP -i :3306 -i :6740 -i :6741
如果端口未监听: 进程未启动或已停滞,请查看常见故障
如果端口已监听: 流水线进程正在运行,继续步骤3。

Docker dependencies

Docker依赖组件

These Docker containers must be running and healthy:
ContainerPurpose
posthog-kafka-1
Message bus for recording events
posthog-db-1
Postgres for metadata
posthog-redis7-1
Redis for state
posthog-clickhouse-1
ClickHouse for session data
seaweedfs-main
Blob storage for recording data
Check with:
bash
docker ps --format "table {{.Names}}\t{{.Status}}" | grep -E "kafka|db|redis7|clickhouse|seaweed"
All should show
(healthy)
except seaweedfs which doesn't have a health check. If
seaweedfs-main
is missing, the
replay
Docker profile may not be active — check the
docker-compose
phrocs process output for
--profile replay
.
以下Docker容器必须正常运行:
容器名称用途
posthog-kafka-1
录制事件的消息总线
posthog-db-1
元数据存储的Postgres数据库
posthog-redis7-1
状态存储的Redis
posthog-clickhouse-1
会话数据存储的ClickHouse
seaweedfs-main
录制数据的Blob存储服务
检查命令:
bash
docker ps --format "table {{.Names}}\\t{{.Status}}" | grep -E "kafka|db|redis7|clickhouse|seaweed"
除seaweedfs外,所有容器应显示
(healthy)
状态(seaweedfs无健康检查)。若
seaweedfs-main
缺失,可能未启用
replay
Docker配置文件——请检查
docker-compose
的phrocs进程输出中是否包含
--profile replay

Step 3 — Is data flowing through Kafka?

步骤3 — 数据是否在Kafka中流转?

If capture-replay is running and receiving
/s
calls, data should land on the
session_recording_snapshot_item_events
Kafka topic. Check the Kafka UI at
http://localhost:8080
(if the
debug_tools
intent is enabled) or use kcat:
bash
kcat -b localhost:9092 -t session_recording_snapshot_item_events -C -c 5 -e
If the topic is empty or doesn't exist: capture-replay isn't writing to Kafka. Check its phrocs logs for Kafka connection errors.
If data is on the topic but recordings don't appear: ingestion-sessionreplay isn't consuming. Check if it's stuck, crashed, or if an orphaned process is holding the consumer group (see common failures).
若capture-replay正在运行且接收
/s
请求,数据应进入
session_recording_snapshot_item_events
Kafka主题。可通过
http://localhost:8080
的Kafka UI(若已启用
debug_tools
)或使用kcat检查:
bash
kcat -b localhost:9092 -t session_recording_snapshot_item_events -C -c 5 -e
如果主题为空或不存在: capture-replay未向Kafka写入数据,请检查其phrocs日志中的Kafka连接错误。
如果主题中有数据但录制内容不显示: ingestion-sessionreplay未消费数据,请检查进程是否停滞、崩溃,或是否有孤立进程占用消费者组(见常见故障)。

Step 4 — Check SeaweedFS

步骤4 — 检查SeaweedFS

Ingestion writes recording blobs to SeaweedFS. Verify it's accessible:
bash
curl -s http://localhost:8333/ | head -5
The
SESSION_RECORDING_V2_S3_ENDPOINT
env var must be set correctly. In
bin/start
, this defaults to
http://seaweedfs:8333
(the Docker hostname). Host processes resolve this via Docker networking.
摄入服务会将录制Blob写入SeaweedFS,请验证其可访问性:
bash
curl -s http://localhost:8333/ | head -5
环境变量
SESSION_RECORDING_V2_S3_ENDPOINT
必须配置正确。在
bin/start
中,其默认值为
http://seaweedfs:8333
(Docker主机名),主机进程通过Docker网络解析该地址。

Common failures reference

常见故障参考

See common failures for detailed diagnosis of:
  • Orphaned Node processes holding Kafka consumer groups
  • Processes stuck at
    bin/wait-for-docker
  • tsx watch silently swallowing crashes
  • Port conflicts between Docker and host processes
  • Cargo build lock contention on startup
请查看常见故障获取以下问题的详细诊断方法:
  • 占用Kafka消费者组的孤立Node进程
  • 卡在
    bin/wait-for-docker
    的进程
  • tsx watch静默吞崩溃
  • Docker与主机进程的端口冲突
  • 启动时Cargo构建锁竞争",