A structured syslog client library for embedded and industrial systems, implementing RFC 5424 (structured syslog) with RFC 5426 (UDP) and RFC 6587 (TCP) transports. TLS per RFC 5425 is available via a pluggable Stream abstraction — the repo ships a reference OpenSSL integration, and callers can plug in any TLS library (wolfSSL, mbedTLS, hardware-offload, …) by implementing the same Stream vtable. TLS itself is not a core dependency; Core has zero OpenSSL references.
Designed for resource-constrained environments:
- C99, no dynamic memory allocation required — allocator is caller-injected
- Transport-agnostic — UDP, TCP, TLS, or bring your own
- Buffer-agnostic — NullBuffer (direct send), portable CircularBuffer (mutex-injected ring), POSIX message queue, or bring your own
- No
#ifdeffeature flags — optional features composed at link time - MISRA C:2012 informed
- Dependency injection throughout — fully testable without a network
Approaching feature-complete for POSIX and Windows: RFC 5424 structured formatting, UDP / TCP / TLS / mTLS transport, asynchronous buffering, rotating block store-and-forward with CRC-16 integrity, and the full IEC 62443 SL1–SL4 component set.
FreeRTOS support is in active development on Cortex-M3 (mps2-an385 under QEMU): UDP transport via FreeRTOS-Plus-TCP, host-TDD'd adapters, an interactive BDD target wired with the portable CircularBuffer + FreeRtosMutex behind a Service task, and BDD scenarios driven through QEMU's UART (epic E08 #10).
Not yet production-ready, and no API stability guarantee yet. Known gaps:
- Public API may evolve — sender implementations currently use static
singleton state (
SolidSyslogUdpSender,SolidSyslogStreamSender,SolidSyslogSwitchingSender), so multiple concurrent instances per process aren't yet supported. Additional platform backends (RTOS, custom) are still to land. - At-rest integrity is CRC-16 only; HMAC + AES-at-rest are planned for SL4 (E17 #105).
- TLS revocation (CRL / OCSP) is deferred to the OS trust store; the library itself does not perform revocation checks.
- Comprehensive error guards still rolling out (E12 #31).
See Building and testing.
SolidSyslog uses an OO-in-C style with vtable structs and dependency injection. All fields — required and optional — use a uniform field object pattern. Optional features are composed at link time via dead code elimination; there are no conditional compilation directives in the library source.
Public headers are split by audience (Interface Segregation Principle):
SolidSyslog.h— application code that logs events (Log,Service)SolidSyslogConfig.h— system setup code that creates and destroys loggersSolidSyslogError.h— install a handler to react to library-internal errors (NULL guards, send failures); default is silent. SeeBdd/Targets/Common/BddTargetStderrErrorHandler.cfor a reference implementationSolidSyslogSenderDefinition.h/SolidSyslogBufferDefinition.h— extension points for custom senders and buffersSolidSyslogNullBuffer.h— direct-send buffer for single-task systemsSolidSyslogCircularBuffer.h— portable ring buffer with caller-allocated storage and an injectedSolidSyslogMutex(SolidSyslogPosixMutex/SolidSyslogWindowsMutex/SolidSyslogFreeRtosMutex/SolidSyslogNullMutex/ your own); the cross-platform threaded bufferSolidSyslogPosixMessageQueueBuffer.h— thread-safe POSIX message queue bufferSolidSyslogUdpSender.h— UDP transport (RFC 5426)SolidSyslogStreamSender.h— octet-framed syslog (RFC 6587) over any Stream. Note: RFC 6587 is a Historic RFC — the IESG recommends TLS (RFC 5425) over plain TCP for new deployments. TCP is provided for interoperability with existing infrastructureSolidSyslogTlsStream.h— OpenSSL-backed TLS 1.2+ Stream (RFC 5425): server cert validation, hostname verification, cipher pinning, optional mutual TLS. Plugs intoSolidSyslogStreamSenderas a drop-in forSolidSyslogPosixTcpStreamSolidSyslogSwitchingSender.h— composition sender delegating to one of several inner senders via an application-supplied selector callback;Disconnects the outgoing inner on every changeSolidSyslogEndpoint.h— destination spec for senders. Application suppliesendpoint(fills host/port on (re)connect) andendpointVersion(cheap polled fingerprint); senders Disconnect and lazily reopen when the version changes — supports runtime address rotationSolidSyslogStoreDefinition.h/SolidSyslogBlockStore.h— BlockDevice-backed store-and-forward with rotating blocksSolidSyslogSecurityPolicyDefinition.h— extension point for record integrity policiesSolidSyslogCrc16Policy.h— CRC-16/CCITT-FALSE integrity policySolidSyslogStructuredDataDefinition.h— extension point for custom structured dataSolidSyslogMetaSd.h— meta structured data (RFC 5424 §7.3): sequenceId, sysUpTime, languageSolidSyslogTimeQualitySd.h— timeQuality structured data (RFC 5424 §7.1): tzKnown, isSynced, syncAccuracySolidSyslogOriginSd.h— origin structured data (RFC 5424 §7.2): software, swVersion, enterpriseId, ipSolidSyslogPosixClock.h/SolidSyslogPosixHostname.h/SolidSyslogPosixProcessId.h/SolidSyslogPosixSysUpTime.h— POSIX helpersSolidSyslogFreeRtosDatagram.h/SolidSyslogFreeRtosStaticResolver.h/SolidSyslogFreeRtosMutex.h/SolidSyslogFreeRtosSysUpTime.h— FreeRTOS adapters: FreeRTOS-Plus-TCP UDP datagram, hardcoded-IPv4 resolver,xSemaphoreCreateMutexStatic-backed mutex for CircularBuffer, and a kernel-tick sysUpTime source
Three BDD-driven target binaries exercise the library on each supported
platform. They live under Bdd/Targets/ — one binary
per platform, all named SolidSyslogBddTarget:
Bdd/Targets/Linux/— POSIX, PosixMessageQueueBuffer, two pthreads (logger + service), SwitchingSender over UDP + TCP + TLS + mTLS (TLS build required for the last two);--transportsets the initial transport,switch <name>flips it at runtimeBdd/Targets/Windows/— Windows, CircularBuffer + WindowsMutex, Win32 service thread (_beginthreadex) draining the buffer, Winsock UDP / TCP, with the Windows clock / hostname / process-id / sysUpTime helpersBdd/Targets/FreeRtos/— FreeRTOS-on-QEMU (Cortex-M3, mps2-an385), CircularBuffer + FreeRtosMutex drained by a dedicated Service task, UDP via FreeRTOS-Plus-TCP, interactiveset NAME VALUE/send N/quitcommand channel over the CMSDK UART; BDD-driven against syslog-ng. SeeBdd/Targets/FreeRtos/README.md
- IEC 62443 Compliance Guide — component selection by Security Level (SL1–SL4) for industrial control systems
- RFC Compliance Matrix — sender-side coverage of RFC 5424, 5426, 6587, and 5425
See CI pipeline.
See BDD testing.
See Container images.
Copyright 2026 Cozens Software Solutions Limited.
Licensed under the PolyForm Noncommercial License 1.0.0. Free for noncommercial, personal, educational, and government use.
For commercial licensing enquiries, please use the contact form at cososo.co.uk.