Parent epic: #31
Builds on: S12.18 (error reporting API)
Parent epic: #31
Status
Refinement needed before this is pulled into work. The scope below is a
sketch from the design discussion that produced S12.18 — it's prescriptive
on direction but deliberately leaves several decisions open. Some scope may
split out into a follow-on story (rate-limiting in particular looks like a
candidate for its own slice).
Context
S12.18 lands the error reporting API but does not self-emit syslog messages.
This story adds the layer where library-internal events become syslog messages
on the wire — the dogfood pattern (RFC 5424 facility 5 = syslog).
Discussion thread that produced this story decided:
- The user handler is always called for every error (S12.18 already covers).
- Self-emit is a separate, library-owned layer that runs before the user
handler and only fires for runtime errors on a healthy library.
- Construction-time errors and log-path errors must not self-emit (recursion /
no working channel).
- A repeated error (e.g. SD format fault on every message) must not flood the
SIEM — needs rate-limiting.
Sketched scope (subject to refinement)
- Origin parameter. Add
SolidSyslogErrorOrigin { CONSTRUCTION, RUNTIME, LOG_PATH }
to SolidSyslog_Error() and to the handler signature. Update all existing
call sites (S12.18's wiring + whatever S12.04/05/06 added by then).
- Self-emit layer in the dispatcher. When
origin == RUNTIME and self-emit
is enabled, emit a syslog message via SolidSyslog_Log with
facility = SOLIDSYSLOG_FACILITY_SYSLOG (5).
- Construction-complete gate. Self-emit becomes active only after
SolidSyslog_Create returns successfully — likely leans on the null-instance
pattern (Log on the default instance is already a no-op).
SolidSyslog_SetSelfEmit(bool) toggle. Default: enabled (per the
control-products framing — wired up at design and test time, no on-site
surprise).
- Examples updated so newcomers see the dogfood pattern out of the box.
Likely to split out (refine before pulling)
- Rate-limiter for the flooding case (e.g. SD format fault on every Log call
→ SIEM saturation). Candidate designs from the discussion:
- Dedup-by-message-pointer ring (4–8 slots, suppression-deadline per pointer,
suppression-count rides on the next emit). Cheap, embedded-friendly.
- Token-bucket (N events/sec). Simpler but blunter.
Probably its own story (S12.20?) so we can land self-emit first and observe
the actual flooding shape before committing to a limiter design.
Open questions to settle in refinement
- Origin enum values —
CONSTRUCTION / RUNTIME / LOG_PATH was the working set,
but is there a fourth axis we missed (e.g. distinguishing SetX config
changes after init from initial construction)?
- When does the construction gate flip — last line of
SolidSyslog_Create, or
only after some other milestone?
- Does the public handler signature gain
origin here, even if some integrators
don't care about it? (Currently it doesn't, per S12.18.)
- Toggle granularity — single
SetSelfEmit(bool), or per-origin
(e.g. enable for RUNTIME, disable for everything else)?
- Header for the origin enum and self-emit toggle — extend
SolidSyslogError.h
or split into a separate SolidSyslogSelfEmit.h?
Acceptance
To be defined when the story is refined.
Parent epic: #31
Builds on: S12.18 (error reporting API)
Parent epic: #31
Status
Refinement needed before this is pulled into work. The scope below is a
sketch from the design discussion that produced S12.18 — it's prescriptive
on direction but deliberately leaves several decisions open. Some scope may
split out into a follow-on story (rate-limiting in particular looks like a
candidate for its own slice).
Context
S12.18 lands the error reporting API but does not self-emit syslog messages.
This story adds the layer where library-internal events become syslog messages
on the wire — the dogfood pattern (RFC 5424 facility 5 =
syslog).Discussion thread that produced this story decided:
handler and only fires for runtime errors on a healthy library.
no working channel).
SIEM — needs rate-limiting.
Sketched scope (subject to refinement)
SolidSyslogErrorOrigin { CONSTRUCTION, RUNTIME, LOG_PATH }to
SolidSyslog_Error()and to the handler signature. Update all existingcall sites (S12.18's wiring + whatever S12.04/05/06 added by then).
origin == RUNTIMEand self-emitis enabled, emit a syslog message via
SolidSyslog_Logwithfacility = SOLIDSYSLOG_FACILITY_SYSLOG(5).SolidSyslog_Createreturns successfully — likely leans on the null-instancepattern (
Logon the default instance is already a no-op).SolidSyslog_SetSelfEmit(bool)toggle. Default: enabled (per thecontrol-products framing — wired up at design and test time, no on-site
surprise).
Likely to split out (refine before pulling)
→ SIEM saturation). Candidate designs from the discussion:
suppression-count rides on the next emit). Cheap, embedded-friendly.
Probably its own story (S12.20?) so we can land self-emit first and observe
the actual flooding shape before committing to a limiter design.
Open questions to settle in refinement
CONSTRUCTION / RUNTIME / LOG_PATHwas the working set,but is there a fourth axis we missed (e.g. distinguishing
SetXconfigchanges after init from initial construction)?
SolidSyslog_Create, oronly after some other milestone?
originhere, even if some integratorsdon't care about it? (Currently it doesn't, per S12.18.)
SetSelfEmit(bool), or per-origin(e.g. enable for
RUNTIME, disable for everything else)?SolidSyslogError.hor split into a separate
SolidSyslogSelfEmit.h?Acceptance
To be defined when the story is refined.