From 6f833c18047f452b0e08e27144ba034111bc2237 Mon Sep 17 00:00:00 2001 From: David Cozens Date: Sun, 16 Aug 2026 18:28:39 +0100 Subject: [PATCH] docs: close the README with what the repository is for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- README.md | 68 +++++++++++++++++++-------------------------------- run-report.md | 12 ++++----- 2 files changed, 31 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 223ef15..6e42075 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,25 @@ # solid-syslog-example -A worked integration of [SolidSyslog](https://github.com/cososo-ltd/solid-syslog), built up in -stages — from a device with no syslog at all to one whose records are authenticated and encrypted. +An example of integrating [SolidSyslog](https://github.com/cososo-ltd/solid-syslog) into an +application that already exists, starting from a realistic device rather than an empty one. -Each stage is one commit. It says what it does, what it changes, what it gives you, and what it -costs. The costs are measured by the device itself, not estimated. +Each pull request merged to `main` is one stage of that integration, and each raises the security +posture of the logging path. A stage states what it changes, what it gives you, and what it costs, +measured by the device itself rather than estimated. -It builds on a baseline that simulates the sort of device you might be adding this to, and that -measures itself: see [docs/baseline.md](docs/baseline.md) for what the baseline is, how the -figures are made, and how to run it. +The purpose is to show the process of integration, the cost of each step and the benefit it brings, +so that all three can be set against your own threat model when you plan your own. -## This stage — Right-sized +The baseline is the sort of device this might be added to: it already networks, mounts a filesystem +and holds a mutual-TLS session to its broker before any syslog exists. See +[docs/baseline.md](docs/baseline.md) for what it is, how the figures are made, and how to run it. -Fit the compile-time sizes to what this device uses, now that every collaborator is in place. +## Where it ends up -The message cap comes first, because the ring, the store's record buffer and the formatter frame on -both task stacks all follow it. - -```c -/* app/config/solid_syslog_tunables.h */ -#define SOLIDSYSLOG_MAX_MESSAGE_SIZE 400U - -#define SOLIDSYSLOG_ADDRESS_POOL_SIZE 1U -#define SOLIDSYSLOG_TCP_STREAM_POOL_SIZE 1U -#define SOLIDSYSLOG_STREAM_SENDER_POOL_SIZE 1U -``` - -The worst case measured here is 345 octets: the four SD-ELEMENTs with both counters at full 32-bit -width and both addresses at fifteen characters, plus a short message. 400 allows for longer messages -on this device. Anything longer is truncated rather than dropped. - -The pool defaults suit a device running several transports at once. This one runs a single sender -over a single stream to a single destination. - -The overrides reach the library through `SOLIDSYSLOG_USER_TUNABLES_FILE`, which the library carries -on an INTERFACE target, so Core, the platform packs and this application all compile against the -same values. They change struct sizes, and a build where only some translation units saw them would -disagree about how big those structs are. - -The ring drops from eight records to four. The store holds a backlog, so the ring only has to absorb -what can be logged while the service task is sending. - -The task stacks go last, at twice their measured high-water marks rounded up to a whole -`configMINIMAL_STACK_SIZE`. - -**When you need it.** Once the pipeline is complete. Sizing earlier means sizing against a device -that is still missing collaborators. +The device logs one RFC 5424 record carrying four SD-ELEMENTs: sequence number and uptime, time +quality, origin, and a private element naming the protection its own log pipeline is under. The +record goes to the collector over mutual TLS and is spooled to a local store encrypted with +AES-256-GCM, so records survive a failed send and a disk that leaves the device gives nothing away. @@ -53,8 +27,16 @@ that is still missing collaborators. -The full report for this stage — what the device did, every figure, and the self-check — is -committed as [`run-report.md`](run-report.md), and rewritten by every stage. +Most devices want less than that. The table below prices every stage, and the cheapest row that does +anything useful — a valid, timestamped record on the wire — is a fraction of it. + +**Read it as a sequence.** Start at the Baseline commit and step forward. `git show` on any stage +gives the diff to apply to your own build, the reasoning behind it, and the measured cost of applying +it; each stage's run is committed alongside it as [`run-report.md`](run-report.md). Stop where your +device's threat model does. + +This history is rebuilt against each SolidSyslog release, which means a force-push. An existing clone +or fork needs re-cloning rather than pulling. ## Every stage diff --git a/run-report.md b/run-report.md index 77268e0..6c3785c 100644 --- a/run-report.md +++ b/run-report.md @@ -14,8 +14,8 @@ [report] flash_data,656,316,340 [report] static_bss,146584,110876,35708 [report] heap_used,4440,4440,0 -[report] mbedtls_peak,37248,21332,15916 -[report] mbedtls_free,19072,11436,7636 +[report] mbedtls_peak,37156,21332,15824 +[report] mbedtls_free,19164,11436,7728 [report] lwip_mem_free,7576,7576,0 [report] lwip_pbufs_free,13,14,-1 [report] stack_log,720,120,600 @@ -47,8 +47,8 @@ ## Collector (syslog-ng) received ```text -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 -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 +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 +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 ``` ## 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 OK flash_data: 656 (expected 656, Δ0) OK static_bss: 146584 (expected 146584, Δ0) OK heap_used: 4440 (expected 4440, Δ0) - OK mbedtls_peak: 37248 (expected 37184, Δ64) - OK mbedtls_free: 19072 (expected 19136, Δ64) + OK mbedtls_peak: 37156 (expected 37184, Δ28) + OK mbedtls_free: 19164 (expected 19136, Δ28) OK lwip_mem_free: 7576 (expected 7576, Δ0) OK lwip_pbufs_free: 13 (expected 13, Δ0) OK stack_log: 720 (expected 720, Δ0)