Skip to content

Add event logging on app dev#6937

Draft
dmerand wants to merge 1 commit intomainfrom
dlm-add-dev-logs
Draft

Add event logging on app dev#6937
dmerand wants to merge 1 commit intomainfrom
dlm-add-dev-logs

Conversation

@dmerand
Copy link
Contributor

@dmerand dmerand commented Mar 4, 2026

What

Add an append-only JSONL event log to shopify app dev that external tools can tail for real-time session observability.

Why

AI coding agents and other external tools need a machine-readable way to observe the dev session lifecycle — knowing when a session starts, when extensions are uploaded, when errors occur, and when the preview is ready. Currently this information is only available in human-readable terminal output, which is fragile to parse and lossy.

See below for an example agent skill that would use this flow.

How

  • DevSessionEventLog — append-only JSONL writer at .shopify/dev-session-events.jsonl, gitignored, truncated on each dev start
  • DevSession owns all event writes via a writeEvent() helper, subscribing to DevSessionStatusManager events for status transitions
  • Event log initialization is non-critical: if init() fails (permissions, disk), dev continues without logging
  • All writes are fire-and-forget with debug-level error logging
  • Proper cleanup: abort signal tears down status listener, app watcher handlers, and closes the event log

Testing

# In one terminal
shopify app dev

# In another terminal, tail the event log
tail -f .shopify/dev-session-events.jsonl | jq .
  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix
  • Existing analytics will cater for this addition
  • PR includes analytics changes to measure impact

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

📡 Agent Skill: dev-session-event-log

Overview

shopify app dev writes a machine-readable event log to .shopify/dev-session-events.jsonl in the app root directory (where shopify.app.toml lives). The file is append-only JSONL (one JSON object per line), truncated on each dev start, and gitignored.

The log covers session lifecycle events only. It does not include build tool output (webpack/esbuild), network proxy activity, or individual compilation steps.

Consuming the log

# Tail in real-time (human-readable)
tail -f .shopify/dev-session-events.jsonl | jq .

# Programmatic consumers should read complete lines before parsing,
# as tail -f may deliver partial lines during concurrent writes.

Event reference

Every event has a ts (ISO 8601 timestamp) and event field. Additional fields vary by event type:

Event When Key fields
session-starting Dev session initialization begins store, app_id, extension_count
session-created Session successfully created preview_url, graphiql_url, duration_ms
session-updated Extensions updated after a file change extensions_updated (string array of handles), duration_ms
session-start-failed Build errors at startup (terminal — process exits) reason, error_count, duration_ms
change-detected File change detected extension_count, extensions[] (each has handle, type)
bundle-uploaded Extensions bundled and uploaded duration_ms, extensions[] (handle strings), inherited_count
status-loading Status transition to loading message, is_ready, preview_url
status-success Status transition to success message, is_ready, preview_url
status-error Status transition to error message, is_ready, preview_url
remote-error API/platform error errors[] (each has message, category), duration_ms
unknown-error Unexpected error errors[] (each has message only), duration_ms

Notes:

  • bundle-uploaded is only emitted when assets need uploading. Config-only changes may skip it.
  • status-* events are deduplicated — they only appear when the status message actually changes.

Common patterns

Wait for session ready:
Watch for session-created — the preview_url field contains the URL to open.

Detect and recover from errors:

  • status-error with message "Build error..." → fix source code, wait for next status-success
  • remote-error → read errors[].message for the exact API validation error (e.g. invalid scopes)

Typical successful startup:

session-starting → bundle-uploaded → session-created → status-success

Failed startup (terminal — process exits, must re-run shopify app dev):

session-starting → session-start-failed

Typical update cycle (file change):

change-detected → status-loading → bundle-uploaded → session-updated → status-success

Error and recovery:

change-detected → status-error (build error)
  ... fix code ...
change-detected → bundle-uploaded → session-updated → status-success

Silent abort: If a new file change arrives while an update is in-flight, the in-progress update may be silently aborted. You'll see a new change-detected without a preceding session-updated for the prior change.

Example events

{"ts":"2026-03-04T19:13:41.502Z","event":"session-starting","store":"example.myshopify.com","app_id":"gid://shopify/App/123","extension_count":4}
{"ts":"2026-03-04T19:13:42.246Z","event":"bundle-uploaded","duration_ms":741.31,"extensions":["app_access","webhooks","app_home","branding"],"inherited_count":0}
{"ts":"2026-03-04T19:13:43.970Z","event":"session-created","preview_url":"https://admin.shopify.com/store/example/apps/abc123","graphiql_url":"http://localhost:3457/graphiql","duration_ms":2467.12}
{"ts":"2026-03-04T19:13:43.978Z","event":"status-success","message":"Ready, watching for changes in your app","is_ready":true,"preview_url":"https://admin.shopify.com/store/example/apps/abc123"}
{"ts":"2026-03-04T19:16:35.816Z","event":"change-detected","extension_count":1,"extensions":[{"handle":"admin-action","type":"created"}]}
{"ts":"2026-03-04T19:35:38.123Z","event":"remote-error","errors":[{"message":"These scopes are invalid - [read_fake_scope]","category":"invalid"}]}

Copy link
Contributor Author

dmerand commented Mar 4, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements 78.85% 14516/18409
🟡 Branches 73.14% 7216/9866
🟡 Functions 79.07% 3706/4687
🟡 Lines 79.2% 13715/17318

Test suite run success

3801 tests passing in 1450 suites.

Report generated by 🧪jest coverage report action from a66594c

@dmerand dmerand force-pushed the dlm-add-dev-logs branch 2 times, most recently from 36c6cde to d8c3ef9 Compare March 4, 2026 20:42
@dmerand dmerand force-pushed the dlm-add-dev-logs branch from d8c3ef9 to a66594c Compare March 4, 2026 20:52
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.

1 participant