Class SyslogAuditSink

java.lang.Object
com.mcpdbwizard.pub.SyslogAuditSink
All Implemented Interfaces:
McpAuditSink

public class SyslogAuditSink extends Object implements McpAuditSink
Sends audit records to a syslog collector as RFC 5424 messages.

Select it with MCP_AUDIT_SINK=com.mcpdbwizard.pub.SyslogAuditSink. It needs no library: syslog is a line on a socket, which is most of why it is worth having — nearly every SIEM already listens for it, and adding one costs this project no dependency at all.

Environment
MCP_AUDIT_SYSLOG_HOSTRequired. The collector.
MCP_AUDIT_SYSLOG_PORTDefault 514.
MCP_AUDIT_SYSLOG_PROTOCOLtcp (default) or udp.
MCP_AUDIT_SYSLOG_FACILITY0-23, default 13 (log audit).
MCP_AUDIT_SYSLOG_APP_NAMEAPP-NAME field, default "mcpdbwizard".

Use TCP. UDP cannot tell you whether the trail is complete.

Over UDP a record is written to a socket and nothing ever comes back: a collector that is down, full, or behind a dropping firewall is indistinguishable from one that recorded everything. That is tolerable for logs and a poor fit for evidence, so the default is TCP and choosing UDP is warned about at start-up.

What flush() means here, precisely

It reports whether any send since the previous flush failed locally — a refused connection, a broken pipe, a socket error. It does not mean the collector indexed the record, because syslog has no acknowledgement in either transport; even over TCP the guarantee stops at the far end's kernel accepting the bytes.

That matters most in front of a spool. SpoolingAuditSink deletes a segment when this returns true, so with syslog the spool protects against this process dying and against the collector being unreachable, and not against a collector that accepts bytes and discards them. Returning false unconditionally over UDP was considered and rejected: it would be just as untrue, and it would make the spool grow until it hit its cap and began dropping records — trading a small uncertainty for a certain loss. Copyright 2003-2026 ATB Consultancy Services Ltd (formerly Orinda Software Ltd, Dublin, Ireland)

  • Field Details

  • Constructor Details

    • SyslogAuditSink

      public SyslogAuditSink()
      Built reflectively by McpAuditSinks.fromEnvironment().
    • SyslogAuditSink

      public SyslogAuditSink(String theHostValue, int thePortValue, boolean theUdpFlagValue, int theFacilityValue, String theAppNameValue)
  • Method Details

    • record

      public void record(McpAuditEvent theEvent)
      Record one call. Must not throw.

      Never throws.

      Specified by:
      record in interface McpAuditSink
      Parameters:
      theEvent - the call to record; never null
    • flush

      public boolean flush()
      Confirm that everything handed to McpAuditSink.record(com.mcpdbwizard.pub.McpAuditEvent) since the last flush is durably accepted.

      This is what makes a spool possible. A spool writes each record to disk first and may only delete it once the sink has genuinely taken it — and for an asynchronous sink like Kafka, record returning tells you nothing, because the send has not completed yet.

      The default returns true, which is correct for a sink that delivers synchronously inside record. An asynchronous sink must override it, and must return false if anything since the last flush was lost — returning true on a failed batch would let a spool delete records that never arrived, which is the one way a spool can be worse than no spool.

      Compared against the count at the END OF THE PREVIOUS FLUSH, not the start of this one — the same rule KafkaAuditSink.flush() documents at length. record(com.mcpdbwizard.pub.McpAuditEvent) fails synchronously here, so sampling the counter at the top of this method could not see a failure that had already happened, and a spool would delete a segment whose records never left the machine.

      Specified by:
      flush in interface McpAuditSink
      Returns:
      true if everything since the last flush is safely delivered
    • getDroppedCount

      public long getDroppedCount()
      Description copied from interface: McpAuditSink
      How many records this sink is known to have LOST, or -1 when it does not report.

      The number an operator actually needs, and the one nothing surfaced before: a trail is only worth citing if it is complete, and "complete" is exactly what a drop count denies. Reported through the SPI rather than by casting to a particular sink so a status page keeps working when the sink is swapped.

      -1 means "this sink does not count", which a caller must show differently from 0. Claiming zero losses on a sink that cannot tell is the one wrong answer here.

      Specified by:
      getDroppedCount in interface McpAuditSink
    • getDeliveredCount

      public long getDeliveredCount()
      Description copied from interface: McpAuditSink
      How many records were confirmed delivered, or -1 when the sink does not report.
      Specified by:
      getDeliveredCount in interface McpAuditSink
    • describe

      public String describe()
      Description copied from interface: McpAuditSink
      A short human description of what this sink is, for an operator reading a status page.

      Defaults to the class name. A wrapper overrides it to name what it wraps — otherwise a spooled Kafka sink reports only "SpoolingAuditSink", and where the records finally go is the part being asked about.

      Specified by:
      describe in interface McpAuditSink
    • close

      public void close()
      Specified by:
      close in interface McpAuditSink