# Collector JSONL records

URL: /reference/collector-jsonl

Read any process sample from the Foxborne collector field by field, with types and units, the record for a missing process, and the companion clock Foxborne places every sample on.



Collector JSONL holds the process samples the Foxborne collector takes on a vehicle's companion computer. Each line is one JSON object: one sample of one process. Files arrive with the collector's uploads, or through **Import files** like the other formats.

At the default rate of 1 per second, each sample records CPU, resident memory and restart count for one watched process. The [`memory_pressure`](/rules/memory-pressure) rule reads these records.

## Process sample fields [#process-sample-fields]

| Field      | Type and unit                           | Meaning                                                                                                                          |
| ---------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `t_utc`    | String, UTC, ISO 8601 with milliseconds | Wall-clock time of the sample on the companion computer. It is only as good as that clock.                                       |
| `mono_ns`  | Integer, nanoseconds                    | Monotonic time since the companion computer booted. The journal's `__MONOTONIC_TIMESTAMP` counts the same clock in microseconds. |
| `boot_id`  | String                                  | Boot ID of the companion computer. The example records carry the first 8 hex characters of the journal's `_BOOT_ID`.             |
| `proc`     | String                                  | Process name, from **Processes to sample** in the collector policy.                                                              |
| `pid`      | Integer                                 | Process ID at the time of the sample. It changes when the process restarts.                                                      |
| `rss_kib`  | Integer, KiB                            | Resident set size. The console shows it in MiB: 6,336,512 KiB is 6,188 MiB.                                                      |
| `cpu_pct`  | Number, percent                         | CPU use of the process. The example reads 187.4, so values above 100 occur.                                                      |
| `restarts` | Integer, count                          | Restart count of the process.                                                                                                    |

## Record for a missing process [#record-for-a-missing-process]

When a watched process is not running at a sample, the collector still writes a record. It sets `present` to `false` and `pid` to `null`, and it carries no memory, CPU or restart values.

```json title="uas07-orin-samples.jsonl" caption="Example dataset, INC-0139, row 4,402, one line in the file"
{
  "t_utc": "2026-09-21T03:14:08.402Z",
  "boot_id": "5d0c88e1",
  "proc": "perception_node",
  "pid": null,
  "present": false
}
```

| Field     | Value   | Meaning                                     |
| --------- | ------- | ------------------------------------------- |
| `present` | `false` | The process was not running at this sample. |
| `pid`     | `null`  | No process, so no process ID.               |

The console titles this event **perception\_node sample missing, process gone**. In the example dataset, samples of a running process carry no `present` field.

In INC-0139, chrony never synchronized, so `t_utc` reads the companion's own clock: 03:14, during a flight that ran from 14:05 to 14:23 UTC. The manual alignment proposed for that incident puts the offset at +11:03:04.916, bound ±1.04 s.

## Example record [#example-record]

This is the first of the three samples behind the `memory_pressure` finding in INC-0142, row 2,811 of `uas04-orin-samples.jsonl`:

```json title="uas04-orin-samples.jsonl" caption="Example dataset, INC-0142, row 2,811, one line in the file"
{
  "t_utc": "2026-09-24T14:32:01.204Z",
  "mono_ns": 1149990000000,
  "boot_id": "9b2e4c1d",
  "proc": "perception_node",
  "pid": 2213,
  "rss_kib": 6336512,
  "cpu_pct": 187.4,
  "restarts": 0
}
```

* `rss_kib` 6,336,512 is 6,188 MiB, at or above the rule's 6,144 MiB threshold. The next two rows read 6,402 and 6,655 MiB, and the rule confirmed the finding at 14:32:03.204.
* `mono_ns` sits on the journal's clock. The kernel's journal line reporting the kill of pid 2213 carries `__MONOTONIC_TIMESTAMP` 1152904000. That is 2.914 s after this sample on the same clock, and the two wall times differ by the same 2.914 s.
* After the restart, samples carry pid 3398 and `restarts` 1, matching the journal's "restart counter is at 1".

The evidence inspector shows the same record, indented, under **Original record**, with **Rows 2,811 to 2,813** under **Location**.

