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