Packages

Cafex is a pure Elixir implementation of Kafka client.

Current section

Files

Jump to
misha_cafex lib mix tasks cafex.groups.ex
Raw

lib/mix/tasks/cafex.groups.ex

defmodule Mix.Tasks.Cafex.Groups do
use Mix.Task
import Mix.Cafex
import Cafex.Consumer.Util
alias Cafex.Connection
alias Cafex.Kafka.Metadata
alias Cafex.Protocol.DescribeGroups
alias Cafex.Protocol.ListGroups
@shortdoc "List/Describe kafka consumer groups"
@recursive true
@moduledoc """
List/Describe kafka consumer groups
## Examples
mix cafex.groups -b localhost:9091
## Command line options
* `-b`, `--broker` - The Kafka broker in the form: `host1:port1`
"""
@doc false
def run(args) do
Mix.Task.run "compile"
Logger.configure level: :warn
{cli_opts, groups, _} = OptionParser.parse(args, aliases: [b: :broker])
broker = Keyword.get(cli_opts, :broker)
unless broker do
Mix.raise "Missed required arguments. Run `mix help #{Mix.Task.task_name(__MODULE__)}` for help"
end
%{servers: brokers} = parse_servers_url(broker)
ensure_started
{:ok, %{brokers: [%{host: host, port: port}|_] = brokers}} = Metadata.request(brokers, nil)
if length(groups) > 0 do
Enum.each(groups, fn group ->
describe_group(group, host, port)
end)
else
Enum.each(brokers, &list_groups/1)
end
:ok
end
defp describe_group(group, host, port) do
{host, port} = get_coordinator(group, host, port)
{:ok, conn} = Connection.start(host, port)
request = %DescribeGroups.Request{groups: [group]}
{:ok, %{groups: [%{error: error,
group_id: ^group,
state: state,
protocol_type: protocol_type,
protocol: protocol,
members: members}]}} = Connection.request(conn, request)
:ok = Connection.close(conn)
info_msg "Group: #{group}"
info_msg "Error: #{inspect error}"
info_msg "State: #{state}"
info_msg "Protocol Type: #{protocol_type}"
info_msg "Protocol: #{protocol}"
info_msg "Members:"
Enum.each(members, fn %{member_id: member_id,
client_id: client_id,
client_host: client_host,
member_metadata: {metadata_version, subscriptions, metadata_user_data},
member_assignment: {assignment_version, partitions, assignment_user_data}} ->
info_msg "======================================================"
info_msg " MemberId: #{member_id}"
info_msg " ClientId: #{client_id}"
info_msg " ClientHost: #{client_host}"
info_msg " Member Metadata:"
info_msg " Version: #{metadata_version}"
info_msg " Subscriptions: #{inspect subscriptions}"
info_msg " UserData:\n#{inspect decode_partitions(metadata_user_data), pretty: true, limit: 5000, char_lists: :as_lists}"
info_msg " Member Assignment:"
info_msg " Version: #{assignment_version}"
info_msg " Partitions:\n#{inspect partitions, pretty: true, limit: 5000, char_lists: :as_lists}"
info_msg " UserData: #{assignment_user_data}"
info_msg ""
end)
end
defp list_groups(%{node_id: id, host: host, port: port}) do
{:ok, conn} = Connection.start(host, port)
request = %ListGroups.Request{}
{:ok, response} = Connection.request(conn, request)
:ok = Connection.close(conn)
info_msg "Broker: #{id} [#{host}:#{port}]"
case response do
%{error: :no_error, groups: groups} ->
display groups
%{error: error} ->
error_msg "Error: #{inspect error}"
end
info_msg ""
end
defp display([]) do
warn_msg "No groups in this broker"
end
defp display(groups) do
Enum.each(groups, fn group ->
info_msg group
end)
end
end