# Journal JSON logs

Upload journald exports and other JSON Lines log files with [`add_journal_json()`](https://dev.nominal.io/python/ref/generated/nominal.core.Dataset.md#nominal.core.Dataset.add_journal_json "nominal.core.Dataset.add_journal_json").
Each line becomes one entry in a log channel.

To send logs from a running program instead, see [Stream logs](https://dev.nominal.io/python/guides/streaming/logs.md).

## Connect the client

This guide assumes you have [installed](https://dev.nominal.io/python/guides/install.md) the client and setup your [API keys](https://dev.nominal.io/python/guides/api-keys-setup.md).

```python
from nominal.core import NominalClient

client = NominalClient.from_profile("default")
```

## Upload a file

The file needs a `.jsonl` or `.jsonl.gz` name and one JSON object per line:

```json
{"__REALTIME_TIMESTAMP": "1789051099000000", "MESSAGE": "Sent ACTUATE_MOTOR command", "level": "INFO"}
{"__REALTIME_TIMESTAMP": "1789051100000000", "MESSAGE": "Motor temperature above target", "level": "WARN"}
```

- `MESSAGE` holds the log message.
- `__REALTIME_TIMESTAMP` holds microseconds since the Unix epoch.
- Every other field, here `level`, becomes a log argument with a string value.
- Lines without a message or timestamp are skipped.

```python
dataset = client.create_dataset("Engine test logs")
file = dataset.add_journal_json("engine.jsonl", channel="engine_logs")  # channel defaults to "logs"
file.poll_until_ingestion_completed()
```

## Use another timestamp field

Pass both `timestamp_column` and `timestamp_type` for a different field or epoch unit:

```python
file = dataset.add_journal_json(
    "engine-ms.jsonl",
    channel="engine_logs",
    timestamp_column="timestamp_ms",
    timestamp_type="epoch_milliseconds",
)
file.poll_until_ingestion_completed()
```

`timestamp_type` takes epoch units only.
For ISO 8601 or relative times, convert them to epoch values first, or parse the entries and [stream them](https://dev.nominal.io/python/guides/streaming/logs.md).

## View the logs

Add the dataset to an [asset](https://dev.nominal.io/python/guides/assets.md#add-data-with-data-scopes) or a [run](https://dev.nominal.io/python/guides/runs.md).
In a workbook on that asset or run, add a **Logs** panel and select the `engine_logs` channel.
