Skip to content

Prefix logs with remote inference connection ID#648

Merged
emranemran merged 2 commits intomainfrom
mh/connection-id-logs
Mar 10, 2026
Merged

Prefix logs with remote inference connection ID#648
emranemran merged 2 commits intomainfrom
mh/connection-id-logs

Conversation

@mjh1
Copy link
Contributor

@mjh1 mjh1 commented Mar 10, 2026

Summary by CodeRabbit

  • New Features

    • Logs now include an automatic connection ID tag for WebSocket sessions to improve traceability and debugging.
    • New internal controls ensure the connection ID is set when sessions start and cleared when they end.
  • Bug Fixes

    • Connection setup/teardown is more resilient: failures in updating log correlation are handled gracefully and won’t interrupt cleanup.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

🚀 fal.ai Preview Deployment

App ID daydream/scope-pr-648--preview
WebSocket wss://fal.run/daydream/scope-pr-648--preview/ws
Commit 732f947

Testing

Connect to this preview deployment by running this on your branch:

uv run build && SCOPE_CLOUD_APP_ID="daydream/scope-pr-648--preview/ws" uv run daydream-scope

🧪 E2E tests will run automatically against this deployment.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

✅ E2E Tests passed

Status passed
fal App daydream/scope-pr-648--preview
Run View logs

Test Artifacts

Check the workflow run for screenshots.

Signed-off-by: Max Holland <max@livepeer.org>
@mjh1 mjh1 force-pushed the mh/connection-id-logs branch from 9998482 to c831e8d Compare March 10, 2026 16:55
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f0ab0609-6bac-47f6-9716-a46107560bee

📥 Commits

Reviewing files that changed from the base of the PR and between c831e8d and 732f947.

📒 Files selected for processing (2)
  • src/scope/cloud/fal_app.py
  • src/scope/server/app.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/scope/cloud/fal_app.py
  • src/scope/server/app.py

📝 Walkthrough

Walkthrough

Adds Fal connection ID propagation for log correlation: thread-safe storage and logging filter, server endpoints to set/clear the ID, and WebSocket/cloud components that PUT the ID on connect and DELETE it on disconnect.

Changes

Cohort / File(s) Summary
Logging infrastructure
src/scope/server/logs_config.py
Adds thread-safe global storage for a Fal connection ID, set_fal_connection_id / get_fal_connection_id APIs, FalConnectionFilter logging.Filter to inject fal_conn, and LOG_FORMAT.
Server integration & endpoints
src/scope/server/app.py
Switches root logging to use LOG_FORMAT, attaches FalConnectionFilter to handlers, and adds internal endpoints PUT /api/v1/internal/fal-connection-id and DELETE /api/v1/internal/fal-connection-id to set/clear the connection ID.
Connection lifecycle changes
src/scope/cloud/fal_app.py, src/scope/server/cloud_connection.py
On WebSocket/cloud readiness, code issues an async PUT to set the Fal connection ID (and calls set_fal_connection_id), and performs DELETE/clears the ID on disconnect; exceptions are suppressed during these network/cleanup steps.

Sequence Diagram(s)

sequenceDiagram
    participant Client as WebSocket Client
    participant FalApp as fal_app.py
    participant Server as app.py
    participant LogsConfig as logs_config.py
    participant Logger as Python Logger

    Client->>FalApp: Establish WebSocket
    FalApp->>Server: PUT /api/v1/internal/fal-connection-id (connection_id)
    Server->>LogsConfig: set_fal_connection_id(connection_id)
    LogsConfig->>LogsConfig: store connection_id (thread-safe)
    FalApp->>Logger: emit logs
    Logger->>LogsConfig: FalConnectionFilter.filter()
    LogsConfig->>Logger: inject fal_conn attribute
    Logger->>Logger: format using LOG_FORMAT (includes fal_conn)
    Client->>FalApp: Disconnect
    FalApp->>Server: DELETE /api/v1/internal/fal-connection-id
    Server->>LogsConfig: set_fal_connection_id(None)
    LogsConfig->>LogsConfig: clear connection_id
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A tiny hop to tag each trace,
Connection IDs find their place,
Thread-safe burrows store the key,
Filters whisper fal_conn to me,
Logs aligned — we bound with grace!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: prefixing logs with a remote inference connection ID for correlation purposes. The changes across multiple files implement exactly this objective.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mh/connection-id-logs

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/scope/server/logs_config.py (1)

34-36: Inconsistent lock usage for thread-safe read.

