Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ add_executable(baseline
${APP_DIR}/net/EthernetIf.c
${APP_DIR}/storage/diskio.c
${APP_DIR}/storage/SemihostingDisk.c
${APP_DIR}/syslog/Syslog.c
${APP_DIR}/syslog/SyslogErrorHandler.c
$<TARGET_OBJECTS:baseline_upstream>
)
Expand All @@ -151,7 +152,7 @@ target_include_directories(baseline PRIVATE
${APP_DIR}/net/smsc9220
${APP_DIR}/platform # CmsdkUart.h, SemihostingExit.h, SemihostingIo.h
${APP_DIR}/storage # SemihostingDisk.h
${APP_DIR}/syslog # SyslogErrorHandler.h
${APP_DIR}/syslog # Syslog.h, SyslogErrorHandler.h
${FREERTOS_KERNEL_PATH}/include
${FREERTOS_PORT_DIR}
${LWIP_DIR}/src/include
Expand Down
47 changes: 29 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,45 @@ It builds on a baseline that simulates the sort of device you might be adding th
measures itself: see [docs/baseline.md](docs/baseline.md) for what the baseline is, how the
figures are made, and how to run it.

## This stage — Error handler
## This stage — Logger created

Install the handler before any other call into SolidSyslog.
Create the logger with both collaborators absent, deliberately, and read what the handler prints.

```c
SolidSyslog_SetErrorHandler(OnSyslogError, NULL);
struct SolidSyslogConfig config = {
.Buffer = NULL,
.Sender = NULL,
};

struct SolidSyslog* logger = SolidSyslog_Create(&config);
```

No `_Create` fails or returns `NULL` — a missing collaborator is substituted with its Null object
and reported — so the only evidence is what the handler says:

```text
[syslog] CRITICAL SolidSyslog bad-config (detail 1)
[syslog] CRITICAL SolidSyslog bad-config (detail 2)
[syslog] CRITICAL SolidSyslog bad-config (detail 3)
```

Nothing in the library fails loudly. A `_Create` that cannot succeed substitutes a Null object and
reports it rather than returning `NULL`, so a logger that has silently stopped looks exactly like
one with nothing to say. The handler is what tells the two apart, which is why it goes in before
the first `_Create` and not after something looks wrong. It reports many misconfiguration errors,
and can save significant time while integrating.
Three, for the buffer, the sender and the store. Each names the collaborator in `Detail`, as a
value of the emitting class's own error enum.

This is not only an integration aid. The handler is the seam into the device's own error and health
reporting, and it stays valuable at run time: later stages raise an edge-triggered warning when the
collector becomes unreachable and a notice when delivery recovers. Route it wherever the device
already routes faults — here, the same console as everything else, so a fault lands in the run
report next to the rest of what the device did.
The order matters. Wire everything at once and see nothing, and you cannot tell a working logger
from a silent one. Seeing the faults first, then watching them go quiet as each collaborator
arrives, is the difference between believing it works and knowing.

The handler names the four lifecycle categories a misconfigured integration raises and prints the
rest numerically. A device reacting to a fault would switch on the category rather than the text.
A convention worth adopting now: `NULL` as a parameter means "not supplied" and is reported, while
a collaborator you have deliberately done without is passed as its Null object. The library
distinguishes the two, and so should anyone reading the wiring later.

**When you need it.** Every device, and first. It is the only thing standing between a
misconfigured logger and a silent one.
**When you need it.** As a step rather than a destination. It costs one build to prove the handler
is connected and the library is reachable, before anything can be blamed on the network.

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

**Cost above baseline: Flash +404 B, RAM +8 B.**
**Cost above baseline: Flash +1,052 B, RAM +184 B.**

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

Expand All @@ -54,6 +64,7 @@ committed as [`run-report.md`](run-report.md), and rewritten by every stage.
| Baseline | a device that already networks, stores, and holds an mTLS session — before any syslog | — | — |
| Linked | the core library and lwIP raw-mode networking, linked but not yet called | +0 | +0 |
| Error handler | a fault inside the logger reaches the console instead of being silent | +404 | +8 |
| Logger created | the logger object, reporting exactly what is still missing from it | +1,052 | +184 |

*Deltas are bytes above the baseline, which is itself Flash 350,308 B, RAM 111,192 B.*

Expand Down
3 changes: 3 additions & 0 deletions app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "SemihostingExit.h"
#include "ServiceTask.h"
#include "SimulatedExistingApp.h"
#include "Syslog.h"
#include "SyslogErrorHandler.h"

#include "lwip/tcpip.h"
Expand Down Expand Up @@ -97,6 +98,8 @@ int main(void)
/* Before the first _Create — see SyslogErrorHandler.h for why that matters. */
SyslogErrorHandler_Install();

Syslog_Start();

/* lwIP tcpip thread + core-lock mutex + mbox. Pre-scheduler safe. */
tcpip_init(NULL, NULL);

Expand Down
30 changes: 30 additions & 0 deletions app/syslog/Syslog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* See Syslog.h. Created with nothing wired into it, on purpose: a missing
* collaborator is substituted with its Null object and reported, and the run
* report is where that shows. */

#include "Syslog.h"

#include "SolidSyslogConfig.h"

#include <stddef.h>

static struct SolidSyslog* s_logger = NULL;

void Syslog_Start(void)
{
/* Buffer and Sender decide where a record goes. NULL is "not supplied" and
* is reported; a collaborator deliberately done without is passed as its
* Null object instead, which is how the library tells the two apart. */
struct SolidSyslogConfig config = {
.Buffer = NULL,
.Sender = NULL,
};

/* No null check — Create returns a shared null instance rather than NULL. */
s_logger = SolidSyslog_Create(&config);
}

struct SolidSyslog* Syslog_Handle(void)
{
return s_logger;
}
15 changes: 15 additions & 0 deletions app/syslog/Syslog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* The device's SolidSyslog wiring — the one place that knows how the logger is
* assembled. Everything else in the application just logs. */
#ifndef SYSLOG_H
#define SYSLOG_H

struct SolidSyslog;

/** Build the config and create the logger. Call once at startup, after
* SyslogErrorHandler_Install so any fault in here is reported. */
void Syslog_Start(void);

/** The logger, for the tasks that log from it and drain it. */
struct SolidSyslog* Syslog_Handle(void);

#endif /* SYSLOG_H */
13 changes: 13 additions & 0 deletions measurements/logger.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# logger figures (bytes) — captured by scripts/run.sh (CAPTURE=1).
# The device reads measurements/Baseline.csv as its frozen baseline and reports current-minus-Baseline.
flash_text,350976
flash_data,384
static_bss,110992
heap_used,4440
mbedtls_peak,21300
mbedtls_free,11468
lwip_mem_free,7576
lwip_pbufs_free,13
stack_log,120
stack_service,52
stack_harness,2840
1 change: 1 addition & 0 deletions measurements/stages.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
Baseline Baseline a device that already networks, stores, and holds an mTLS session — before any syslog
linked Linked the core library and lwIP raw-mode networking, linked but not yet called
error-handler Error handler a fault inside the logger reaches the console instead of being silent
logger Logger created the logger object, reporting exactly what is still missing from it
33 changes: 18 additions & 15 deletions run-report.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
# solid-syslog-example — run (error-handler)
# solid-syslog-example — run (logger)

## Device (self-measured)

```text
[device] solid-syslog-example (FreeRTOS + lwIP + mbedTLS + FatFs)
[syslog] CRITICAL SolidSyslog bad-config (detail 1)
[syslog] CRITICAL SolidSyslog bad-config (detail 2)
[syslog] CRITICAL SolidSyslog bad-config (detail 3)
[device] starting simulated existing application...
[sim] broker session to 10.0.2.2:8883: TLSv1.3, TLS1-3-CHACHA20-POLY1305-SHA256
[device] sim app (lwIP up, FatFs mounted, broker session held over mTLS): ready
[report] --- SolidSyslog cost above baseline (simulated existing application) ---
[report] key,current,baseline,used_above_baseline
[report] flash_text,350392,349992,400
[report] flash_data,320,316,4
[report] static_bss,110880,110876,4
[report] flash_text,350976,349992,984
[report] flash_data,384,316,68
[report] static_bss,110992,110876,116
[report] heap_used,4440,4440,0
[report] mbedtls_peak,21336,21332,4
[report] mbedtls_free,11432,11436,-4
[report] mbedtls_peak,21276,21332,-56
[report] mbedtls_free,11492,11436,56
[report] lwip_mem_free,7576,7576,0
[report] lwip_pbufs_free,13,14,-1
[report] lwip_pbufs_free,14,14,0
[report] stack_log,120,120,0
[report] stack_service,52,52,0
[report] stack_harness,2840,2840,0
Expand All @@ -28,7 +31,7 @@

```text
text data bss dec hex filename
350384 328 110880 461592 70b18 /w/build/baseline-cross/baseline.elf
350968 392 110992 462352 70e10 /w/build/baseline-cross/baseline.elf
```

## Listeners (proved before the device ran)
Expand All @@ -49,17 +52,17 @@
(nothing — this device sends no records yet)
```

## Self-check (vs measurements/error-handler.csv)
## Self-check (vs measurements/logger.csv)

```text
OK flash_text: 350392 (expected 350392, Δ0)
OK flash_data: 320 (expected 320, Δ0)
OK static_bss: 110880 (expected 110880, Δ0)
OK flash_text: 350976 (expected 350976, Δ0)
OK flash_data: 384 (expected 384, Δ0)
OK static_bss: 110992 (expected 110992, Δ0)
OK heap_used: 4440 (expected 4440, Δ0)
OK mbedtls_peak: 21336 (expected 21296, Δ40)
OK mbedtls_free: 11432 (expected 11472, Δ40)
OK mbedtls_peak: 21276 (expected 21300, Δ24)
OK mbedtls_free: 11492 (expected 11468, Δ24)
OK lwip_mem_free: 7576 (expected 7576, Δ0)
OK lwip_pbufs_free: 13 (expected 13, Δ0)
OK lwip_pbufs_free: 14 (expected 13, Δ1)
OK stack_log: 120 (expected 120, Δ0)
OK stack_service: 52 (expected 52, Δ0)
OK stack_harness: 2840 (expected 2840, Δ0)
Expand Down
Loading