Historian
The historian (io.scadex.historian) keeps every accepted value of every tag far beyond what the gateway's event backbone retains, and answers tag history reads while it runs. This page is for engineers who run a gateway and for anyone reading history through the API.
It stores its data in SQLite and declares SDK contract 1.2. Its kind is historian and its capabilities are api and history.
What it records
The historian is an ordinary consumer of the gateway's value stream (IModuleValueConsumer): every accepted value of every tag, whoever produced it, in the order the backbone stored it. Each batch and its stream position are stored in one transaction, so a restart resumes without loss or duplicates. Downtime is caught up for as long as the backbone still retains what was missed.
Samples are kept for 90 days by default (retentionDays). The setting ranges from 1 to 36,500 days. Shortening it prunes at once; otherwise pruning runs hourly.
- A renamed tag keeps its history.
- A deleted tag's history stays queryable by its last path until retention removes it.
- The data file is
DATA_DIR/modules/io.scadex.historian/history.db. Storage sits behind anIHistorianStoreinterface, so an external database would mean implementing that interface; none exists yet.
Position, lag and gaps
GET /status reports where the historian is in the stream:
| Field | Meaning |
|---|---|
running | The store is open |
retentionDays | How long samples are kept |
position, streamHead | The last position stored and the newest position known to exist |
lag | streamHead - position: how far behind the live stream it is |
lastBatchAt | When the last batch was stored |
approximateSamples, tags | Rough sample count and the number of tags with samples |
oldest, newest | The time range held, Unix milliseconds |
sizeBytes | Size on disk |
gaps | Stretches the historian never received, each with from, to and missedMessages |
lastPrunedAt, lastPruneError | The last retention run |
A gap appears when the backbone's retention outran the consumer, for example after a long outage. The same figures show on the Modules page under Value stream for this module.
Opening in the background
The store opens in the background, so a slow disk does not hold up the gateway. Until it is open, the module's routes answer 503 with "The history store is still opening." and history reads come from the backbone instead.
How reads fall back
Tag history reads (trends, replay, tag.replay in scripts) use the historian when it is running (IModuleHistoryProvider). Without it, or if it fails, the gateway answers from what the event backbone still retains, and the reply says which one answered. A reply from the historian also says whether it is still catching up (catchingUp), from when it has data (retainedFrom), up to when (coveredUntil) and which gaps fall in the range. See History and replay.
Routes
All routes are under /api/v1/modules/io.scadex.historian. start and end are Unix milliseconds.
| Request | Purpose |
|---|---|
GET /status | Position, lag, oldest and newest sample, size on disk, gaps |
GET /points?path&start&end&limit&cursor | Raw samples, oldest first. limit defaults to 10,000 and may be at most 100,000. truncated and nextCursor page through them |
GET /buckets?path&start&end&buckets | Count, min, max, average, first and last of Good numeric values per time bucket. buckets defaults to 500 and may be at most 10,000 |
GET /settings | {"retentionDays": 90} |
PUT /settings | Body {"retentionDays": n}; 400 outside 1–36,500 |
GET routes need the viewer role and PUT /settings needs engineer. While the module is stopped these routes answer 503, and when it is not installed 404; see Modules.
The dashboard page
Open Tags, then Historian under the History heading (engineers and administrators). The page lists every trendable tag (folders, tag types, instances and @gateway/@types paths are left out), with a filter by path, and draws the trend of the selected tag. A status line at the top says Recording or Stopped, from when it holds data and for how many days it is kept. When the module is not running the line says that trends only go back as far as the gateway keeps recent values.
The retention setting has no control on this page in this version; change it through PUT /settings.