Skip to content

feat: send the first record — passthrough buffer over UDP - #31

Merged
DavidCozens merged 1 commit into
mainfrom
stage/udp
Jul 29, 2026
Merged

feat: send the first record — passthrough buffer over UDP#31
DavidCozens merged 1 commit into
mainfrom
stage/udp

Conversation

@DavidCozens

@DavidCozens DavidCozens commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Pull request

What this stage adds

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,716 B
RAM +372 B
Log stack +16 B

What the collector received:

<134>1 - - - - BOOT - device started

Every header field is a NILVALUE. RFC 5424 defines one for all of them, 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.

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.

Files

 README.md               | 11 +++----
 app/main.c              | 14 +++++++--
 app/syslog/Syslog.c     | 78 +++++++++++++++++++++++++++++++++++++++++++------
 app/tasks/LogTask.c     | 16 +++++++++-
 app/tasks/LogTask.h     |  3 +-
 measurements/stages.tsv |  1 +
 measurements/udp.csv    | 13 +++++++++
 run-report.md           | 45 ++++++++++++++--------------
 8 files changed, 139 insertions(+), 42 deletions(-)

Checklist

  • The diff is application-only — no change to board bring-up, config headers, or build infra.
  • measurements/udp.csv committed.
  • Row added to measurements/stages.tsv.
  • README regenerated: python3 scripts/gen-cost-table.py.
  • ./run.sh green (build + QEMU + baseline self-check) — run-report.md committed.

Context for review: 4 of 21 sequential single-commit PRs replaying the integration on top of the Baseline root. Each lands green and reviewed before the next is built on it, because a change to an early commit would force every commit above it to be re-run and re-measured.

Summary by CodeRabbit

  • New Features

    • Added a full UDP-based syslog pipeline for startup logs.
    • Startup now sends a BOOT record (“device started”) via the syslog path.
    • Readiness now depends on successful startup log emission in addition to the existing simulation state.
  • Bug Fixes

    • Improved syslog initialization timing so the syslog sender is started after network setup.
  • Documentation

    • Updated README stage/cost figures and run-report validation details to match the UDP syslog behavior and updated measurements.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9cbd9e7d-a386-4eb7-af19-cf07735cba25

📥 Commits

Reviewing files that changed from the base of the PR and between 021cd74 and 8761d43.

⛔ Files ignored due to path filters (2)
  • measurements/stages.tsv is excluded by !**/*.tsv
  • measurements/udp.csv is excluded by !**/*.csv
📒 Files selected for processing (6)
  • README.md
  • app/main.c
  • app/syslog/Syslog.c
  • app/tasks/LogTask.c
  • app/tasks/LogTask.h
  • run-report.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • app/tasks/LogTask.h
  • app/tasks/LogTask.c
  • README.md
  • app/main.c
  • run-report.md
  • app/syslog/Syslog.c

📝 Walkthrough

Walkthrough

The application now initializes a lwIP UDP syslog sender after TCP/IP setup, emits a BOOT record, gates readiness on successful emission, and updates documentation and run measurements for the first-record UDP flow.

Changes

UDP syslog first-record flow

Layer / File(s) Summary
UDP pipeline startup
app/syslog/Syslog.c, app/main.c
Syslog_Start builds a lwIP UDP sender with a fixed collector endpoint and is invoked after tcpip_init.
BOOT record and readiness
app/tasks/LogTask.c, app/tasks/LogTask.h, app/main.c
LogTask emits a BOOT informational record, and harness readiness now requires successful emission.
Run results and cost documentation
README.md, run-report.md
Stage descriptions, cost values, UDP measurements, and BOOT-record self-check output are updated.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HarnessTask
  participant Syslog_Start
  participant LogTask
  participant UDPCollector
  HarnessTask->>Syslog_Start: start after TCP/IP initialization
  Syslog_Start->>UDPCollector: configure UDP destination
  HarnessTask->>LogTask: emit one BOOT record
  LogTask->>UDPCollector: send BOOT syslog record
  LogTask-->>HarnessTask: return emission result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title is concise and accurately summarizes the main change: the first record sent over UDP via a passthrough buffer.
Description check ✅ Passed Description matches the required template with the stage summary and checklist, and it includes the key implementation and verification details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch stage/udp

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/syslog/Syslog.c`:
- Around line 1-9: Update the module comment near the Syslog implementation to
state that the emitted RFC 5424 message uses MSGID=BOOT and only the other
listed unset fields use NILVALUE; also update README.md lines 15-17 to replace
the claim that every header field is “-” with the precise NILVALUE fields. No
direct code behavior change is needed.

In `@app/tasks/LogTask.c`:
- Around line 41-44: The send result from SolidSyslog_Log must be propagated
before signaling completion: update app/tasks/LogTask.c lines 41-44 so
s_emitDone communicates success or failure instead of being given
unconditionally, and make LogTask_EmitOnce() return that outcome. In app/main.c
lines 69-76, preserve the existing ready/logged flow while ensuring a failed log
send cannot set ready or produce a successful exit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7ad0454f-8cb9-4630-a619-574e9eb677bf

📥 Commits

Reviewing files that changed from the base of the PR and between c1b59ec and 021cd74.

⛔ Files ignored due to path filters (2)
  • measurements/stages.tsv is excluded by !**/*.tsv
  • measurements/udp.csv is excluded by !**/*.csv
📒 Files selected for processing (6)
  • README.md
  • app/main.c
  • app/syslog/Syslog.c
  • app/tasks/LogTask.c
  • app/tasks/LogTask.h
  • run-report.md

Comment thread app/syslog/Syslog.c Outdated
Comment thread app/tasks/LogTask.c
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,716 B
  RAM      +372 B
  Log stack  +16 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.

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>
@DavidCozens
DavidCozens merged commit d14764e into main Jul 29, 2026
2 checks passed
@DavidCozens
DavidCozens deleted the stage/udp branch July 29, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant