> For the complete documentation index, see [llms.txt](https://docs.siminsights.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.siminsights.com/insights-and-analytics/what-we-capture/how-logging-works.md).

# How logging works

When a learner experiences a simulation, their activity is recorded as a stream of timestamped events. This page describes how that stream is organized, so the [Event Reference](/insights-and-analytics/what-we-capture/event-reference.md) and [Attribute Reference](/insights-and-analytics/what-we-capture/attribute-reference.md) make sense.

## Core concepts

**Event.** A single occurrence at a point in time. Events are either learner generated, such as grabbing an object, or system generated, such as a scene finishing loading. Every event has a name and a timestamp.

**Attribute.** A key and value attached to an event. A grab event carries the name of the object grabbed. Attributes differ by event type, on top of a common set that every event carries.

**Session.** Begins when the learner opens the application and ends when they leave it. Identified by `sessionId`. One session can contain several runs.

**Run.** Begins when a simulation is loaded and ends when the learner leaves it. Identified by `runId`. This is the unit most analytics are built around, and the unit a replay covers.

**Lesson attempt.** When a simulation is played inside a lesson, the run is also tied to a lesson attempt through `lessonAttemptId`, which links simulation activity to course and classroom progress.

## Platforms

The `appName` field identifies where a run happened.

| appName                  | Platform                                    |
| ------------------------ | ------------------------------------------- |
| hypermock-vr             | VR headsets, Quest family and Pico          |
| hypermock-desktop        | Desktop application and the web build       |
| hypermock-web            | Spark, the conversational simulation player |
| hyperskill-android       | Android                                     |
| hyperskill-vision        | Apple Vision Pro                            |
| hololens2, hyperskill-hl | Microsoft HoloLens 2                        |
| ios                      | iOS and iPadOS                              |
| career-pathway           | Career Pathway assessment                   |
| activity-viewer          | Lesson and activity player                  |

Not every event appears on every platform. Controller and haptic attributes only appear where the hardware supports them. The Event Reference notes where this matters.

## Identifying the learner

Three fields carry identity, and which are present depends on how the learner reached the simulation.

| Field                        | Meaning                                                                                               |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| `hs_user_id`                 | The HyperSkill account. Present for signed in learners.                                               |
| `user_auth0`                 | The sign in identity, for example `google-oauth2 \| 1234...`. Present when the learner authenticated. |
| `hs_anon_id`                 | A generated identifier for a learner with no account.                                                 |
| `userId`                     | A display name, not a stable identifier                                                               |
| `student_id`, `student_name` | Supplied by an LMS on SCORM launches.                                                                 |

A run is anonymous when it carries neither `hs_user_id` nor a real `user_auth0`

Scores and skill values are recorded per run, so an anonymous run still produces results. They just cannot be attributed to a person.

## Timestamps

Every event carries two times, and they answer different questions.

| Field              | Meaning                                |
| ------------------ | -------------------------------------- |
| `timestamp_client` | When the event happened on the device. |
| `timestamp_server` | When the event arrived at our servers. |

Both are Unix milliseconds in UTC.

Events are uploaded in batches, so several events can share a single `timestamp_server` even though they happened seconds apart. On a headset used offline, an entire session uploads at once when it reconnects, which compresses hours of activity into a single instant of server time.

Use `timestamp_client` to measure how long something took, the gap between two events, or the order they occurred in. Use `timestamp_server` for when a session was received, and as a fallback when a client timestamp is missing.

Client clocks are set by the device and are occasionally wrong. Because a wrong clock is usually wrong by a constant amount, differences between two client timestamps stay accurate even when the absolute time does not.

## Sensor Data

The sensor stream records three entities per run: `headset`, `ctrl_l` and `ctrl_r`. Each sample carries position as `px`, `py`, `pz` and rotation as `rx`, `ry`, `rz`, tied to a `runId`.
