Skip to content

Commit 05c344f

Browse files
DavidCozensclaude
andcommitted
docs: close the README with what the repository is for
Every commit so far rewrote "## This stage —" to describe the one capability it added. At the tip that is the wrong shape: a reader arriving at the repository wants to know what it is for before what the last commit changed. The opening now says it: an integration into an application that already exists, starting from a realistic device, where each pull request merged to main is one stage and one increase in the security posture of the logging path. The purpose is the process, the cost of each step and the benefit it brings, so all three can be set against the reader's own threat model. "## Where it ends up" then describes the device the sequence arrives at, and the instruction to read the history forward from the Baseline commit follows the generated total. It also states that the history is rebuilt against each SolidSyslog release, so a reader who has cloned or forked knows a force-push is coming. Nothing here reaches the binary, so there is no measurement to take. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 461d271 commit 05c344f

2 files changed

Lines changed: 31 additions & 49 deletions

File tree

‎README.md‎

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,42 @@
11
# solid-syslog-example
22

3-
A worked integration of [SolidSyslog](https://github.com/cososo-ltd/solid-syslog), built up in
4-
stages — from a device with no syslog at all to one whose records are authenticated and encrypted.
3+
An example of integrating [SolidSyslog](https://github.com/cososo-ltd/solid-syslog) into an
4+
application that already exists, starting from a realistic device rather than an empty one.
55

6-
Each stage is one commit. It says what it does, what it changes, what it gives you, and what it
7-
costs. The costs are measured by the device itself, not estimated.
6+
Each pull request merged to `main` is one stage of that integration, and each raises the security
7+
posture of the logging path. A stage states what it changes, what it gives you, and what it costs,
8+
measured by the device itself rather than estimated.
89

9-
It builds on a baseline that simulates the sort of device you might be adding this to, and that
10-
measures itself: see [docs/baseline.md](docs/baseline.md) for what the baseline is, how the
11-
figures are made, and how to run it.
10+
The purpose is to show the process of integration, the cost of each step and the benefit it brings,
11+
so that all three can be set against your own threat model when you plan your own.
1212

13-
## This stage — Right-sized
13+
The baseline is the sort of device this might be added to: it already networks, mounts a filesystem
14+
and holds a mutual-TLS session to its broker before any syslog exists. See
15+
[docs/baseline.md](docs/baseline.md) for what it is, how the figures are made, and how to run it.
1416

15-
Fit the compile-time sizes to what this device uses, now that every collaborator is in place.
17+
## Where it ends up
1618

17-
The message cap comes first, because the ring, the store's record buffer and the formatter frame on
18-
both task stacks all follow it.
19-
20-
```c
21-
/* app/config/solid_syslog_tunables.h */
22-
#define SOLIDSYSLOG_MAX_MESSAGE_SIZE 400U
23-
24-
#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 1U
25-
#define SOLIDSYSLOG_TCP_STREAM_POOL_SIZE 1U
26-
#define SOLIDSYSLOG_STREAM_SENDER_POOL_SIZE 1U
27-
```
28-
29-
The worst case measured here is 345 octets: the four SD-ELEMENTs with both counters at full 32-bit
30-
width and both addresses at fifteen characters, plus a short message. 400 allows for longer messages
31-
on this device. Anything longer is truncated rather than dropped.
32-
33-
The pool defaults suit a device running several transports at once. This one runs a single sender
34-
over a single stream to a single destination.
35-
36-
The overrides reach the library through `SOLIDSYSLOG_USER_TUNABLES_FILE`, which the library carries
37-
on an INTERFACE target, so Core, the platform packs and this application all compile against the
38-
same values. They change struct sizes, and a build where only some translation units saw them would
39-
disagree about how big those structs are.
40-
41-
The ring drops from eight records to four. The store holds a backlog, so the ring only has to absorb
42-
what can be logged while the service task is sending.
43-
44-
The task stacks go last, at twice their measured high-water marks rounded up to a whole
45-
`configMINIMAL_STACK_SIZE`.
46-
47-
**When you need it.** Once the pipeline is complete. Sizing earlier means sizing against a device
48-
that is still missing collaborators.
19+
The device logs one RFC 5424 record carrying four SD-ELEMENTs: sequence number and uptime, time
20+
quality, origin, and a private element naming the protection its own log pipeline is under. The
21+
record goes to the collector over mutual TLS and is spooled to a local store encrypted with
22+
AES-256-GCM, so records survive a failed send and a disk that leaves the device gives nothing away.
4923

5024
<!-- STAGE-COST:START (generated by scripts/gen-cost-table.py — do not edit by hand) -->
5125

5226
**Cost above baseline: Flash +13,788 B, RAM +36,048 B.**
5327

5428
<!-- STAGE-COST:END -->
5529

56-
The full report for this stage — what the device did, every figure, and the self-check — is
57-
committed as [`run-report.md`](run-report.md), and rewritten by every stage.
30+
Most devices want less than that. The table below prices every stage, and the cheapest row that does
31+
anything useful — a valid, timestamped record on the wire — is a fraction of it.
32+
33+
**Read it as a sequence.** Start at the Baseline commit and step forward. `git show` on any stage
34+
gives the diff to apply to your own build, the reasoning behind it, and the measured cost of applying
35+
it; each stage's run is committed alongside it as [`run-report.md`](run-report.md). Stop where your
36+
device's threat model does.
37+
38+
This history is rebuilt against each SolidSyslog release, which means a force-push. An existing clone
39+
or fork needs re-cloning rather than pulling.
5840

5941
## Every stage
6042

‎run-report.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
[report] flash_data,656,316,340
1515
[report] static_bss,146584,110876,35708
1616
[report] heap_used,4440,4440,0
17-
[report] mbedtls_peak,37248,21332,15916
18-
[report] mbedtls_free,19072,11436,7636
17+
[report] mbedtls_peak,37156,21332,15824
18+
[report] mbedtls_free,19164,11436,7728
1919
[report] lwip_mem_free,7576,7576,0
2020
[report] lwip_pbufs_free,13,14,-1
2121
[report] stack_log,720,120,600
@@ -47,8 +47,8 @@
4747
## Collector (syslog-ng) received
4848

4949
```text
50-
wire <134>1 2026-08-16T16:16:14.430000Z 10.0.2.15 solid-syslog-example - BOOT [meta sequenceId="1" sysUpTime="243"][timeQuality tzKnown="1" isSynced="0"][origin software="solid-syslog-example" swVersion="0.1.0" enterpriseId="32473" ip="10.0.2.15"][logPipeline@32473 transport="mtls" atRest="aes-256-gcm"] device started
51-
parsed PRIORITY=134 TIMESTAMP=2026-08-16T16:16:14+00:00 HOSTNAME=10.0.2.15 APP_NAME=solid-syslog-example PROCID= MSGID=BOOT STRUCTURED_DATA=[meta sequenceId="1" sysUpTime="243"][timeQuality tzKnown="1" isSynced="0"][origin software="solid-syslog-example" swVersion="0.1.0" enterpriseId="32473" ip="10.0.2.15"][logPipeline@32473 transport="mtls" atRest="aes-256-gcm"] MSG=device started
50+
wire <134>1 2026-08-16T17:28:13.500000Z 10.0.2.15 solid-syslog-example - BOOT [meta sequenceId="1" sysUpTime="250"][timeQuality tzKnown="1" isSynced="0"][origin software="solid-syslog-example" swVersion="0.1.0" enterpriseId="32473" ip="10.0.2.15"][logPipeline@32473 transport="mtls" atRest="aes-256-gcm"] device started
51+
parsed PRIORITY=134 TIMESTAMP=2026-08-16T17:28:13+00:00 HOSTNAME=10.0.2.15 APP_NAME=solid-syslog-example PROCID= MSGID=BOOT STRUCTURED_DATA=[meta sequenceId="1" sysUpTime="250"][timeQuality tzKnown="1" isSynced="0"][origin software="solid-syslog-example" swVersion="0.1.0" enterpriseId="32473" ip="10.0.2.15"][logPipeline@32473 transport="mtls" atRest="aes-256-gcm"] MSG=device started
5252
```
5353

5454
## Self-check (vs measurements/right-size.csv)
@@ -58,8 +58,8 @@ parsed PRIORITY=134 TIMESTAMP=2026-08-16T16:16:14+00:00 HOSTNAME=10.0.2.15 APP_N
5858
OK flash_data: 656 (expected 656, Δ0)
5959
OK static_bss: 146584 (expected 146584, Δ0)
6060
OK heap_used: 4440 (expected 4440, Δ0)
61-
OK mbedtls_peak: 37248 (expected 37184, Δ64)
62-
OK mbedtls_free: 19072 (expected 19136, Δ64)
61+
OK mbedtls_peak: 37156 (expected 37184, Δ28)
62+
OK mbedtls_free: 19164 (expected 19136, Δ28)
6363
OK lwip_mem_free: 7576 (expected 7576, Δ0)
6464
OK lwip_pbufs_free: 13 (expected 13, Δ0)
6565
OK stack_log: 720 (expected 720, Δ0)

0 commit comments

Comments
 (0)