Skip to content

3. Sessions

A span cannot outlive the process being killed, so a session is not a span. It is an identifier stamped on every record, two events, and a summary.

  • MUST generate session.id as a random UUID (version 4 or 7), lowercase, with hyphens.
  • MUST set session.previous_id on the session.start event when a session follows another one on the same install.
  • MUST stamp session.id on records as section 2.4 says.
  • MUST start a new session when the app returns to the foreground after 30 minutes or more in the background.
  • MUST start a new session when the current one reaches 4 hours of total length, at the next foreground transition or record after that point.
  • MUST start a new session on every cold start of the process. A process launched in the background (a background fetch, a push notification) MAY defer starting a session until it first comes to the foreground.
  • Both durations are policy values (section 12).
  • MUST emit a session.start log record when a session begins, with session.id and, when there is one, session.previous_id.
  • SHOULD emit session.end when the SDK knows the session ended (rotation while the process lives).
  • A backend MUST NOT require session.end. It derives the end from the last record seen and the session summary.
  • Both events are always sent, whatever the sampling decision (section 9).

Release health (crash-free sessions and users, adoption, session counts) needs every session, but sampling drops detail (section 9). The session summary is a small record sent for every session, sampled or not, so these numbers are exact rather than reweighted.

A summary is a log record with event name apsio.session.summary and these attributes:

Attribute Type Required Value
session.id string MUST The session the summary describes
apsio.session.start_time int MUST When the session started, Unix nanoseconds
apsio.session.outcome string MUST active, exited, crashed or abnormal_exit
apsio.session.error_count int MUST Handled errors recorded so far in the session
apsio.session.foreground boolean SHOULD Whether the app was in the foreground when the summary was written
service.version, app.build_id string MUST when sent by another launch The release of the session, per section 2.5

The record’s timeUnixNano is the last time the session was seen alive.

  • MUST send a summary with outcome active when the session starts.
  • MUST send a final summary when the outcome is known:
    • exited when the session rotates or the app terminates normally;
    • crashed when the next launch finds a crash report for the session (section 6);
    • abnormal_exit when the next launch infers or reads a termination without a crash report.
  • MAY send more active summaries during the session, for example on each move to the background, so the last-seen time stays current if the process is killed.
  • A backend MUST keep, per session, the summary with the latest timeUnixNano, except that crashed and abnormal_exit are final: a later active or exited summary for the same session does not replace them.
  • A session whose last summary is still active after the rotation timeouts have passed is counted as exited.