## What the collector records on every sample [#what-the-collector-records-on-every-sample]

**What the collector reads**, in the **Collector policy** drawer under **Sources**, **Vehicle collectors**, lists the clock data the collector keeps. Its **Clock** row reads: "Wall time, monotonic time, boot ID and chrony status on every sample. SYSTEM\_TIME pairs from 0.8."

| Recorded            | In the example records                                                           |
| ------------------- | -------------------------------------------------------------------------------- |
| Wall time           | `t_utc`                                                                          |
| Monotonic time      | `mono_ns`                                                                        |
| Boot ID             | `boot_id`                                                                        |
| chrony status       | Recorded on every sample. The example records show no field for it.              |
| `SYSTEM_TIME` pairs | Recorded by collector 0.8 and later. The example records show no field for them. |

The **Clock** column of **Vehicle collectors** shows each vehicle's chrony state, such as **Synced +0.8 ms** or **Not synchronised**. Collectors on 0.7.3, the older version in the example dataset, show **No SYSTEM\_TIME** beside the version. The collector never records environment variables, process arguments or camera frames.

## How Foxborne recognizes the format [#how-foxborne-recognizes-the-format]

**Import files** reads the first 4,096 bytes of each file and runs these checks in order. The first match sets the format.

| Order | Looks for                                   | Detected as            | Detail line               |
| ----- | ------------------------------------------- | ---------------------- | ------------------------- |
| 1     | The ULog magic bytes `55 4C 6F 67 01 12 35` | PX4 ULog               | **Magic bytes verified**  |
| 2     | `__REALTIME_TIMESTAMP`                      | journalctl JSON export | **Journal fields found**  |
| 3     | `"recv_utc"`                                | Receiver JSONL         | **Receive records found** |
| 4     | `"boot_id"` or `"rss_kib"`                  | Collector JSONL        | **Process samples found** |

A file that matches none is rejected with &#x2A;*Not a format Foxborne reads. Expected PX4 ULog, journalctl JSON, collector JSONL or receiver JSONL.**

The file name counts in one case only: a file named `.ulg` without the magic bytes is quarantined rather than rejected. Because the receiver check runs first, a file with `"recv_utc"` in its first 4,096 bytes imports as receiver JSONL.

## The clock Foxborne assigns [#the-clock-foxborne-assigns]

**Source files** on the run page lists process samples with these values, here from run R-0931 in the example dataset:

| Column               | Value                                                                                                   | What it means                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| **Clock and anchor** | **Companion monotonic, same boot as journal**, anchored by **Shared boot ID 9b2e4c1d with the journal** | The samples sit on the journal's clock for the same boot. |
| **Bound**            | **±6 ms**                                                                                               | The journal's bound, which the samples inherit.           |
| **Parser**           | `agent 0.8.1`                                                                                           | The parser and version that read the file.                |

The journal and process samples read **Same clock** under **Ordering bounds between sources**, so their events are always in order against each other.

When chrony never synchronized on that boot, the journal has no anchor and the samples have none either. In run R-0922 both show **None: chrony never synchronised**, and the timeline keeps them on the companion's own clock. Collector 0.8.1 records `SYSTEM_TIME` pairs, which give companion evidence a shared anchor with the flight log.

## Where the console shows these records [#where-the-console-shows-these-records]

* **Timeline:** the **Process samples** lane draws each process as a series in MiB, with the rule's threshold line, such as **Threshold 6,144 MiB**.
* **Evidence inspector:** **Original record** holds the record, and **Location** gives its rows.
* **Event page:** **Memory around this event** charts the samples from 8 s before to 4 s after the event. **Breadcrumbs** collapse samples per PID, such as **Process samples: perception\_node, pid 2213**.

## Related [#related]

* [The companion collector](/collect/collector) and [Set the collector policy](/collect/collector/policy) cover what the collector samples and how often.
* [memory\_pressure](/rules/memory-pressure) is the rule that reads these records.
* [Clocks, anchors and error bounds](/concepts/clocks) explains the shared boot ID anchor.
* [Receiver JSONL records](/reference/receiver-jsonl) documents the ground receive log.
