30
30
31
31
-export ([start /2 , stop /1 , prep_stop /1 ]).
32
32
-export ([start_apps /1 , start_apps /2 , stop_apps /1 ]).
33
+ -export ([product_info /0 ,
34
+ product_name /0 ,
35
+ product_version /0 ,
36
+ motd_file /0 ,
37
+ motd /0 ]).
33
38
-export ([log_locations /0 , config_files /0 ]). % % for testing and mgmt-agent
34
39
-export ([is_booted /1 , is_booted /0 , is_booting /1 , is_booting /0 ]).
35
40
@@ -376,8 +381,9 @@ run_prelaunch_second_phase() ->
376
381
start_it (StartType ) ->
377
382
case spawn_boot_marker () of
378
383
{ok , Marker } ->
384
+ Product = product_name (),
379
385
T0 = erlang :timestamp (),
380
- rabbit_log :info (" RabbitMQ is asked to start..." , []),
386
+ rabbit_log :info (" ~s is asked to start..." , [Product ]),
381
387
try
382
388
{ok , _ } = application :ensure_all_started (rabbitmq_prelaunch ,
383
389
StartType ),
@@ -387,8 +393,8 @@ start_it(StartType) ->
387
393
388
394
T1 = erlang :timestamp (),
389
395
rabbit_log_prelaunch :debug (
390
- " Time to start RabbitMQ : ~p µs" ,
391
- [timer :now_diff (T1 , T0 )]),
396
+ " Time to start ~s : ~p µs" ,
397
+ [Product , timer :now_diff (T1 , T0 )]),
392
398
stop_boot_marker (Marker ),
393
399
ok
394
400
catch
@@ -436,10 +442,12 @@ stop() ->
436
442
ok ->
437
443
case rabbit_boot_state :get () of
438
444
ready ->
439
- rabbit_log :info (" RabbitMQ is asked to stop..." ),
445
+ Product = product_name (),
446
+ rabbit_log :info (" ~s is asked to stop..." , [Product ]),
440
447
do_stop (),
441
448
rabbit_log :info (
442
- " Successfully stopped RabbitMQ and its dependencies" ),
449
+ " Successfully stopped ~s and its dependencies" ,
450
+ [Product ]),
443
451
ok ;
444
452
stopped ->
445
453
ok
@@ -463,7 +471,9 @@ stop_and_halt() ->
463
471
try
464
472
stop ()
465
473
catch Type :Reason ->
466
- rabbit_log :error (" Error trying to stop RabbitMQ: ~p :~p " , [Type , Reason ]),
474
+ rabbit_log :error (
475
+ " Error trying to stop ~s : ~p :~p " ,
476
+ [product_name (), Type , Reason ]),
467
477
error ({Type , Reason })
468
478
after
469
479
% % Enclose all the logging in the try block.
@@ -519,9 +529,9 @@ stop_apps([]) ->
519
529
ok ;
520
530
stop_apps (Apps ) ->
521
531
rabbit_log :info (
522
- lists :flatten ([" Stopping RabbitMQ applications and their dependencies in the following order:~n " ,
532
+ lists :flatten ([" Stopping ~s applications and their dependencies in the following order:~n " ,
523
533
[" ~p~n " || _ <- Apps ]]),
524
- lists :reverse (Apps )),
534
+ [ product_name () | lists :reverse (Apps )] ),
525
535
ok = app_utils :stop_applications (
526
536
Apps , handle_app_error (error_during_shutdown )),
527
537
case lists :member (rabbit , Apps ) of
@@ -664,7 +674,7 @@ maybe_print_boot_progress(true, IterationsLeft) ->
664
674
{memory , any ()}].
665
675
666
676
status () ->
667
- { ok , Version } = application : get_key ( rabbit , vsn ),
677
+ Version = product_version ( ),
668
678
S1 = [{pid , list_to_integer (os :getpid ())},
669
679
% % The timeout value used is twice that of gen_server:call/2.
670
680
{running_applications , rabbit_misc :which_applications ()},
@@ -817,9 +827,10 @@ start(normal, []) ->
817
827
try
818
828
run_prelaunch_second_phase (),
819
829
820
- rabbit_log :info (" ~n Starting RabbitMQ ~s on Erlang ~s~n ~s~n ~s~n " ,
821
- [rabbit_misc : version (), rabbit_misc :otp_release (),
830
+ rabbit_log :info (" ~n Starting ~s ~s on Erlang ~s~n ~s~n ~s~n " ,
831
+ [product_name (), product_version (), rabbit_misc :otp_release (),
822
832
? COPYRIGHT_MESSAGE , ? INFORMATION_MESSAGE ]),
833
+ log_motd (),
823
834
{ok , SupPid } = rabbit_sup :start_link (),
824
835
825
836
% % Compatibility with older RabbitMQ versions + required by
@@ -905,7 +916,7 @@ do_run_postlaunch_phase() ->
905
916
end
906
917
end , Plugins ),
907
918
908
- rabbit_log_prelaunch :debug (" Marking RabbitMQ as running" ),
919
+ rabbit_log_prelaunch :debug (" Marking ~s as running" , [ product_name ()] ),
909
920
rabbit_boot_state :set (ready ),
910
921
911
922
ok = rabbit_lager :broker_is_started (),
@@ -1059,8 +1070,8 @@ log_broker_started(Plugins) ->
1059
1070
" ~n " ? BG32_START " " ? C_END " ~s " ).
1060
1071
1061
1072
print_banner () ->
1062
- { ok , Product } = application : get_key ( description ),
1063
- { ok , Version } = application : get_key ( vsn ),
1073
+ Product = product_name ( ),
1074
+ Version = product_version ( ),
1064
1075
LineListFormatter = fun (Placeholder , [_ | Tail ] = LL ) ->
1065
1076
LF = lists :flatten ([Placeholder || _ <- lists :seq (1 , length (Tail ))]),
1066
1077
{LF , LL };
@@ -1083,8 +1094,21 @@ print_banner() ->
1083
1094
% % padded list lines
1084
1095
{LogFmt , LogLocations } = LineListFormatter (" ~n ~ts " , log_locations ()),
1085
1096
{CfgFmt , CfgLocations } = LineListFormatter (" ~n ~ts " , config_locations ()),
1097
+ {MOTDFormat , MOTDArgs } = case motd () of
1098
+ undefined ->
1099
+ {" " , []};
1100
+ MOTD ->
1101
+ Lines = string :split (MOTD , " \n " , all ),
1102
+ Padded = [case Line of
1103
+ <<>> -> " \n " ;
1104
+ _ -> [" " , Line , " \n " ]
1105
+ end
1106
+ || Line <- Lines ],
1107
+ {" ~n~ts " , [Padded ]}
1108
+ end ,
1086
1109
io :format (Logo ++
1087
- " ~n "
1110
+ " ~n " ++
1111
+ MOTDFormat ++
1088
1112
" ~n Doc guides: https://rabbitmq.com/documentation.html"
1089
1113
" ~n Support: https://rabbitmq.com/contact.html"
1090
1114
" ~n Tutorials: https://rabbitmq.com/getstarted.html"
@@ -1094,9 +1118,24 @@ print_banner() ->
1094
1118
" ~n Config file(s): ~ts " ++ CfgFmt ++ " ~n "
1095
1119
" ~n Starting broker..." ,
1096
1120
[Product , Version , ? COPYRIGHT_MESSAGE , ? INFORMATION_MESSAGE ] ++
1121
+ MOTDArgs ++
1097
1122
LogLocations ++
1098
1123
CfgLocations ).
1099
1124
1125
+ log_motd () ->
1126
+ case motd () of
1127
+ undefined ->
1128
+ ok ;
1129
+ MOTD ->
1130
+ Lines = string :split (MOTD , " \n " , all ),
1131
+ Padded = [case Line of
1132
+ <<>> -> " \n " ;
1133
+ _ -> [" " , Line , " \n " ]
1134
+ end
1135
+ || Line <- Lines ],
1136
+ rabbit_log :info (" ~n~ts " , [string :trim (Padded , trailing , [$\r , $\n ])])
1137
+ end .
1138
+
1100
1139
log_banner () ->
1101
1140
{FirstLog , OtherLogs } = case log_locations () of
1102
1141
[Head | Tail ] ->
@@ -1236,6 +1275,114 @@ validate_msg_store_io_batch_size_and_credit_disc_bound(CreditDiscBound,
1236
1275
end
1237
1276
end .
1238
1277
1278
+ - spec product_name () -> string ().
1279
+
1280
+ product_name () ->
1281
+ #{name := ProductName } = product_info (),
1282
+ ProductName .
1283
+
1284
+ - spec product_version () -> string ().
1285
+
1286
+ product_version () ->
1287
+ #{version := ProductVersion } = product_info (),
1288
+ ProductVersion .
1289
+
1290
+ - spec product_info () -> #{name := string (),
1291
+ version := string ()}.
1292
+
1293
+ product_info () ->
1294
+ PTKey = {? MODULE , product },
1295
+ try
1296
+ % % The value is cached the first time to avoid calling the
1297
+ % % application master many times just for that.
1298
+ persistent_term :get (PTKey )
1299
+ catch
1300
+ error :badarg ->
1301
+ {NameFromEnv , VersionFromEnv } =
1302
+ case rabbit_env :get_context () of
1303
+ #{product_name := NFE ,
1304
+ product_version := VFE } -> {NFE , VFE };
1305
+ _ -> {undefined , undefined }
1306
+ end ,
1307
+
1308
+ Info =
1309
+ if
1310
+ NameFromEnv =/= undefined andalso
1311
+ VersionFromEnv =/= undefined ->
1312
+ #{name => NameFromEnv ,
1313
+ version => VersionFromEnv };
1314
+ true ->
1315
+ _ = application :load (rabbit ),
1316
+ Name = case NameFromEnv of
1317
+ undefined ->
1318
+ string_from_app_env (
1319
+ product_name ,
1320
+ base_product_name ());
1321
+ _ ->
1322
+ NameFromEnv
1323
+ end ,
1324
+ Version = case VersionFromEnv of
1325
+ undefined ->
1326
+ string_from_app_env (
1327
+ product_version ,
1328
+ base_product_version ());
1329
+ _ ->
1330
+ VersionFromEnv
1331
+ end ,
1332
+ #{name => Name ,
1333
+ version => Version }
1334
+ end ,
1335
+ persistent_term :put (PTKey , Info ),
1336
+ Info
1337
+ end .
1338
+
1339
+ string_from_app_env (Key , Default ) ->
1340
+ case application :get_env (rabbit , Key ) of
1341
+ {ok , Val } ->
1342
+ case io_lib :deep_char_list (Val ) of
1343
+ true ->
1344
+ case lists :flatten (Val ) of
1345
+ " " -> Default ;
1346
+ String -> String
1347
+ end ;
1348
+ false ->
1349
+ Default
1350
+ end ;
1351
+ undefined ->
1352
+ Default
1353
+ end .
1354
+
1355
+ base_product_name () ->
1356
+ % % This function assumes the `rabbit` application was loaded in
1357
+ % % product_info().
1358
+ {ok , Product } = application :get_key (rabbit , description ),
1359
+ Product .
1360
+
1361
+ base_product_version () ->
1362
+ % % This function assumes the `rabbit` application was loaded in
1363
+ % % product_info().
1364
+ rabbit_misc :version ().
1365
+
1366
+ motd_file () ->
1367
+ case rabbit_env :get_context () of
1368
+ #{motd_file := File } ->
1369
+ File ;
1370
+ _ ->
1371
+ _ = application :load (rabbit ),
1372
+ string_from_app_env (motd_file , undefined )
1373
+ end .
1374
+
1375
+ motd () ->
1376
+ case motd_file () of
1377
+ undefined ->
1378
+ undefined ;
1379
+ File ->
1380
+ case file :read_file (File ) of
1381
+ {ok , MOTD } -> string :trim (MOTD , trailing , [$\r ,$\n ]);
1382
+ {error , _ } -> undefined
1383
+ end
1384
+ end .
1385
+
1239
1386
home_dir () ->
1240
1387
case init :get_argument (home ) of
1241
1388
{ok , [[Home ]]} -> Home ;
0 commit comments