Skip to content

Added support for TCP octet-counting framing - #83

Open
diligent-raccoon wants to merge 4 commits into
logstash-plugins:mainfrom
diligent-raccoon:main
Open

Added support for TCP octet-counting framing#83
diligent-raccoon wants to merge 4 commits into
logstash-plugins:mainfrom
diligent-raccoon:main

Conversation

@diligent-raccoon

Copy link
Copy Markdown

Hello,

Intro

First time creating a PR so I'm prepared to having to redo it until it's fit this repo standards.
I've signed the CLA.

PR Goal

My goal with this PR is to allow the syslog input plugin to support receiving logs from assets using transparent framing, also called octet counting, as it is described in the RFC 6587 section 3.4.1.

Changes

I tinkered with the tcp_read_lines function and added a check.
If the first character in a buffer is a number, it will proceed with reading the first 16 chars (arbitrary number to make sure to capture the number of bytes in the log while not reading too much) and cut at the first space. The space is the delimiter specified in RFC 6587.
It will then read the next log_len amount of bytes minus the bytes that remained in the buffer and yield the result for processing.
If the first char is not a digit, the handling of the log does not change, looking for the "\n" to cut off the log.

Limitations

This PR was written with the assumption that the logs were sent in good faith and that the bytes in the header do represent the length of the log. If the byte count at the start of the log is wrong, logs will be truncated / malformed and the input may crash and restart.

@github-actions

Copy link
Copy Markdown

Changelog and Version Management

No changelog or version changes detected. You can either update them manually or use a comment command to update them automatically on merge:

/pr_prepare release:<patch|minor|major> — bump version + update changelog
/pr_prepare changelog:add — changelog entry only (no version bump)

/pr_prepare release:patch
- Add the changelog entry here
  - (Additional details can be provided in multiple lines, respecting markdown formatting)

Omit the entry line to use the PR title. If multiple commands are posted, the last one wins.

Copilot AI 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.

Pull request overview

This PR updates the Logstash syslog input plugin to support RFC 6587 transparent framing (octet-counting) for TCP syslog ingestion, and bumps the plugin version/documentation accordingly.

Changes:

  • Add octet-counting (transparent framing) logic to tcp_read_lines for TCP inputs.
  • Bump plugin version to 3.8.0 and add a changelog entry for the new feature.
  • Update plugin documentation to mention TCP framing and link to RFC 6587.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
version Bumps plugin version to 3.8.0.
lib/logstash/inputs/syslog.rb Implements transparent-framing parsing in the TCP read loop.
docs/index.asciidoc Documents TCP framing support and adds RFC 6587 reference.
CHANGELOG.md Adds a 3.8.0 entry describing transparent framing support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

end
end
end
if buffer[0].match?(/\d/) #Check if the first char is a digit

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Could not find information supporting this, tests are passing without issue and I do not understand why adding an anchor would help.

Comment on lines +240 to +244
buffer << socket.read_nonblock(16)
first_space = buffer.index(" ")
log_len = Integer(buffer.slice!(0..first_space))
buffer << socket.read_nonblock(log_len-buffer.length)
yield buffer.slice!(0..log_len)
Comment on lines +237 to +242
if buffer[0].match?(/\d/) #Check if the first char is a digit
loop do
begin
buffer << socket.read_nonblock(16)
first_space = buffer.index(" ")
log_len = Integer(buffer.slice!(0..first_space))
Comment thread docs/index.asciidoc Outdated
Comment on lines +36 to +38
This input also supports both transparent and non-transparent TCP framing..

For more information see the http://www.ietf.org/rfc/rfc3164.txt[RFC3164 page].
For more information on syslog see the http://www.ietf.org/rfc/rfc3164.txt[RFC3164 page] and for more information on TCP framing see the https://www.ietf.org/rfc/rfc6587.txt[RFC 6587 page].
Comment thread CHANGELOG.md
@diligent-raccoon

Copy link
Copy Markdown
Author

Will have a deeper look at the PROXY and the first_space being nil later.

@diligent-raccoon

Copy link
Copy Markdown
Author

NoMethodError with match?

As mentioned in my comment, I could not find references supporting this and the tests from the suite and the tests I've done on my side are passing without issue. I also don't quite understand how adding an anchor (\A) would help to solve the problem.
Inputs are welcome on this topic.

first_space is nil and log length handling

Valid issue and the code suggested sounds sane, will run test and validate on my side.

Framing mode and PROXY / grok pattern

This is a valid issue imo and I wanted to get some advice on how to go about it, the philosophy of the plugins and their configuration.
I would add a new configuration parameter tcp_framing with the values explicit, auto, transparent.

  • explicit: Assumed framing is explicit and all connection are treated as such. This is the current behavior of the input.
  • auto: Would behave like first presented in this PR: each new connection would get test to pick either explicit or transparent framing
  • transparent: Assumed framing is transparent and all connection are treated as such.

The default would be explicit.

Defaulting to explicit would leave currently configured inputs in production working as they were before without having to set the parameter to explicit for every input that might be affected (using a PROXY or custom grok pattern).
Being able to choose between all three gives all the flexibility needed to configure the input.

Does this sound like a sane approach ? Do you have any suggestion / recommendation ?

Of course I am aware this includes creating the dedicated documentation section and all that jazz.

@diligent-raccoon diligent-raccoon changed the title Added added support for TCP octet-counting framing Added support for TCP octet-counting framing Jul 22, 2026
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.

3 participants