feat: send the first record — passthrough buffer over UDP - #52
Conversation
|
@coderabbitai review |
|
Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThe application now initializes lwIP before Syslog, configures a synchronous UDP sender for ChangesUDP Syslog pipeline
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This change sends the first formatted syslog record synchronously over UDP using the documented configuration, with no actionable merge-blocking risk remaining beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Main
participant lwIP
participant Syslog_Start
participant LogTask
participant UDP_Sender
participant Collector
Main->>lwIP: tcpip_init
Main->>Syslog_Start: configure UDP Syslog
LogTask->>UDP_Sender: SolidSyslog_Log(BOOT record)
UDP_Sender->>Collector: send UDP datagram
LogTask-->>Main: logging success
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
✅ Action performedReview finished.
|
9c080cf to
0fbdfab
Compare
|
@coderabbitai pause |
The smallest wiring that delivers anything: a UDP sender over lwIP's raw API, with a passthrough buffer in front of it. Passthrough means Log sends inline on the calling task — no queue, no background drain, nothing to service — so this is the cheapest thing that can be called working. Flash +4,724 B RAM +1,912 B Log stack +904 B What the collector received: <134>1 - - - - BOOT - device started Timestamp, hostname, app-name and procid are all NILVALUE. RFC 5424 defines one for each, so the record is valid and syslog-ng parses it — filling them in is a later stage with a cost of its own, and separating the two is what lets the cost of each be seen. The three bad-config reports from the previous stage are gone, which is the other half of that stage's point. Most of the RAM is stack. The record is built on the stack of whichever task calls Log, sized by SOLIDSYSLOG_MAX_MESSAGE_SIZE, and the log seam was at the FreeRTOS floor: the first record overflowed it and the overflow hook said so. It grows to four times the floor here, which measures 1,024 bytes used against 2,048 allocated. That margin is deliberate for now and comes off at the end, once every collaborator is in place and the high-water marks are worth trusting. Two details worth knowing. Every lwIP raw call has to happen on the thread that owns the lwIP core; lwipopts.h sets LWIP_TCPIP_CORE_LOCKING, so taking the core lock in the caller's own task is simpler than posting to the tcpip mailbox and is unconditionally synchronous, which the marshal contract requires. And the collector address is a numeric literal, which keeps the resolver numeric-only — no DNS, so no LWIP_DNS and no resolver component compiled in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
81fad45 to
e0bbdb1
Compare
✅ Action performedReviews paused. |
The simplest configuration that sends a syslog message. A
SolidSyslogUdpSenderover lwIP's rawAPI, with a
SolidSyslogPassthroughBufferin front of it, soSolidSyslog_Logformats the recordand hands it straight to the sender on the calling task — no queue, no background drain, nothing
to service.
What the collector received:
Timestamp, hostname, app-name and process-id are the RFC's nil value. The record is valid without
them, and syslog-ng parses it; filling them in is the next stage. The three bad-config reports from
the previous stage are gone, which is the other half of that stage's point.
The record is built on the stack of whichever task calls
SolidSyslog_Log, sized bySOLIDSYSLOG_MAX_MESSAGE_SIZE. The logging task was at the FreeRTOS floor, and the first recordoverflowed it — the overflow hook caught it and named the task. It grows to four times the floor
here, which measures 1,024 bytes used against 2,048 allocated. The margin is deliberate: stack
allocations are tightened against measured high-water marks once every collaborator is in place.
Two details are worth getting right. Every lwIP raw call has to happen on the thread that owns the
lwIP core;
lwipopts.hsetsLWIP_TCPIP_CORE_LOCKING, so taking the core lock in the caller's owntask is simpler than posting to the tcpip mailbox and is unconditionally synchronous, which the
marshal contract requires. And the collector address is a numeric literal, which keeps the resolver
numeric-only — no DNS, so no
LWIP_DNSand no DNS resolver component compiled in.Syslog_Startalso moves aftertcpip_init, because the marshal it installs takes the lwIP corelock and
tcpip_initis what creates it.Summary by CodeRabbit
BOOTmessage in RFC 5424 format to the configured collector.