# Journal JSON logs

Nominal reads journald exports and other JSON Lines log files (`.jsonl`). Each line becomes one entry in a log channel. A line needs a `MESSAGE` and a `__REALTIME_TIMESTAMP` in microseconds since the Unix epoch, and every other field becomes a log argument:

```json
{"__REALTIME_TIMESTAMP": "1789051099000000", "MESSAGE": "Sent ACTUATE_MOTOR command", "level": "INFO"}
```

## Upload a file

**Nominal app**

1. In the sidebar, click **+** (**New**), then **Upload data**. Drop the `.jsonl` file onto **Upload files**, or click **SELECT FILES**.
2. Click **SELECT A DESTINATION** and choose **Standalone dataset**. Pick a dataset, or click **NEW DATASET**, enter a name and click **CREATE DATASET**.
3. Click **CONFIRM & INGEST**.

**Python**

```python
from nominal.core import NominalClient

client = NominalClient.from_profile("default")
dataset = client.create_dataset("Engine test logs")
file = dataset.add_journal_json("engine.jsonl")
file.poll_until_ingestion_completed()  # raises if ingestion fails
```

**nomctl**

```bash
nomctl ingest journal-json --name "Engine test logs" engine.jsonl
```

## Options

| Setting | Python | nomctl |
| --- | --- | --- |
| Log channel name, if not `logs` | `channel` | `--channel` |
| Another timestamp field, in another epoch unit | `timestamp_column` and `timestamp_type`, together | — |

To see the entries, add the dataset to an asset or run, then add a **Logs** panel to a workbook on it.
