Skip to content

[eas-cli] Add observe:session for inspecting events by session ID#3868

Merged
douglowder merged 9 commits into
mainfrom
doug/eng-21942-eas-cli-enable-querying-by-session-id
Jun 18, 2026
Merged

[eas-cli] Add observe:session for inspecting events by session ID#3868
douglowder merged 9 commits into
mainfrom
doug/eng-21942-eas-cli-enable-querying-by-session-id

Conversation

@douglowder

@douglowder douglowder commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Why

New command for retrieving and analyzing events in a session.

USAGE
  $ eas observe:session SESSIONID [--project-id <value>] [--json] [--non-interactive]

ARGUMENTS
  SESSIONID  Session ID to inspect

FLAGS
  --json                Enable JSON output, non-JSON messages will be printed to stderr. Implies --non-interactive.
  --non-interactive     Run the command in non-interactive mode.
  --project-id=<value>  EAS project ID (defaults to the project ID of the current directory)

DESCRIPTION
  display the timeline of metric and log events for a specific session

How

Query both metrics and logs, filtered by the session ID passed in.

Example results:

# Results for an app startup session (main session)
easd observe:session 2bb44b16-7650-4efd-8ec8-a1bd75ee81dc

App version: 1.1.0 (31)
Device:      Pixel 7 · Android 13
First seen:  May 11, 2026, 04:12:07.662 AM
Last seen:   May 11, 2026, 04:13:04.886 AM

Offset  Type    Name          Value  Properties         Severity
------  ------  ------------  -----  -----------------  --------
0.00s   metric  Bundle Load   0.77s  -                  -       
0.05s   log     app.open      -      cold_start=false   INFO    
0.15s   metric  Startup TTR   1.38s  -                  -       
0.45s   metric  Startup TTI   2.16s  -                  -       
0.55s   metric  Warm Launch   1.29s  -                  -       
0.95s   log     screen.view   -      screen=profile     INFO    
17.16s  log     habit.logged  -      habit_id=meditate  INFO    
                                     streak_days=12             
56.59s  log     screen.view   -      screen=streak      INFO    
57.22s  log     screen.view   -      screen=paywall     INFO

# Results for a navigation session with routes
$ eas observe:session 7e57f6cd-f8e9-4fe0-b6a5-934856d61663

App version: 1.1.0 (31)
Device:      iPhone16,1 · iOS 17.5
First seen:  May 6, 2026, 06:54:35.820 AM
Last seen:   May 6, 2026, 06:56:11.753 AM

Offset  Type    Name                           Value / Severity
------  ------  -----------------------------  ----------------
0.00s   metric  Nav Cold TTR · /task/[taskId]  0.51s           
0.08s   metric  Nav TTI · /task/[taskId]       0.53s           
4.78s   metric  Nav Warm TTR · /stats          0.55s           
4.84s   metric  Nav TTI · /stats               0.57s           
33.66s  metric  Nav Warm TTR · /stats          0.53s           
33.72s  metric  Nav TTI · /stats               0.47s           
53.96s  metric  Nav Warm TTR · /stats          0.24s           
54.02s  metric  Nav TTI · /stats               0.82s           
78.61s  metric  Nav Warm TTR · /new            0.21s           
78.67s  metric  Nav TTI · /new                 0.27s           
95.87s  metric  Nav Warm TTR · /new            0.08s           
95.93s  metric  Nav TTI · /new                 0.20s

Test Plan

  • Tested against a project in staging.
  • New unit tests added.

@linear-code

linear-code Bot commented Jun 16, 2026

Copy link
Copy Markdown

ENG-21942

Copy link
Copy Markdown
Contributor Author

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

@douglowder douglowder force-pushed the doug/eng-21942-eas-cli-enable-querying-by-session-id branch from 2680bbb to 5af17f2 Compare June 16, 2026 21:53
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.72727% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.91%. Comparing base (2435468) to head (c1da5c1).

Files with missing lines Patch % Lines
packages/eas-cli/src/observe/formatSessions.ts 97.11% 2 Missing ⚠️
packages/eas-cli/src/observe/fetchSessions.ts 96.56% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3868      +/-   ##
==========================================
+ Coverage   58.79%   58.91%   +0.13%     
==========================================
  Files         929      932       +3     
  Lines       40612    40744     +132     
  Branches     8553     8593      +40     
==========================================
+ Hits        23873    24002     +129     
- Misses      16643    16646       +3     
  Partials       96       96              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@douglowder douglowder changed the title [eas-cli] Add observe:sessions for inspecting events by session ID [eas-cli] Add observe:session for inspecting events by session ID Jun 17, 2026
@douglowder douglowder marked this pull request as ready for review June 17, 2026 20:29

@kadikraman kadikraman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Works great, thank you for adding this!

