Skip to content

Add share group consumer#252

Open
orangecola wants to merge 9 commits into
logstash-plugins:mainfrom
orangecola:main
Open

Add share group consumer#252
orangecola wants to merge 9 commits into
logstash-plugins:mainfrom
orangecola:main

Conversation

@orangecola

Copy link
Copy Markdown

Fixes #251

E2E Testing:

$ docker exec ls-test sh -c 'pkill -f logstash; rm -f /tmp/share_output.jsonl /tmp/ls.log; sleep 2' 2>&1
docker exec kafka-sg /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic final-test --partitions 3 --replication-factor 1 2>&1
docker exec kafka-sg /opt/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config share.auto.offset.reset=earliest --entity-type groups --entity-name final-group 2>&1
for i in $(seq 1 50); do echo "final-$i"; done | docker exec -i kafka-sg /opt/kafka/bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic final-test 2>&1 | tail -1

cat > /tmp/final.conf <<'EOF'
input {
  kafka {
    bootstrap_servers => "kafka-sg:9092"
    topics => ["final-test"]
    group_id => "final-group"
    consumer_mode => "share_group"
    consumer_threads => 3
    client_id => "final-smoke"
    codec => "plain"
    poll_timeout_ms => 500
  }
}
output {
  file { path => "/tmp/share_output.jsonl" codec => line { format => "%{message}" } }
}
EOF
docker cp /tmp/final.conf ls-test:/tmp/final.conf
docker exec -d ls-test sh -c '/usr/share/logstash/bin/logstash -f /tmp/final.conf --path.data /tmp/ls-data-final > /tmp/ls.log 2>&1'
for i in 1 2 3 4 5 6 7 8; do
  sleep 5
  count=$(docker exec ls-test sh -c 'test -f /tmp/share_output.jsonl && wc -l < /tmp/share_output.jsonl || echo 0' 2>&1 | tr -d ' ')
  echo "t=${i}x5s: received=$count"
  if [ "$count" = "50" ]; then break; fi
done
echo "=== SUMMARY ==="
docker exec ls-test sh -c 'echo "total=$(wc -l < /tmp/share_output.jsonl)  unique=$(sort -u /tmp/share_output.jsonl | wc -l)  duplicates=$(sort /tmp/share_output.jsonl | uniq -d | wc -l)"' 2>&1
echo "=== error check ==="
docker exec ls-test sh -c 'grep -cE "\[ERROR\]" /tmp/ls.log' 2>&1
docker exec ls-test sh -c 'grep -E "\[ERROR\]" /tmp/ls.log | grep -v -E "licensereader|monitoring"' 2>&1 | head -5

Created topic final-test.
Completed updating config for group final-group.
t=1x5s: received=37
t=2x5s: received=37
t=3x5s: received=37
t=4x5s: received=87
t=5x5s: received=87
t=6x5s: received=87
t=7x5s: received=87
t=8x5s: received=87
=== SUMMARY ===
total=87  unique=85  duplicates=1
=== error check ===
3

@alexcams alexcams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for this contribution @orangecola! The overall implementation looks nice, just left some nits worth to check.
Could you also update CHANGELOG.md file and bump version in gempspec?

Comment thread lib/logstash/inputs/kafka.rb Outdated
Comment thread lib/logstash/inputs/kafka.rb Outdated
Comment thread docs/input-kafka.asciidoc Outdated
Comment thread lib/logstash/inputs/kafka.rb
@orangecola

Copy link
Copy Markdown
Author

Addressed comments and updated version files.

Thanks for this contribution @orangecola! The overall implementation looks nice, just left some nits worth to check. Could you also update CHANGELOG.md file and bump version in gempspec?

@alexcams alexcams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for addressing the comments @orangecola! I've been testing this feature manually and I can confirm the share group consumer works correctly — records are distributed across threads without specific thread-partition assignment.

While checking the docs, I've seen a recommendation for consumer_threads config that states:

Ideally you should have as many threads as the number of partitions for a perfect balance -- more threads than partitions means that some threads will be idle

in 3 places:

Would you mind updating this to be consistent with the new share_group consumer mode?
Thanks in advance!

@orangecola orangecola requested a review from alexcams April 27, 2026 15:03

@alexcams alexcams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Requested changes in last review

@orangecola

Copy link
Copy Markdown
Author