set_fal_connection_id acquires _fal_connection_id_lock, but get_fal_connection_id reads the global directly without the lock. The same applies to FalConnectionFilter.filter() at line 48.

In CPython, simple reference reads/writes are atomic due to the GIL, so this is safe in practice. However, the inconsistency suggests either the lock in the setter is unnecessary, or the getter should also acquire it for consistency. Consider either removing the lock entirely (since atomic reference assignment is safe) or using it consistently.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/scope/server/logs_config.py` around lines 34 - 36, The getter and filter
read _fal_connection_id without using _fal_connection_id_lock while
set_fal_connection_id uses the lock; make access consistent by acquiring
_fal_connection_id_lock when reading: update get_fal_connection_id() to acquire
the lock before returning _fal_connection_id and update
FalConnectionFilter.filter() to acquire the same lock when reading
_fal_connection_id (or, if you prefer to remove synchronization entirely, remove
_fal_connection_id_lock and all lock usage from set_fal_connection_id and
FalConnectionFilter.filter so reads/writes are plain atomic assignments).
src/scope/server/app.py (1)

463-474: Consider validating connection_id input.

The endpoint accepts any value from the JSON body without validation. If connection_id is missing or not a string, set_fal_connection_id will still be called with None or a non-string value. While the FalConnectionFilter handles None gracefully, you might want to validate the input for consistency.

🛡️ Optional input validation
 `@app.put`("/api/v1/internal/fal-connection-id")
 async def put_fal_connection_id(request: Request):
     """Set the fal connection ID that is injected into every log line.

     Called by the fal_app proxy when a new WebSocket connection is established.
     This is an internal endpoint not intended for external consumers.
     """
     body = await request.json()
     connection_id = body.get("connection_id")
+    if not isinstance(connection_id, str) or not connection_id:
+        raise HTTPException(status_code=400, detail="connection_id must be a non-empty string")
     set_fal_connection_id(connection_id)
     logger.info("Fal connection ID set")
     return {"status": "ok", "connection_id": connection_id}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/scope/server/app.py` around lines 463 - 474, The put_fal_connection_id
handler currently accepts any JSON value; validate that
body.get("connection_id") exists and is a string before calling
set_fal_connection_id: if missing or not a str, return a 400 error JSON (and log
a warning) and do not call set_fal_connection_id; if valid, proceed to call
set_fal_connection_id(connection_id) and log success. Reference the
put_fal_connection_id function and set_fal_connection_id (and
FalConnectionFilter behavior) when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/scope/server/app.py`:
- Around line 463-474: The put_fal_connection_id handler currently accepts any
JSON value; validate that body.get("connection_id") exists and is a string
before calling set_fal_connection_id: if missing or not a str, return a 400
error JSON (and log a warning) and do not call set_fal_connection_id; if valid,
proceed to call set_fal_connection_id(connection_id) and log success. Reference
the put_fal_connection_id function and set_fal_connection_id (and
FalConnectionFilter behavior) when making the change.

In `@src/scope/server/logs_config.py`:
- Around line 34-36: The getter and filter read _fal_connection_id without using
_fal_connection_id_lock while set_fal_connection_id uses the lock; make access
consistent by acquiring _fal_connection_id_lock when reading: update
get_fal_connection_id() to acquire the lock before returning _fal_connection_id
and update FalConnectionFilter.filter() to acquire the same lock when reading
_fal_connection_id (or, if you prefer to remove synchronization entirely, remove
_fal_connection_id_lock and all lock usage from set_fal_connection_id and
FalConnectionFilter.filter so reads/writes are plain atomic assignments).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 126bf92f-84f5-4e42-96be-d0104216534a

📥 Commits

Reviewing files that changed from the base of the PR and between 5d1800b and c831e8d.

📒 Files selected for processing (4)
  • src/scope/cloud/fal_app.py
  • src/scope/server/app.py
  • src/scope/server/cloud_connection.py
  • src/scope/server/logs_config.py

Signed-off-by: Max Holland <max@livepeer.org>
@mjh1
Copy link
Contributor Author

mjh1 commented Mar 10, 2026

Verified:
Screenshot 2026-03-10 at 17 13 34

@mjh1 mjh1 requested a review from emranemran March 10, 2026 17:15
@emranemran emranemran merged commit 4cba0a9 into main Mar 10, 2026
10 checks passed
@mjh1 mjh1 deleted the mh/connection-id-logs branch March 11, 2026 10:59
@coderabbitai coderabbitai bot mentioned this pull request Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants