1010-include_lib (" kernel/include/logger.hrl" ).
1111-include_lib (" rabbit_common/include/rabbit.hrl" ).
1212-include_lib (" amqp10_common/include/amqp10_types.hrl" ).
13+ -include (" rabbit_reader.hrl" ).
1314-include (" rabbit_amqp.hrl" ).
1415
1516-export ([init /1 ,
7980 pending_recv :: boolean (),
8081 buf :: list (),
8182 buf_len :: non_neg_integer (),
82- tracked_channels :: #{channel_number () => Session :: pid ()}
83+ tracked_channels :: #{channel_number () => Session :: pid ()},
84+ stats_timer :: rabbit_event :state ()
8385 }).
8486
8587-type state () :: # v1 {}.
9092
9193unpack_from_0_9_1 (
9294 {Sock , PendingRecv , SupPid , Buf , BufLen , ProxySocket ,
93- ConnectionName , Host , PeerHost , Port , PeerPort , ConnectedAt },
95+ ConnectionName , Host , PeerHost , Port , PeerPort , ConnectedAt , StatsTimer },
9496 Parent ) ->
9597 logger :update_process_metadata (#{connection => ConnectionName }),
9698 # v1 {parent = Parent ,
@@ -106,6 +108,7 @@ unpack_from_0_9_1(
106108 tracked_channels = maps :new (),
107109 writer = none ,
108110 connection_state = received_amqp3100 ,
111+ stats_timer = StatsTimer ,
109112 connection = # v1_connection {
110113 name = ConnectionName ,
111114 container_id = none ,
@@ -201,6 +204,10 @@ mainloop(Deb, State = #v1{sock = Sock, buf = Buf, buf_len = BufLen}) ->
201204 end
202205 end .
203206
207+ handle_other (emit_stats , State ) ->
208+ emit_stats (State );
209+ handle_other (ensure_stats_timer , State ) ->
210+ ensure_stats_timer (State );
204211handle_other ({'EXIT' , Parent , Reason }, State = # v1 {parent = Parent }) ->
205212 ReasonString = rabbit_misc :format (" broker forced connection closure with reason '~w '" ,
206213 [Reason ]),
@@ -247,8 +254,17 @@ handle_other({'$gen_call', From, {info, Items}}, State) ->
247254 end ,
248255 gen_server :reply (From , Reply ),
249256 State ;
250- handle_other ({'$gen_cast' , {force_event_refresh , _Ref }}, State ) ->
251- State ;
257+ handle_other ({'$gen_cast' , {force_event_refresh , Ref }}, State ) ->
258+ case ? IS_RUNNING (State ) of
259+ true ->
260+ % %TODO test case
261+ Infos = infos (? CONNECTION_EVENT_KEYS , State ),
262+ rabbit_event :notify (connection_created , Infos , Ref ),
263+ rabbit_event :init_stats_timer (State , # v1 .stats_timer );
264+ false ->
265+ % % Ignore, we will emit a connection_created event once we start running.
266+ State
267+ end ;
252268handle_other (terminate_connection , _State ) ->
253269 stop ;
254270handle_other ({set_credential , Cred }, State ) ->
@@ -527,6 +543,7 @@ handle_connection_frame(
527543 proplists :get_value (pid , Infos ),
528544 Infos ),
529545 ok = rabbit_event :notify (connection_created , Infos ),
546+ ok = maybe_emit_stats (State ),
530547 ok = rabbit_amqp1_0 :register_connection (self ()),
531548 Caps = [% % https://docs.oasis-open.org/amqp/linkpair/v1.0/cs01/linkpair-v1.0-cs01.html#_Toc51331306
532549 <<" LINK_PAIR_V1_0" >>,
@@ -646,7 +663,8 @@ handle_input({frame_header, Mode},
646663 " frame size (~b bytes) > maximum frame size (~b bytes)" ,
647664 [Size , MaxFrameSize ]));
648665 true ->
649- switch_callback (State , {frame_body , Mode , DOff , Channel }, Size - 8 )
666+ State1 = switch_callback (State , {frame_body , Mode , DOff , Channel }, Size - 8 ),
667+ ensure_stats_timer (State1 )
650668 end ;
651669handle_input ({frame_header , _Mode }, Malformed , _State ) ->
652670 throw ({bad_1_0_header , Malformed });
@@ -1045,6 +1063,11 @@ i(channels, #v1{tracked_channels = Channels}) ->
10451063 maps :size (Channels );
10461064i (channel_max , # v1 {connection = # v1_connection {channel_max = Max }}) ->
10471065 Max ;
1066+ i (reductions = Item , _State ) ->
1067+ {Item , Reductions } = erlang :process_info (self (), Item ),
1068+ Reductions ;
1069+ i (garbage_collection , _State ) ->
1070+ rabbit_misc :get_gc_info (self ());
10481071i (Item , # v1 {}) ->
10491072 throw ({bad_argument , Item }).
10501073
@@ -1055,6 +1078,30 @@ socket_info(Get, Select, #v1{sock = Sock}) ->
10551078 {error , _ } -> ''
10561079 end .
10571080
1081+ maybe_emit_stats (State ) ->
1082+ ok = rabbit_event :if_enabled (
1083+ State ,
1084+ # v1 .stats_timer ,
1085+ fun () -> emit_stats (State ) end ).
1086+
1087+ emit_stats (State ) ->
1088+ [{_ , Pid },
1089+ {_ , RecvOct },
1090+ {_ , SendOct },
1091+ {_ , Reductions }] = infos (? SIMPLE_METRICS , State ),
1092+ Infos = infos (? OTHER_METRICS , State ),
1093+ rabbit_core_metrics :connection_stats (Pid , Infos ),
1094+ rabbit_core_metrics :connection_stats (Pid , RecvOct , SendOct , Reductions ),
1095+ % % NB: Don't call ensure_stats_timer because it becomes expensive
1096+ % % if all idle non-hibernating connections emit stats.
1097+ rabbit_event :reset_stats_timer (State , # v1 .stats_timer ).
1098+
1099+ ensure_stats_timer (State )
1100+ when ? IS_RUNNING (State ) ->
1101+ rabbit_event :ensure_stats_timer (State , # v1 .stats_timer , emit_stats );
1102+ ensure_stats_timer (State ) ->
1103+ State .
1104+
10581105ignore_maintenance ({map , Properties }) ->
10591106 lists :member (
10601107 {{symbol , <<" ignore-maintenance" >>}, true },
0 commit comments