-
Notifications
You must be signed in to change notification settings - Fork 13
unified shv log format
Fanda Vacek edited this page Dec 16, 2022
·
16 revisions
getLog({"since": dt1|"last", "until": dt2|null, "withSnapshot": true|false, "withPathsDict": true|false, "recordCountLimit": 1000 })
parameters:
-
since
- default: null- dt1 - time of first returned record
-
null
- time of first record in history available -
"last"
- obviously used together withwithSnapshot == true
, time of the most recent record in history log is taken asince
value.
-
until
- default: null- dt2 - time of last returned record exclusively, records with TS >= dt2 will not be part of response
- null - all records or until
recordCountLimit
is hit
-
withSnapshot
- default false, return snapshot of all values in time == since, all the snapshot entries will have time == since -
withPathsDict
- default true, returnpathsDict
in metadata. PathsDict maps every entry path to unique int number. This can save some space in returned log. -
recordCountLimit
- default 1000, maximum number of records returned, client is free to return less thanrecordCountLimit
requested.
Unified log format is used when it is retrieved from any SHV device.
Example:
<
"dateTime":d"2022-12-16T20:57:44.908Z",
"logParams":{
"recordCountLimit":10000,
"since":d"2022-12-15T20:57:40.297Z",
"until":d"2022-12-16T21:57:40.297Z",
"withPathsDict":true,
"withSnapshot":false,
"withTypeInfo":false
},
"logVersion":2,
"pathsDict":i{
0:"shv/system/1/voltage600",
1:"shv/heating/1/airTemp",
2:"shv/vet/1/vehicleDetected",
3:"shv/vet/1/status",
4:"shv/vet/1/status/direction",
5:"shv/tc/1/status/occupied",
6:"shv/tc/1/status",
7:"shv/system/1/status/blocked",
8:"shv/system/1/status",
9:"shv/ppi/1/status/blocked",
10:"shv/ppi/1/status",
11:"shv/tc/2/status/occupied",
12:"shv/tc/2/status",
},
"recordCount":4187,
"recordCountLimit":10000,
"recordCountLimitHit":false,
"since":d"2022-12-15T20:57:40.297Z",
"until":d"2022-12-16T21:57:40.297Z",
"withPathsDict":true,
"withSnapshot":false
>[
[d"2022-12-15T21:01:09.990Z", 0, 651., null, null, 0u, null],
[d"2022-12-15T21:02:03.190Z", 1, -5., null, null, 0u, null],
[
d"2022-12-15T21:04:01.530Z",
2,
{"transceiverPosition":1, "vehicleId":3023, "vehiclePosition":1},
null,
null,
1u,
null
],
[d"2022-12-15T21:04:01.530Z", 3, 0, null, null, 1u, null],
[d"2022-12-15T21:04:01.530Z", 4, 0, null, null, 0u, null],
[
d"2022-12-15T21:04:01.530Z",
2,
{"transceiverPosition":1, "vehicleId":3023, "vehiclePosition":1},
null,
null,
1u,
null
],
[d"2022-12-15T21:04:03.860Z", 5, true, null, null, 0u, null],
[d"2022-12-15T21:04:03.860Z", 6, 1, null, null, 0u, null],
[d"2022-12-15T21:04:03.860Z", 7, true, null, null, 0u, null],
[d"2022-12-15T21:04:03.860Z", 8, 2, null, null, 0u, null],
[d"2022-12-15T21:04:03.960Z", 9, true, null, null, 0u, null],
[d"2022-12-15T21:04:03.960Z", 10, 18, null, null, 0u, null],
[d"2022-12-15T21:04:06.060Z", 11, true, null, null, 0u, null],
[d"2022-12-15T21:04:06.060Z", 12, 1, null, null, 0u, null],
[d"2022-12-15T21:04:10.860Z", 5, false, null, null, 0u, null],
[d"2022-12-15T21:04:10.860Z", 6, 0, null, null, 0u, null],
[d"2022-12-15T21:04:12.760Z", 11, false, null, null, 0u, null],
[d"2022-12-15T21:04:12.760Z", 12, 0, null, null, 0u, null],
[d"2022-12-15T21:04:12.760Z", 7, false, null, null, 0u, null],
[d"2022-12-15T21:04:12.760Z", 8, 0, null, null, 0u, null],
[d"2022-12-15T21:04:12.860Z", 9, false, null, null, 0u, null],
]
One possible device log format implementation to support the Unified SHV log format
in simple way
- Devices are logging to the text file
- Every entry is one line terminated by
\n
- Fields in line are separated by
\t
- Minimal fields are:
-
timestamp
- monotonic timestamp with formatyyyy-mm-ddThh:MM:ss.zzz
-
orig_timestamp
-timestamp
MUST be monotonic, if the device tries to log with timestamp lower than the last record one, thentimestamp
is adjusted to be monotonic and original timestamp is saved asorig_timestamp
. This information is necessary to reconstructtimestamp
in rows where device system time wasn't in sync with NTP -
path
- string -
value
-Cpon
coded logged value forpath
-
Notes:
- It is a device responsibility to ensure monotonic
timestamp
. When device boots, it have to read last log entry and remember recently loggedtimestamp
. If device time after reboot is lover than recent TS, it have to log new events with therecent timestamp
. Even if new timestamps will not be correct, they can be reconstructed later on, when device will connect to internet and sync system time with NTP, usinguptime
value. - It is necessary to keep
timestamp
monotonic even if it is not correct to enable binary search in logs and to generate theUnified log format
easily. -
\n
and\t
are good line and field separators, since they never appear in Cpon packed values - One option to implement device logs was to use SQLite. Simple file was chosen according to Do the simplest thing that could possibly work rule from following reasons:
- Append line to file is really cheep and fast in almost every possible OS
- To ensure DB consistency even when device is rebooted suddenly, Sqlite will create rollback journal on SD card https://www.sqlite.org/tempfiles.html , this can produce undesirable write cycles on EEPROM.
- restore corrupted text log file is pretty easy task comparing to do the same thing with Sqlite
- Open Sqlite with every log entry can spend some system resources to read table structures and init SQL library. App can keep Sqlite connected all its lifetime to come over this.
log file example
2022-01-11T15:38:50.104Z--->123456--->status--->2u--->52345u--->chng
2022-01-11T18:51:37.987Z--->1970-01-01T00:01:37.987Z--->status--->1u--->12345u--->fastchng
Columns:
- monotonic timestamp
- original timestamp (if monotonicity is broken)
- shv/path
- value
- short-time - uint16_t number of miliseconds reported by device without RTC
- domain - values can be grouped to domains
-
chng
value change, it is used primarily for digital slow signals -
fastchng
- analog values changing all the time