Skip to content

feat(xtcp): wide output support — jsonl/csv/tsv + tcp/file/stderr/http#36

Open
randomizedcoder wants to merge 1 commit into
feat/stdout-destinationfrom
feat/output-formats-destinations
Open

feat(xtcp): wide output support — jsonl/csv/tsv + tcp/file/stderr/http#36
randomizedcoder wants to merge 1 commit into
feat/stdout-destinationfrom
feat/output-formats-destinations

Conversation

@randomizedcoder

Copy link
Copy Markdown
Owner

Makes xtcp2 socket data easy to analyze with everyday tools (R/pandas/DuckDB/jq/Vector). Reuses the existing envelope-marshaller and destination patterns.

Stacked on #35 (feat/stdout-destination) — base it there for review; retargets to main once #35 merges. Includes the framing refactor described below.

Formats (envelope marshallers)

  • jsonl — one raw JSON record per line (NDJSON / ClickHouse JSONEachRow).
  • csv / tsv — columns generated via protobuf reflection (all 122 XtcpFlatRecord fields by default, or a -columns subset), humanized: IPs as dotted-quad/v6, TCP state & congestion as names, timestamp as RFC3339. Header written once per stream.

Destinations (stdlib, no build tag)

  • tcp:host:port — reliable streaming to Vector/Logstash/Fluentd/nc (fills the UDP-only gap).
  • file:/path — append to a file (reuses writerDest, 0600).
  • stderr — one-liner over writerDest.
  • http(s)://… — POST each batch; Content-Type derived from the marshaller.

Framing refactor

Marshallers now own their trailing newline; writerDest/tcp/http write bytes verbatim. Text formats are newline-delimited on every sink, while protobufList stays a clean length-delimited stream. (Adjusts the \n behavior introduced in #35.)

Config

New -columns flag → csv_columns proto field. marshal_to validation min_len 4→3 so csv/tsv validate. regen-protos updated all language bindings.

Tests & verification

  • Unit: humanizer (incl. the IPv4-in-16-byte-slot regression → 192.168.122.1, not c0a8:7a01::), reflection columns + -columns selection/errors, jsonl/csv/tsv output, and tcp/file/stderr/http sinks (net.Listen/httptest).
  • nix build .#test-pkg-xtcp .#test-cmd-xtcp2 .#checks.x86_64-linux.golangci-lint all pass.
  • End-to-end in a container: -dest stdout -marshal csv -columns … and -marshal jsonl printed real host sockets with humanized addresses/states (172.16.50.219, LISTEN, CUBIC).

Roadmap (not in this PR)

Influx line protocol, ClickHouse RowBinary/JSONEachRow-direct, Avro, Arrow, syslog, MQTT, Redis Streams, JetStream, Pulsar, cloud queues, SQL sinks, OTLP, a pretty table format.

🤖 Generated with Claude Code

…r/http sinks

Make socket data easy to analyze with common tools. Adds, all reusing the
existing envelope-marshaller + destination patterns:

Formats (envelope marshallers, marshallers_text.go):
- jsonl   — one raw JSON record per line (NDJSON / ClickHouse JSONEachRow)
- csv/tsv — reflection-generated columns (all 122 XtcpFlatRecord fields by
  default, or a -columns subset), humanized: IPs as dotted-quad/v6, TCP state
  and congestion as names, timestamp as RFC3339 (humanize.go, flat_record_row.go).
  Header written once per stream.

Destinations (stdlib, no build tag):
- tcp:host:port  — reliable streaming to Vector/Logstash/Fluentd/nc (fills the
  UDP-only gap)
- file:/path     — append to a file (reuses writerDest, 0600)
- stderr         — one-liner over writerDest
- http(s)://...  — POST each batch; Content-Type derived from the marshaller

Framing: marshallers now own their trailing newline and writerDest/tcp/http
write bytes verbatim, so text formats are newline-delimited on every sink while
protobufList stays a clean length-delimited stream.

Config: new -columns flag → csv_columns proto field; marshal_to min_len 4→3 so
"csv"/"tsv" validate (regen-protos updated all language bindings).

Tests cover the humanizer (incl. the IPv4-in-16-byte-slot regression),
reflection columns + selection, jsonl/csv/tsv output, and tcp/file/stderr/http
sinks (net.Listen / httptest). Verified end-to-end in a container: csv/jsonl of
real host sockets to stdout with humanized addresses/states.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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