Skip to content

[Feature] Syslog log sink — RFC 5424 over UDP, TCP and TLS #1161

Description

@pathosDev

Part of the multi-sink logging effort (meta issue below). Builds on the core pipeline and
BatchingSink issues.

Why syslog

It is the one integration that needs no vendor at all: rsyslog, syslog-ng, journald's
forwarder, Papertrail and a long tail of network appliances all speak it. One sink covers
all of them.

Scope

src/logging/SyslogSink.ts + options family, extends BatchingSink.

RFC 5424 frame:

<134>1 2026-08-12T09:41:02.113Z host app-name 1234 - - order placed {orderId=42}
  • PRI = facility * 8 + severity; severity mapped Debug → 7, Info → 6, Warn → 4,
    Error → 3; facility defaults to 16 (local0)
  • RFC 3339 timestamp with millisecond precision
  • HOSTNAME from options or the OS hostname; APP-NAME defaults to the system name;
    PROCID is the process id where available, else -; MSGID is -
  • the structured-data element is deliberately - in v1: a well-formed SD-ID needs an IANA
    private enterprise number. Fields are appended to MSG as the same {k=v} suffix the
    text formatter uses. Documented, and revisitable if someone wants an enterprise id.

Transports:

  • UDP via the same lazy node:dgram module type the GELF sink uses
  • TCP / TLS via getTcpBackend().connect(...), with framing octet-counting
    (RFC 6587, <length> <frame>) or lf

Options: transport (udp | tcp | tls), host, port (514), facility, appName,
hostName, framing, tls (code-only), delivery. HOCON block
actor-ts.logger.sinks.syslog.

Acceptance criteria

  • byte-exact frames for both framings, verified against the RFC's own example shape
  • PRI arithmetic across facilities and all four levels
  • a message containing a newline cannot break octet-counting framing
  • UDP and TCP transports exercised through injectable seams, no network in tests
  • docs section in observability/logging/integrations, EN + DE, noting the omitted
    structured-data element and why
  • CHANGELOG entry
  • bun run typecheck + bun test green on every commit; coverage gate before merge

Reference

Part of #1150.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowNice-to-have / niche / demand-driven

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions