diff --git a/deps/rabbit/include/rabbit_amqp.hrl b/deps/rabbit/include/rabbit_amqp.hrl index 84e98d5d565d..185e80fe0c64 100644 --- a/deps/rabbit/include/rabbit_amqp.hrl +++ b/deps/rabbit/include/rabbit_amqp.hrl @@ -37,6 +37,7 @@ [pid, frame_max, timeout, + container_id, vhost, user, node diff --git a/deps/rabbit/src/rabbit_amqp_reader.erl b/deps/rabbit/src/rabbit_amqp_reader.erl index 52e2ba2e8f9c..0ad228a4e653 100644 --- a/deps/rabbit/src/rabbit_amqp_reader.erl +++ b/deps/rabbit/src/rabbit_amqp_reader.erl @@ -35,6 +35,7 @@ -record(v1_connection, {name :: binary(), + container_id :: none | binary(), vhost :: none | rabbit_types:vhost(), %% server host host :: inet:ip_address() | inet:hostname(), @@ -104,6 +105,7 @@ unpack_from_0_9_1( connection_state = received_amqp3100, connection = #v1_connection{ name = ConnectionName, + container_id = none, vhost = none, host = Host, peer_host = PeerHost, @@ -491,6 +493,7 @@ handle_connection_frame( end, State1 = State0#v1{connection_state = running, connection = Connection#v1_connection{ + container_id = ContainerId, vhost = Vhost, incoming_max_frame_size = IncomingMaxFrameSize, outgoing_max_frame_size = OutgoingMaxFrameSize, @@ -969,6 +972,8 @@ i(connected_at, #v1{connection = #v1_connection{connected_at = Val}}) -> Val; i(name, #v1{connection = #v1_connection{name = Val}}) -> Val; +i(container_id, #v1{connection = #v1_connection{container_id = Val}}) -> + Val; i(vhost, #v1{connection = #v1_connection{vhost = Val}}) -> Val; i(host, #v1{connection = #v1_connection{host = Val}}) -> diff --git a/deps/rabbit/src/rabbit_networking.erl b/deps/rabbit/src/rabbit_networking.erl index 82371ec9c2cd..8e35fd0eb6e5 100644 --- a/deps/rabbit/src/rabbit_networking.erl +++ b/deps/rabbit/src/rabbit_networking.erl @@ -25,9 +25,9 @@ node_listeners/1, node_client_listeners/1, register_connection/1, unregister_connection/1, register_non_amqp_connection/1, unregister_non_amqp_connection/1, - connections/0, non_amqp_connections/0, connection_info_keys/0, - connection_info/1, connection_info/2, - connection_info_all/0, connection_info_all/1, + connections/0, non_amqp_connections/0, + connection_info/2, + connection_info_all/1, emit_connection_info_all/4, emit_connection_info_local/3, close_connection/2, close_connections/2, close_all_connections/1, close_all_user_connections/2, @@ -482,23 +482,11 @@ non_amqp_connections() -> local_non_amqp_connections() -> pg_local:get_members(rabbit_non_amqp_connections). --spec connection_info_keys() -> rabbit_types:info_keys(). - -connection_info_keys() -> rabbit_reader:info_keys(). - --spec connection_info(rabbit_types:connection()) -> rabbit_types:infos(). - -connection_info(Pid) -> rabbit_reader:info(Pid). - -spec connection_info(rabbit_types:connection(), rabbit_types:info_keys()) -> rabbit_types:infos(). connection_info(Pid, Items) -> rabbit_reader:info(Pid, Items). --spec connection_info_all() -> [rabbit_types:infos()]. - -connection_info_all() -> cmap(fun (Q) -> connection_info(Q) end). - -spec connection_info_all(rabbit_types:info_keys()) -> [rabbit_types:infos()]. diff --git a/deps/rabbit/src/rabbit_reader.erl b/deps/rabbit/src/rabbit_reader.erl index 01c3f0cb4eb8..18b3c08c8fc4 100644 --- a/deps/rabbit/src/rabbit_reader.erl +++ b/deps/rabbit/src/rabbit_reader.erl @@ -43,7 +43,7 @@ -include_lib("rabbit_common/include/rabbit_framing.hrl"). -include_lib("rabbit_common/include/rabbit.hrl"). --export([start_link/2, info_keys/0, info/1, info/2, force_event_refresh/2, +-export([start_link/2, info/2, force_event_refresh/2, shutdown/2]). -export([system_continue/3, system_terminate/4, system_code_change/4]). @@ -116,10 +116,6 @@ connection_blocked_message_sent }). --define(STATISTICS_KEYS, [pid, recv_oct, recv_cnt, send_oct, send_cnt, - send_pend, state, channels, reductions, - garbage_collection]). - -define(SIMPLE_METRICS, [pid, recv_oct, send_oct, reductions]). -define(OTHER_METRICS, [recv_cnt, send_cnt, send_pend, state, channels, garbage_collection]). @@ -132,8 +128,6 @@ timeout, frame_max, channel_max, client_properties, connected_at, node, user_who_performed_action]). --define(INFO_KEYS, ?CREATION_EVENT_KEYS ++ ?STATISTICS_KEYS -- [pid]). - -define(AUTH_NOTIFICATION_INFO_KEYS, [host, name, peer_host, peer_port, protocol, auth_mechanism, ssl, ssl_protocol, ssl_cipher, peer_cert_issuer, peer_cert_subject, @@ -188,15 +182,6 @@ system_terminate(Reason, _Parent, _Deb, _State) -> system_code_change(Misc, _Module, _OldVsn, _Extra) -> {ok, Misc}. --spec info_keys() -> rabbit_types:info_keys(). - -info_keys() -> ?INFO_KEYS. - --spec info(pid()) -> rabbit_types:infos(). - -info(Pid) -> - gen_server:call(Pid, info, infinity). - -spec info(pid(), rabbit_types:info_keys()) -> rabbit_types:infos(). info(Pid, Items) -> @@ -633,9 +618,6 @@ handle_other({'$gen_call', From, {shutdown, Explanation}}, State) -> force -> stop; normal -> NewState end; -handle_other({'$gen_call', From, info}, State) -> - gen_server:reply(From, infos(?INFO_KEYS, State)), - State; handle_other({'$gen_call', From, {info, Items}}, State) -> gen_server:reply(From, try {ok, infos(Items, State)} catch Error -> {error, Error} @@ -1627,6 +1609,7 @@ ic(client_properties, #connection{client_properties = CP}) -> CP; ic(auth_mechanism, #connection{auth_mechanism = none}) -> none; ic(auth_mechanism, #connection{auth_mechanism = {Name, _Mod}}) -> Name; ic(connected_at, #connection{connected_at = T}) -> T; +ic(container_id, _) -> ''; % AMQP 1.0 specific field ic(Item, #connection{}) -> throw({bad_argument, Item}). socket_info(Get, Select, #v1{sock = Sock}) -> diff --git a/deps/rabbit/test/amqp_client_SUITE.erl b/deps/rabbit/test/amqp_client_SUITE.erl index 75ac899075ba..7267c88bb123 100644 --- a/deps/rabbit/test/amqp_client_SUITE.erl +++ b/deps/rabbit/test/amqp_client_SUITE.erl @@ -1662,18 +1662,19 @@ events(Config) -> Protocol = {protocol, {1, 0}}, AuthProps = [{name, <<"guest">>}, - {auth_mechanism, <<"PLAIN">>}, - {ssl, false}, - Protocol], + {auth_mechanism, <<"PLAIN">>}, + {ssl, false}, + Protocol], ?assertMatch( - {value, _}, - find_event(user_authentication_success, AuthProps, Events)), + {value, _}, + find_event(user_authentication_success, AuthProps, Events)), Node = get_node_config(Config, 0, nodename), ConnectionCreatedProps = [Protocol, {node, Node}, {vhost, <<"/">>}, {user, <<"guest">>}, + {container_id, <<"my container">>}, {type, network}], {value, ConnectionCreatedEvent} = find_event( connection_created, @@ -1694,8 +1695,8 @@ events(Config) -> Pid, ClientProperties], ?assertMatch( - {value, _}, - find_event(connection_closed, ConnectionClosedProps, Events)), + {value, _}, + find_event(connection_closed, ConnectionClosedProps, Events)), ok. sync_get_unsettled_classic_queue(Config) -> @@ -3696,8 +3697,12 @@ list_connections(Config) -> [ok = rabbit_ct_client_helpers:close_channels_and_connection(Config, Node) || Node <- [0, 1, 2]], Connection091 = rabbit_ct_client_helpers:open_unmanaged_connection(Config, 0), - {ok, C0} = amqp10_client:open_connection(connection_config(0, Config)), - {ok, C2} = amqp10_client:open_connection(connection_config(2, Config)), + ContainerId0 = <<"ID 0">>, + ContainerId2 = <<"ID 2">>, + Cfg0 = maps:put(container_id, ContainerId0, connection_config(0, Config)), + Cfg2 = maps:put(container_id, ContainerId2, connection_config(2, Config)), + {ok, C0} = amqp10_client:open_connection(Cfg0), + {ok, C2} = amqp10_client:open_connection(Cfg2), receive {amqp10_event, {connection, C0, opened}} -> ok after 5000 -> ct:fail({missing_event, ?LINE}) end, @@ -3705,8 +3710,8 @@ list_connections(Config) -> after 5000 -> ct:fail({missing_event, ?LINE}) end, - {ok, StdOut} = rabbit_ct_broker_helpers:rabbitmqctl(Config, 0, ["list_connections", "--silent", "protocol"]), - Protocols0 = re:split(StdOut, <<"\n">>, [trim]), + {ok, StdOut0} = rabbit_ct_broker_helpers:rabbitmqctl(Config, 0, ["list_connections", "--silent", "protocol"]), + Protocols0 = re:split(StdOut0, <<"\n">>, [trim]), %% Remove any whitespaces. Protocols1 = [binary:replace(Subject, <<" ">>, <<>>, [global]) || Subject <- Protocols0], Protocols = lists:sort(Protocols1), @@ -3715,6 +3720,13 @@ list_connections(Config) -> <<"{1,0}">>], Protocols), + %% CLI should list AMQP 1.0 container-id + {ok, StdOut1} = rabbit_ct_broker_helpers:rabbitmqctl(Config, 0, ["list_connections", "--silent", "container_id"]), + ContainerIds0 = re:split(StdOut1, <<"\n">>, [trim]), + ContainerIds = lists:sort(ContainerIds0), + ?assertEqual([<<>>, ContainerId0, ContainerId2], + ContainerIds), + ok = rabbit_ct_client_helpers:close_connection(Connection091), ok = close_connection_sync(C0), ok = close_connection_sync(C2). @@ -6021,8 +6033,8 @@ find_event(Type, Props, Events) when is_list(Props), is_list(Events) -> fun(#event{type = EventType, props = EventProps}) -> Type =:= EventType andalso lists:all( - fun({Key, _Value}) -> - lists:keymember(Key, 1, EventProps) + fun(Prop) -> + lists:member(Prop, EventProps) end, Props) end, Events). diff --git a/deps/rabbit/test/disconnect_detected_during_alarm_SUITE.erl b/deps/rabbit/test/disconnect_detected_during_alarm_SUITE.erl index b44c6de1440f..92bf9aedd8cc 100644 --- a/deps/rabbit/test/disconnect_detected_during_alarm_SUITE.erl +++ b/deps/rabbit/test/disconnect_detected_during_alarm_SUITE.erl @@ -96,7 +96,7 @@ disconnect_detected_during_alarm(Config) -> ListConnections = fun() -> - rpc:call(A, rabbit_networking, connection_info_all, []) + rpc:call(A, rabbit_networking, connection_info_all, [[state]]) end, %% We've already disconnected, but blocked connection still should still linger on. diff --git a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex index c5a362e8859c..faa92cfbb879 100644 --- a/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex +++ b/deps/rabbitmq_cli/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex @@ -17,7 +17,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConnectionsCommand do @info_keys ~w(pid name port host peer_port peer_host ssl ssl_protocol ssl_key_exchange ssl_cipher ssl_hash peer_cert_subject peer_cert_issuer peer_cert_validity state - channels protocol auth_mechanism user vhost timeout frame_max + channels protocol auth_mechanism user vhost container_id timeout frame_max channel_max client_properties recv_oct recv_cnt send_oct send_cnt send_pend connected_at)a @@ -79,7 +79,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConnectionsCommand do def help_section(), do: :observability_and_health_checks - def description(), do: "Lists AMQP 0.9.1 connections for the node" + def description(), do: "Lists AMQP connections for the node" def banner(_, _), do: "Listing connections ..." end diff --git a/deps/rabbitmq_management/priv/www/js/global.js b/deps/rabbitmq_management/priv/www/js/global.js index 44eb4d3c2902..6acd9cdc6874 100644 --- a/deps/rabbitmq_management/priv/www/js/global.js +++ b/deps/rabbitmq_management/priv/www/js/global.js @@ -108,7 +108,8 @@ var ALL_COLUMNS = ['rate-redeliver', 'redelivered', false], ['rate-ack', 'ack', true]]}, 'connections': - {'Overview': [['user', 'User name', true], + {'Overview': [['container_id', 'Container ID', true], + ['user', 'User name', true], ['state', 'State', true]], 'Details': [['ssl', 'TLS', true], ['ssl_info', 'TLS details', false], @@ -585,7 +586,10 @@ var HELP = {
Rate at which queues are created. Declaring a queue that already exists counts for a "Declared" event, but not for a "Created" event.
\
Deleted
\
Rate at which queues are deleted.
\ - ' + ', + + 'container-id': + 'Name of the client application as sent from client to RabbitMQ in field container-id of the AMQP 1.0 open frame.' }; diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/connection.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/connection.ejs index f834b02fb5e0..07ee18ae5043 100644 --- a/deps/rabbitmq_management/priv/www/js/tmpl/connection.ejs +++ b/deps/rabbitmq_management/priv/www/js/tmpl/connection.ejs @@ -17,11 +17,20 @@ <% if (connection.client_properties.connection_name) { %> - Client-provided name + Client-provided connection name <%= fmt_string(connection.client_properties.connection_name) %> <% } %> +<% if (connection.container_id) { %> + + Container ID + + + <%= fmt_string(connection.container_id) %> + +<% } %> + Username <%= fmt_string(connection.user) %> diff --git a/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs b/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs index 464894d20876..470aa3577fbe 100644 --- a/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs +++ b/deps/rabbitmq_management/priv/www/js/tmpl/connections.ejs @@ -26,6 +26,9 @@ <% if (nodes_interesting) { %> <%= fmt_sort('Node', 'node') %> <% } %> +<% if (show_column('connections', 'container_id')) { %> + Container ID +<% } %> <% if (show_column('connections', 'user')) { %> <%= fmt_sort('User name', 'user') %> <% } %> @@ -84,7 +87,9 @@ <% if(connection.client_properties) { %> <%= link_conn(connection.name) %> - <%= fmt_string(short_conn(connection.client_properties.connection_name)) %> + <% if (connection.client_properties.connection_name) { %> + <%= fmt_string(short_conn(connection.client_properties.connection_name)) %> + <% } %> <% } else { %> <%= link_conn(connection.name) %> @@ -92,6 +97,13 @@ <% if (nodes_interesting) { %> <%= fmt_node(connection.node) %> <% } %> +<% if (show_column('connections', 'container_id')) { %> + + <% if (connection.container_id) { %> + <%= fmt_string(connection.container_id) %> + <% } %> + +<% } %> <% if (show_column('connections', 'user')) { %> <%= fmt_string(connection.user) %> <% } %> diff --git a/deps/rabbitmq_stream_management/priv/www/js/tmpl/streamConnection.ejs b/deps/rabbitmq_stream_management/priv/www/js/tmpl/streamConnection.ejs index 571293bf4837..1a5f873dc3e0 100644 --- a/deps/rabbitmq_stream_management/priv/www/js/tmpl/streamConnection.ejs +++ b/deps/rabbitmq_stream_management/priv/www/js/tmpl/streamConnection.ejs @@ -17,7 +17,7 @@ <% if (connection.client_properties.connection_name) { %> - Client-provided name + Client-provided connection name <%= fmt_string(connection.client_properties.connection_name) %> <% } %>