@douglowder douglowder force-pushed the doug/eng-21942-eas-cli-enable-querying-by-session-id branch from abc81b0 to 2bf9b79 Compare June 18, 2026 17:14
douglowder and others added 9 commits June 18, 2026 12:02
New observe:sessions command with two modes:

* No argument — list distinct session IDs in the time window. Pulls one
  page (100) of each event source (events + customEventList) in parallel,
  derives the set of sessions client-side, groups by deviceOs, sorts by
  app version desc (semver-coerced, falling back to string compare) and
  then by firstSeenAt desc, and prints a Session ID / First seen /
  App version table per platform. Always emits a yellow note that the
  command scans the first 100 metric and log events, since the underlying
  GraphQL queries cap pages at 100 and a dedicated sessions query does
  not yet exist.

* Session ID argument — combined timeline for that session. Filters both
  event sources by sessionId, merges them sorted by timestamp, and prints
  a Timestamp / Type / Name / Value-or-Severity table preceded by a
  metadata block (app version, device, first/last seen) derived from the
  newest entry. The same metadata is exposed as a top-level field in the
  JSON output.

Additional features:

* --event-name flag: when listing, restricts the result to sessions that
  contain at least one log event with the given name. Header and empty-
  state message reflect the filter. Rejected with an error when combined
  with a session-ID argument.

* fetchObserveEventsAsync gains optional metricName / sessionId so the
  metric-event query can be filtered to a single session without
  requiring a metric.

* New ObserveEventNameFlag in observe/flags.ts so future observe
  commands can reuse the same --event-name input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ssion ID

The session ID is now a required positional argument and the
list-distinct-sessions mode is gone — along with --platform,
--start/--end/--days, --app-version, --update-id, --event-name, and the
helpers that only supported listing (SessionSummary, sort comparator,
list fetcher / formatter, event-count tracking). The command now exposes
only --project-id, --json, and --non-interactive.

Since the sessionId filter uniquely identifies the session, the time
range is no longer needed. Make startTime and endTime optional on
FetchObserveEventsOptions and FetchCustomEventsOptions and omit them
from the filter when undefined; the session fetcher relies on this so
the request is purely sessionId-scoped (existing observe:metrics and
observe:events callers still pass them explicitly, so behaviour is
unchanged for those commands).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…event

The "First seen" line in the metadata header already shows the full
timestamp of the first event. The events table now replaces the absolute
Timestamp column with an Offset column whose values are the elapsed
time since that first event, in seconds with two-decimal precision
(e.g. 0.00s, 1.23s, 12.50s). Also drop the stale "use --limit to fetch
more per source" suggestion from the hasMore* warning since --limit is
no longer a flag; the message now states that only the first 100 of
each source are shown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Re-run yarn --cwd packages/eas-cli generate-graphql-code to pick up
server-side schema changes that accumulated since the last sync, and
extend AppObserveEventFragmentNode to select routeName so the CLI can
surface which route navigation metric events (expo.navigation.cold_ttr,
expo.navigation.warm_ttr, expo.navigation.tti) belong to.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Thread the AppObserveEvent.routeName field through the metric-event
JSON shape (ObserveEventJson) and through SessionEventEntry, and render
it alongside the metric display name in the observe:session timeline.
Navigation rows now read e.g. "Nav TTI · /home" instead of just
"Nav TTI", so users can see which screen each navigation metric belongs
to within the session.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rity columns

Replace the combined "Value / Severity" column with two: Value shows the
metric value (e.g. 0.80s) for metric rows and the primitive properties
(STRING / NUMBER / BOOLEAN) of a custom event for log rows, formatted as
key=value with one row per property; Severity holds the severityText
(falling back to severityNumber) and is only populated for log rows.
Non-primitive (JSON) properties are still carried through to the JSON
output but are omitted from the table view to keep it readable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ve:session

Move the primitive-property rendering into its own Properties column,
positioned between Value and Severity. This separates the data
visually: metric events have a populated Value column and "-" in
Properties, while custom log events have "-" in Value and their
key=value primitive properties in Properties. Severity continues to
hold only severityText / severityNumber for log rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n table

The session ID is already shown on the command line that produced the
output (and is still emitted in --json), so the redundant
"Session <id>" line above the metadata block adds noise. Remove it and
drop the now-unused sessionId parameter from
buildObserveSessionEventsTable; the table starts directly with the
metadata block (App version / Device / First seen / Last seen) followed
by the timeline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@douglowder douglowder force-pushed the doug/eng-21942-eas-cli-enable-querying-by-session-id branch from bf79c06 to c1da5c1 Compare June 18, 2026 19:04
@github-actions

Copy link
Copy Markdown

✅ Thank you for adding the changelog entry!

@douglowder douglowder merged commit 0986682 into main Jun 18, 2026
11 checks passed
@douglowder douglowder deleted the doug/eng-21942-eas-cli-enable-querying-by-session-id branch June 18, 2026 20:19
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