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 — PassthroughBuffer (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, TCP, TLS, and mTLS transports — TCP and UDP via FreeRTOS-Plus-TCP, TLS
and mTLS via SolidSyslogMbedTlsStream (Mbed TLS) layered over the same
FreeRTOS-Plus-TCP byte stream. Persistent store-and-forward via ChaN FatFs
(semihosting-backed disk image in BDD; integrator-supplied diskio.c in
production), 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. Multiple concurrent sender instances are now
pool-backed (E11) —
SOLIDSYSLOG_UDP_SENDER_POOL_SIZE,SOLIDSYSLOG_STREAM_SENDER_POOL_SIZE,SOLIDSYSLOG_SWITCHING_SENDER_POOL_SIZEinCore/Interface/SolidSyslogTunablesDefaults.hset the slot counts; the matching pools live inCore/Source/SolidSyslog*SenderStatic.c. - 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).
New to SolidSyslog? Start at Getting started — the integrator front door. It covers picking your stack from the capability matrix, both consumption paths (CMake and non-CMake / IAR / Keil source integration), a copy-pasteable manifest for an embedded stack, the tunables, and a minimal "your first log" walkthrough.
Developing the library itself? See Building and testing — the contributor/maintainer preset catalogue. (Consuming the library in your product is the Getting started path above.)
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 implementationSolidSyslogConfigLock.h— optional setup-time lock injection (SolidSyslog_SetConfigLock(lockFn, unlockFn)); wraps library-internal pool slot walks so multi-task setup is safe. Defaults are no-ops, so single-task systems can ignore it. Integrators on RTOS / multi-core wiretaskENTER_CRITICAL, a staticpthread_mutex_t,EnterCriticalSection, or a spinlock pairSolidSyslogSenderDefinition.h/SolidSyslogBufferDefinition.h— extension points for custom senders and buffersSolidSyslogPassthroughBuffer.h— direct-send buffer for single-task systemsSolidSyslogCircularBuffer.h— portable ring buffer with caller-allocated ring memory and an injectedSolidSyslogMutex(SolidSyslogPosixMutex/SolidSyslogWindowsMutex/SolidSyslogFreeRtosMutex/SolidSyslogNullMutex/ your own); the cross-platform threaded buffer. Instance bookkeeping lives in a library-internal static pool (E11)SolidSyslogPosixMessageQueueBuffer.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 helpersSolidSyslogPlusTcpDatagram.h/SolidSyslogPlusTcpTcpStream.h/SolidSyslogPlusTcpResolver.h/SolidSyslogPlusTcpAddress.h— FreeRTOS-Plus-TCP networking adapters: UDP datagram and TCP stream (with ARP-prime on cold connect and boundedSO_RCVTIMEOconnect), hardcoded-IPv4 resolver,struct freertos_sockaddraddress adapter. Selected at CMake time viaSOLIDSYSLOG_FREERTOS_NET=PLUSTCP; an lwIP Raw sibling backend is in progress under epic E28SolidSyslogFreeRtosMutex.h/SolidSyslogFreeRtosSysUpTime.h— FreeRTOS kernel primitives independent of the chosen networking backend:xSemaphoreCreateMutexStatic-backed mutex for CircularBuffer and a kernel-tick sysUpTime sourceSolidSyslogFatFsFile.h— ChaN FatFs file adapter for theSolidSyslogFileextension point;f_syncper write for crash-safe store-and-forward. RTOS-agnostic; runs on bare-metal, FreeRTOS, Zephyr, NuttX
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 (OpenSSL);--transportsets the initial transport,switch <name>flips it at runtimeBdd/Targets/Windows/— Windows, CircularBuffer + WindowsMutex, Win32 service thread (_beginthreadex) draining the buffer, SwitchingSender over Winsock UDP / TCP + OpenSSL TLS / mTLS over Winsock TCP, file-backedSolidSyslogBlockStoreoverSolidSyslogWindowsFile, 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, SwitchingSender over UDP + TCP via FreeRTOS-Plus-TCP plus TLS + mTLS viaSolidSyslogMbedTlsStream(Mbed TLS) layered over the same FreeRTOS-Plus-TCP byte stream, persistent store-and-forward via ChaN FatFs over a semihosting-backed disk image, interactiveset NAME VALUE/send N/set store file/set shutdown 1/quitcommand channel over the CMSDK UART; BDD-driven against syslog-ng includingstore_and_forward,power_cycle_replay,store_capacity,tls_transport, andmtls_transportscenarios. 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.