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)