mb, didn't push changes.

@orangecola orangecola requested a review from alexcams April 27, 2026 15:16

@alexcams alexcams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @orangecola!

@mashhurs mashhurs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe this feature will be 🚀. Thank you alot for the contribution.
The implementation details, docs and format look good to me as well (will review docs section with second round).

One critical concern is that when pipeline config contains the params which cannot be used with share_group, I would support raising a config error instead of silently ignoring. For example, the following config looks invalid to me:

input {
  kafka {
    enable_auto_commit => true
    consumer_mode => "share_group"
  }
}

!header.nil? && !header.value.nil? && !header.key.nil?
end

def validate_share_group_config!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not_allowed_configs_with_share_group =  original_params.keys & %w( group_protocol group_instance_id partition_assignment_strategy enable_auto_commit auto_commit_interval_ms)

if not_allowed_configs_with_share_group.size > 1
  error_message = "#{not_allowed_configs_with_share_group} options cannot be used together when `consumer_mode => 'share_group'`"
  raise LogStash::ConfigurationError, error_message
end

# Schema Registry (`schema_registry_url`) is also not supported.
# The following options are silently ignored in `share_group` mode because they do not
# apply to the Share Group protocol: `heartbeat_interval_ms`, `session_timeout_ms`,
# `isolation_level`, `enable_auto_commit`, `auto_commit_interval_ms`, `auto_offset_reset`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I will also pull, run on my local and review in detail but I would be really specific and not allow enable_auto_commit, heartbeat_interval_ms, etc... params if pipeline config contains. The original_params.keys provides the pipeline config param keys (I will comment below how it can be used).

@orangecola orangecola requested a review from mashhurs April 28, 2026 12:21
@orangecola

Copy link
Copy Markdown
Author

Combined schema_registry_url with other field checks.

@yaauie yaauie left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall, excellent work and a welcome contribution. Thank you!

I've left a few comments in-line, addressing:

  • translating the kafka-ish docs to how the settings apply in the context of a logstash pipeline
  • validating that share_group-specific config options aren't used in conjunction with the consumer_mode => consumer_group (an inversion of the check already added that ensures that consumer_group-specific settings aren't used with the new consumer_mode => share_group)

Comment thread lib/logstash/inputs/kafka.rb Outdated
Comment thread lib/logstash/inputs/kafka.rb Outdated
Comment thread lib/logstash/inputs/kafka.rb
Comment thread docs/input-kafka.asciidoc Outdated
Comment thread docs/input-kafka.asciidoc
Comment thread docs/input-kafka.asciidoc Outdated
Comment thread docs/input-kafka.asciidoc Outdated
Comment thread lib/logstash/inputs/kafka.rb Outdated
Comment thread lib/logstash/inputs/kafka.rb Outdated
@cla-checker-service

cla-checker-service Bot commented May 1, 2026

Copy link
Copy Markdown

💚 CLA has been signed

- Move check_crcs and auto_create_topics to build_common_props (both supported by KafkaShareConsumer)
- Add CONSUMER_GROUP_ONLY_OPTIONS + validate_consumer_group_config! to raise on share_group_acknowledgement_on_error with consumer_group mode
- Release unprocessed records on shutdown in share_group_thread_runner instead of blocking on queue
- Replace ternary with if/else for @share_group_ack_error_type assignment
- Update consumer_threads docs with clearer partition/thread guidance per mode
- Update share group acknowledgement docs to clarify pipeline queue visibility boundary
- Update share_group_acknowledgement_on_error docs to frame around pipeline semantics
- Add note about broker/group-level equivalents for incompatible share_group options

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
orangecola and others added 3 commits May 1, 2026 08:48
- Remove check_crcs from share_group incompatible list in unit test (it's now supported)
- Add unit test confirming check_crcs is accepted in share_group mode
- Add unit test for validate_consumer_group_config! raising on share_group_acknowledgement_on_error
- Add share_group integration tests: config validation + live consumption via Kafka 4.2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Rye Biesemeyer <yaauie@users.noreply.github.com>
@orangecola

Copy link
Copy Markdown
Author

@yaauie / @alexcams updated with suggestions, bumping for review.

@orangecola orangecola requested review from alexcams and yaauie June 23, 2026 02:26
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.

Add share group consumers in kafka

4 participants