Merge pull request #2861 from rabbitmq/use-builtin-logger
Switch from Lager to the new Erlang Logger API for logging
This commit is contained in:
commit
132dee6516
|
|
@ -228,7 +228,7 @@ hdr_sent(_EvtType, {protocol_header_received, 0, 1, 0, 0}, State) ->
|
|||
end;
|
||||
hdr_sent(_EvtType, {protocol_header_received, Protocol, Maj, Min,
|
||||
Rev}, State) ->
|
||||
error_logger:warning_msg("Unsupported protocol version: ~b ~b.~b.~b~n",
|
||||
logger:warning("Unsupported protocol version: ~b ~b.~b.~b",
|
||||
[Protocol, Maj, Min, Rev]),
|
||||
{stop, normal, State};
|
||||
hdr_sent({call, From}, begin_session,
|
||||
|
|
@ -291,7 +291,7 @@ opened(info, {'DOWN', MRef, _, _, _Info},
|
|||
ok = notify_closed(Config, shutdown),
|
||||
{stop, normal, State};
|
||||
opened(_EvtType, Frame, State) ->
|
||||
error_logger:warning_msg("Unexpected connection frame ~p when in state ~p ~n",
|
||||
logger:warning("Unexpected connection frame ~p when in state ~p ",
|
||||
[Frame, State]),
|
||||
{keep_state, State}.
|
||||
|
||||
|
|
@ -367,7 +367,7 @@ send_open(#state{socket = Socket, config = Config}) ->
|
|||
end,
|
||||
Encoded = amqp10_framing:encode_bin(Open),
|
||||
Frame = amqp10_binary_generator:build_frame(0, Encoded),
|
||||
?DBG("CONN <- ~p~n", [Open]),
|
||||
?DBG("CONN <- ~p", [Open]),
|
||||
socket_send(Socket, Frame).
|
||||
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ send_close(#state{socket = Socket}, _Reason) ->
|
|||
Close = #'v1_0.close'{},
|
||||
Encoded = amqp10_framing:encode_bin(Close),
|
||||
Frame = amqp10_binary_generator:build_frame(0, Encoded),
|
||||
?DBG("CONN <- ~p~n", [Close]),
|
||||
?DBG("CONN <- ~p", [Close]),
|
||||
Ret = socket_send(Socket, Frame),
|
||||
case Ret of
|
||||
ok -> _ =
|
||||
|
|
@ -397,7 +397,7 @@ send_sasl_init(State, {plain, User, Pass}) ->
|
|||
send(Record, FrameType, #state{socket = Socket}) ->
|
||||
Encoded = amqp10_framing:encode_bin(Record),
|
||||
Frame = amqp10_binary_generator:build_frame(0, FrameType, Encoded),
|
||||
?DBG("CONN <- ~p~n", [Record]),
|
||||
?DBG("CONN <- ~p", [Record]),
|
||||
socket_send(Socket, Frame).
|
||||
|
||||
send_heartbeat(#state{socket = Socket}) ->
|
||||
|
|
|
|||
|
|
@ -158,16 +158,16 @@ handle_event(info, {Tcp, _, Packet}, StateName, #state{buffer = Buffer} = State)
|
|||
|
||||
handle_event(info, {TcpError, _, Reason}, StateName, State)
|
||||
when TcpError == tcp_error orelse TcpError == ssl_error ->
|
||||
error_logger:warning_msg("AMQP 1.0 connection socket errored, connection state: '~s', reason: '~p'~n",
|
||||
[StateName, Reason]),
|
||||
logger:warning("AMQP 1.0 connection socket errored, connection state: '~s', reason: '~p'",
|
||||
[StateName, Reason]),
|
||||
State1 = State#state{socket = undefined,
|
||||
buffer = <<>>,
|
||||
frame_state = undefined},
|
||||
{stop, {error, Reason}, State1};
|
||||
handle_event(info, {TcpClosed, _}, StateName, State)
|
||||
when TcpClosed == tcp_closed orelse TcpClosed == ssl_closed ->
|
||||
error_logger:warning_msg("AMQP 1.0 connection socket was closed, connection state: '~s'~n",
|
||||
[StateName]),
|
||||
logger:warning("AMQP 1.0 connection socket was closed, connection state: '~s'",
|
||||
[StateName]),
|
||||
State1 = State#state{socket = undefined,
|
||||
buffer = <<>>,
|
||||
frame_state = undefined},
|
||||
|
|
@ -279,7 +279,7 @@ defer_heartbeat_timer(State) -> State.
|
|||
route_frame(Channel, FrameType, {Performative, Payload} = Frame, State0) ->
|
||||
{DestinationPid, State} = find_destination(Channel, FrameType, Performative,
|
||||
State0),
|
||||
?DBG("FRAME -> ~p ~p~n ~p~n", [Channel, DestinationPid, Performative]),
|
||||
?DBG("FRAME -> ~p ~p~n ~p", [Channel, DestinationPid, Performative]),
|
||||
case Payload of
|
||||
<<>> -> ok = gen_statem:cast(DestinationPid, Performative);
|
||||
_ -> ok = gen_statem:cast(DestinationPid, Frame)
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ mapped(cast, {#'v1_0.transfer'{handle = {uint, InHandle},
|
|||
ok = notify_link(Link, credit_exhausted),
|
||||
{next_state, mapped, State};
|
||||
{transfer_limit_exceeded, State} ->
|
||||
error_logger:info_msg("transfer_limit_exceeded for link ~p~n", [Link]),
|
||||
logger:warning("transfer_limit_exceeded for link ~p", [Link]),
|
||||
Link1 = detach_with_error_cond(Link, State,
|
||||
?V_1_0_LINK_ERROR_TRANSFER_LIMIT_EXCEEDED),
|
||||
{next_state, mapped, update_link(Link1, State)}
|
||||
|
|
@ -403,7 +403,7 @@ mapped(cast, #'v1_0.disposition'{role = true, settled = true, first = {uint, Fir
|
|||
|
||||
{next_state, mapped, State#state{unsettled = Unsettled}};
|
||||
mapped(cast, Frame, State) ->
|
||||
error_logger:warning_msg("Unhandled session frame ~p in state ~p~n",
|
||||
logger:warning("Unhandled session frame ~p in state ~p",
|
||||
[Frame, State]),
|
||||
{next_state, mapped, State};
|
||||
mapped({call, From},
|
||||
|
|
@ -490,7 +490,7 @@ mapped({call, From}, Msg, State) ->
|
|||
{keep_state, State1, [{reply, From, Reply}]};
|
||||
|
||||
mapped(_EvtType, Msg, _State) ->
|
||||
error_logger:info_msg("amqp10_session: unhandled msg in mapped state ~W",
|
||||
logger:warning("amqp10_session: unhandled msg in mapped state ~W",
|
||||
[Msg, 10]),
|
||||
keep_state_and_data.
|
||||
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ handle_info({bump_credit, Msg}, State) ->
|
|||
%% @private
|
||||
handle_info(timed_out_flushing_channel, State) ->
|
||||
?LOG_WARN("Channel (~p) closing: timed out flushing while "
|
||||
"connection closing~n", [self()]),
|
||||
"connection closing", [self()]),
|
||||
{stop, timed_out_flushing_channel, State};
|
||||
%% @private
|
||||
handle_info({'DOWN', _, process, ReturnHandler, shutdown},
|
||||
|
|
@ -520,7 +520,7 @@ handle_info({'DOWN', _, process, ReturnHandler, shutdown},
|
|||
handle_info({'DOWN', _, process, ReturnHandler, Reason},
|
||||
State = #state{return_handler = {ReturnHandler, _Ref}}) ->
|
||||
?LOG_WARN("Channel (~p): Unregistering return handler ~p because it died. "
|
||||
"Reason: ~p~n", [self(), ReturnHandler, Reason]),
|
||||
"Reason: ~p", [self(), ReturnHandler, Reason]),
|
||||
{noreply, State#state{return_handler = none}};
|
||||
%% @private
|
||||
handle_info({'DOWN', _, process, ConfirmHandler, shutdown},
|
||||
|
|
@ -529,7 +529,7 @@ handle_info({'DOWN', _, process, ConfirmHandler, shutdown},
|
|||
handle_info({'DOWN', _, process, ConfirmHandler, Reason},
|
||||
State = #state{confirm_handler = {ConfirmHandler, _Ref}}) ->
|
||||
?LOG_WARN("Channel (~p): Unregistering confirm handler ~p because it died. "
|
||||
"Reason: ~p~n", [self(), ConfirmHandler, Reason]),
|
||||
"Reason: ~p", [self(), ConfirmHandler, Reason]),
|
||||
{noreply, State#state{confirm_handler = none}};
|
||||
%% @private
|
||||
handle_info({'DOWN', _, process, FlowHandler, shutdown},
|
||||
|
|
@ -538,7 +538,7 @@ handle_info({'DOWN', _, process, FlowHandler, shutdown},
|
|||
handle_info({'DOWN', _, process, FlowHandler, Reason},
|
||||
State = #state{flow_handler = {FlowHandler, _Ref}}) ->
|
||||
?LOG_WARN("Channel (~p): Unregistering flow handler ~p because it died. "
|
||||
"Reason: ~p~n", [self(), FlowHandler, Reason]),
|
||||
"Reason: ~p", [self(), FlowHandler, Reason]),
|
||||
{noreply, State#state{flow_handler = none}};
|
||||
handle_info({'DOWN', _, process, QPid, _Reason}, State) ->
|
||||
rabbit_amqqueue_common:notify_sent_queue_down(QPid),
|
||||
|
|
@ -588,13 +588,13 @@ handle_method_to_server(Method, AmqpMsg, From, Sender, Flow,
|
|||
From, Sender, Flow, State1)};
|
||||
{ok, none, BlockReply} ->
|
||||
?LOG_WARN("Channel (~p): discarding method ~p in cast.~n"
|
||||
"Reason: ~p~n", [self(), Method, BlockReply]),
|
||||
"Reason: ~p", [self(), Method, BlockReply]),
|
||||
{noreply, State};
|
||||
{ok, _, BlockReply} ->
|
||||
{reply, BlockReply, State};
|
||||
{{_, InvalidMethodMessage}, none, _} ->
|
||||
?LOG_WARN("Channel (~p): ignoring cast of ~p method. " ++
|
||||
InvalidMethodMessage ++ "~n", [self(), Method]),
|
||||
InvalidMethodMessage ++ "", [self(), Method]),
|
||||
{noreply, State};
|
||||
{{InvalidMethodReply, _}, _, _} ->
|
||||
{reply, {error, InvalidMethodReply}, State}
|
||||
|
|
@ -695,7 +695,7 @@ safely_handle_method_from_server(Method, Content,
|
|||
_ -> false
|
||||
end,
|
||||
if Drop -> ?LOG_INFO("Channel (~p): dropping method ~p from "
|
||||
"server because channel is closing~n",
|
||||
"server because channel is closing",
|
||||
[self(), {Method, Content}]),
|
||||
{noreply, State};
|
||||
true ->
|
||||
|
|
@ -776,7 +776,7 @@ handle_method_from_server1(
|
|||
State = #state{return_handler = ReturnHandler}) ->
|
||||
case ReturnHandler of
|
||||
none -> ?LOG_WARN("Channel (~p): received {~p, ~p} but there is "
|
||||
"no return handler registered~n",
|
||||
"no return handler registered",
|
||||
[self(), BasicReturn, AmqpMsg]);
|
||||
{Pid, _Ref} -> Pid ! {BasicReturn, AmqpMsg}
|
||||
end,
|
||||
|
|
@ -791,7 +791,7 @@ handle_method_from_server1(#'basic.ack'{} = BasicAck, none,
|
|||
handle_method_from_server1(#'basic.nack'{} = BasicNack, none,
|
||||
#state{confirm_handler = none} = State) ->
|
||||
?LOG_WARN("Channel (~p): received ~p but there is no "
|
||||
"confirm handler registered~n", [self(), BasicNack]),
|
||||
"confirm handler registered", [self(), BasicNack]),
|
||||
{noreply, update_confirm_set(BasicNack, State)};
|
||||
handle_method_from_server1(#'basic.nack'{} = BasicNack, none,
|
||||
#state{confirm_handler = {CH, _Ref}} = State) ->
|
||||
|
|
@ -835,7 +835,7 @@ handle_connection_closing(CloseType, Reason,
|
|||
handle_channel_exit(Reason = #amqp_error{name = ErrorName, explanation = Expl},
|
||||
State = #state{connection = Connection, number = Number}) ->
|
||||
%% Sent by rabbit_channel for hard errors in the direct case
|
||||
?LOG_ERR("connection ~p, channel ~p - error:~n~p~n",
|
||||
?LOG_ERR("connection ~p, channel ~p - error:~n~p",
|
||||
[Connection, Number, Reason]),
|
||||
{true, Code, _} = ?PROTOCOL:lookup_amqp_exception(ErrorName),
|
||||
ReportedReason = {server_initiated_close, Code, Expl},
|
||||
|
|
@ -928,7 +928,7 @@ server_misbehaved(#amqp_error{} = AmqpError, State = #state{number = Number}) ->
|
|||
handle_shutdown({server_misbehaved, AmqpError}, State);
|
||||
{_, Close} ->
|
||||
?LOG_WARN("Channel (~p) flushing and closing due to soft "
|
||||
"error caused by the server ~p~n", [self(), AmqpError]),
|
||||
"error caused by the server ~p", [self(), AmqpError]),
|
||||
Self = self(),
|
||||
spawn(fun () -> call(Self, Close) end),
|
||||
{noreply, State}
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ internal_pass_frame(Number, Frame, State) ->
|
|||
case internal_lookup_npa(Number, State) of
|
||||
undefined ->
|
||||
?LOG_INFO("Dropping frame ~p for invalid or closed "
|
||||
"channel number ~p~n", [Frame, Number]),
|
||||
"channel number ~p", [Frame, Number]),
|
||||
State;
|
||||
{ChPid, AState} ->
|
||||
NewAState = process_channel_frame(Frame, Number, ChPid, AState),
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ handle_cast(channels_terminated, State) ->
|
|||
handle_cast({hard_error_in_channel, _Pid, Reason}, State) ->
|
||||
server_initiated_close(Reason, State);
|
||||
handle_cast({channel_internal_error, Pid, Reason}, State) ->
|
||||
?LOG_WARN("Connection (~p) closing: internal error in channel (~p): ~p~n",
|
||||
?LOG_WARN("Connection (~p) closing: internal error in channel (~p): ~p",
|
||||
[self(), Pid, Reason]),
|
||||
internal_error(Pid, Reason, State);
|
||||
handle_cast({server_misbehaved, AmqpError}, State) ->
|
||||
|
|
@ -218,12 +218,12 @@ handle_cast({register_blocked_handler, HandlerPid}, State) ->
|
|||
handle_info({'DOWN', _, process, BlockHandler, Reason},
|
||||
State = #state{block_handler = {BlockHandler, _Ref}}) ->
|
||||
?LOG_WARN("Connection (~p): Unregistering connection.{blocked,unblocked} handler ~p because it died. "
|
||||
"Reason: ~p~n", [self(), BlockHandler, Reason]),
|
||||
"Reason: ~p", [self(), BlockHandler, Reason]),
|
||||
{noreply, State#state{block_handler = none}};
|
||||
handle_info({'EXIT', BlockHandler, Reason},
|
||||
State = #state{block_handler = {BlockHandler, Ref}}) ->
|
||||
?LOG_WARN("Connection (~p): Unregistering connection.{blocked,unblocked} handler ~p because it died. "
|
||||
"Reason: ~p~n", [self(), BlockHandler, Reason]),
|
||||
"Reason: ~p", [self(), BlockHandler, Reason]),
|
||||
erlang:demonitor(Ref, [flush]),
|
||||
{noreply, State#state{block_handler = none}};
|
||||
%% propagate the exit to the module that will stop with a sensible reason logged
|
||||
|
|
@ -329,12 +329,12 @@ internal_error(Pid, Reason, State) ->
|
|||
|
||||
server_initiated_close(Close, State) ->
|
||||
?LOG_WARN("Connection (~p) closing: received hard error ~p "
|
||||
"from server~n", [self(), Close]),
|
||||
"from server", [self(), Close]),
|
||||
set_closing_state(abrupt, #closing{reason = server_initiated_close,
|
||||
close = Close}, State).
|
||||
|
||||
server_misbehaved_close(AmqpError, State) ->
|
||||
?LOG_WARN("Connection (~p) closing: server misbehaved: ~p~n",
|
||||
?LOG_WARN("Connection (~p) closing: server misbehaved: ~p",
|
||||
[self(), AmqpError]),
|
||||
{0, Close} = rabbit_binary_generator:map_exception(0, AmqpError, ?PROTOCOL),
|
||||
set_closing_state(abrupt, #closing{reason = server_misbehaved,
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ maybe_add_verify(Options) ->
|
|||
% NB: user has explicitly set 'verify'
|
||||
Options;
|
||||
_ ->
|
||||
?LOG_WARN("Connection (~p): Certificate chain verification is not enabled for this TLS connection. "
|
||||
"Please see https://rabbitmq.com/ssl.html for more information.~n", [self()]),
|
||||
?LOG_WARN("Connection (~p): certificate chain verification is not enabled for this TLS connection. "
|
||||
"Please see https://rabbitmq.com/ssl.html for more information.", [self()]),
|
||||
Options
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -131,14 +131,14 @@ endef
|
|||
APPS_DIR := $(CURDIR)/apps
|
||||
|
||||
LOCAL_DEPS = sasl rabbitmq_prelaunch os_mon inets compiler public_key crypto ssl syntax_tools xmerl
|
||||
BUILD_DEPS = rabbitmq_cli syslog
|
||||
DEPS = cuttlefish ranch lager rabbit_common ra sysmon_handler stdout_formatter recon observer_cli osiris amqp10_common
|
||||
BUILD_DEPS = rabbitmq_cli
|
||||
DEPS = cuttlefish ranch rabbit_common ra sysmon_handler stdout_formatter recon observer_cli osiris amqp10_common syslog
|
||||
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client meck proper
|
||||
|
||||
PLT_APPS += mnesia
|
||||
|
||||
dep_cuttlefish = hex 2.7.0
|
||||
dep_syslog = git https://github.com/schlagert/syslog 3.4.5
|
||||
dep_cuttlefish = git https://github.com/Kyorai/cuttlefish master
|
||||
dep_syslog = git https://github.com/schlagert/syslog 4.0.0
|
||||
dep_osiris = git https://github.com/rabbitmq/osiris master
|
||||
|
||||
define usage_xml_to_erl
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
*.coverdata
|
||||
/ebin/
|
||||
/.erlang.mk/
|
||||
/logs/
|
||||
/rabbitmq_prelaunch.d
|
||||
/xrefr
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ PROJECT_DESCRIPTION = RabbitMQ prelaunch setup
|
|||
PROJECT_VERSION = 1.0.0
|
||||
PROJECT_MOD = rabbit_prelaunch_app
|
||||
|
||||
DEPS = rabbit_common lager
|
||||
DEPS = rabbit_common jsx
|
||||
|
||||
DEP_PLUGINS = rabbit_common/mk/rabbitmq-build.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
-module(rabbit_boot_state).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([get/0,
|
||||
set/1,
|
||||
wait_for/2,
|
||||
|
|
@ -28,7 +31,8 @@ get() ->
|
|||
|
||||
-spec set(boot_state()) -> ok.
|
||||
set(BootState) ->
|
||||
rabbit_log_prelaunch:debug("Change boot state to `~s`", [BootState]),
|
||||
?LOG_DEBUG("Change boot state to `~s`", [BootState],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
?assert(is_valid(BootState)),
|
||||
case BootState of
|
||||
stopped -> persistent_term:erase(?PT_KEY_BOOT_STATE);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([start_link/0]).
|
||||
|
||||
-export([init/1,
|
||||
|
|
@ -65,20 +69,23 @@ code_change(_OldVsn, State, _Extra) ->
|
|||
|
||||
notify_boot_state(ready = BootState,
|
||||
#state{mechanism = legacy, sd_notify_module = SDNotify}) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "notifying of state `~s` (via native module)",
|
||||
[BootState]),
|
||||
[BootState],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
sd_notify_legacy(SDNotify);
|
||||
notify_boot_state(ready = BootState,
|
||||
#state{mechanism = socat, socket = Socket}) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "notifying of state `~s` (via socat(1))",
|
||||
[BootState]),
|
||||
[BootState],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
sd_notify_socat(Socket);
|
||||
notify_boot_state(BootState, _) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "ignoring state `~s`",
|
||||
[BootState]),
|
||||
[BootState],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok.
|
||||
|
||||
sd_notify_message() ->
|
||||
|
|
@ -99,9 +106,10 @@ sd_notify_legacy(SDNotify) ->
|
|||
sd_notify_socat(Socket) ->
|
||||
case sd_current_unit() of
|
||||
{ok, Unit} ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_PREFIX "systemd unit for activation check: \"~s\"~n",
|
||||
[Unit]),
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "systemd unit for activation check: \"~s\"",
|
||||
[Unit],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
sd_notify_socat(Socket, Unit);
|
||||
_ ->
|
||||
ok
|
||||
|
|
@ -116,9 +124,10 @@ sd_notify_socat(Socket, Unit) ->
|
|||
Result
|
||||
catch
|
||||
Class:Reason ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_PREFIX "Failed to start socat(1): ~p:~p~n",
|
||||
[Class, Reason]),
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "Failed to start socat(1): ~p:~p",
|
||||
[Class, Reason],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
false
|
||||
end.
|
||||
|
||||
|
|
@ -147,8 +156,10 @@ sd_open_port(Socket) ->
|
|||
sd_wait_activation(Port, Unit) ->
|
||||
case os:find_executable("systemctl") of
|
||||
false ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_PREFIX "systemctl(1) unavailable, falling back to sleep~n"),
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "systemctl(1) unavailable, falling back to sleep",
|
||||
[],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
timer:sleep(5000),
|
||||
ok;
|
||||
_ ->
|
||||
|
|
@ -156,8 +167,10 @@ sd_wait_activation(Port, Unit) ->
|
|||
end.
|
||||
|
||||
sd_wait_activation(_, _, 0) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_PREFIX "service still in 'activating' state, bailing out~n"),
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "service still in 'activating' state, bailing out",
|
||||
[],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
sd_wait_activation(Port, Unit, AttemptsLeft) ->
|
||||
Ret = os:cmd("systemctl show --property=ActiveState -- '" ++ Unit ++ "'"),
|
||||
|
|
@ -168,7 +181,8 @@ sd_wait_activation(Port, Unit, AttemptsLeft) ->
|
|||
"ActiveState=" ++ _ ->
|
||||
ok;
|
||||
_ = Err ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_PREFIX "unexpected status from systemd: ~p~n", [Err]),
|
||||
?LOG_DEBUG(
|
||||
?LOG_PREFIX "unexpected status from systemd: ~p", [Err],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_logger_json_fmt).
|
||||
|
||||
-export([format/2]).
|
||||
|
||||
format(
|
||||
#{msg := Msg,
|
||||
level := Level,
|
||||
meta := #{time := Timestamp} = Meta},
|
||||
Config) ->
|
||||
FormattedTimestamp = unicode:characters_to_binary(
|
||||
format_time(Timestamp, Config)),
|
||||
FormattedMsg = unicode:characters_to_binary(
|
||||
format_msg(Msg, Meta, Config)),
|
||||
FormattedMeta = format_meta(Meta, Config),
|
||||
Json = jsx:encode(
|
||||
[{time, FormattedTimestamp},
|
||||
{level, Level},
|
||||
{msg, FormattedMsg},
|
||||
{meta, FormattedMeta}]),
|
||||
[Json, $\n].
|
||||
|
||||
format_time(Timestamp, _) ->
|
||||
Options = [{unit, microsecond}],
|
||||
calendar:system_time_to_rfc3339(Timestamp, Options).
|
||||
|
||||
format_msg({string, Chardata}, Meta, Config) ->
|
||||
format_msg({"~ts", [Chardata]}, Meta, Config);
|
||||
format_msg({report, Report}, Meta, Config) ->
|
||||
FormattedReport = format_report(Report, Meta, Config),
|
||||
format_msg(FormattedReport, Meta, Config);
|
||||
format_msg({Format, Args}, _, _) ->
|
||||
io_lib:format(Format, Args).
|
||||
|
||||
format_report(
|
||||
#{label := {application_controller, _}} = Report, Meta, Config) ->
|
||||
format_application_progress(Report, Meta, Config);
|
||||
format_report(
|
||||
#{label := {supervisor, progress}} = Report, Meta, Config) ->
|
||||
format_supervisor_progress(Report, Meta, Config);
|
||||
format_report(
|
||||
Report, #{report_cb := Cb} = Meta, Config) ->
|
||||
try
|
||||
case erlang:fun_info(Cb, arity) of
|
||||
{arity, 1} -> Cb(Report);
|
||||
{arity, 2} -> {"~ts", [Cb(Report, #{})]}
|
||||
end
|
||||
catch
|
||||
_:_:_ ->
|
||||
format_report(Report, maps:remove(report_cb, Meta), Config)
|
||||
end;
|
||||
format_report(Report, _, _) ->
|
||||
logger:format_report(Report).
|
||||
|
||||
format_application_progress(#{label := {_, progress},
|
||||
report := InternalReport}, _, _) ->
|
||||
Application = proplists:get_value(application, InternalReport),
|
||||
StartedAt = proplists:get_value(started_at, InternalReport),
|
||||
{"Application ~w started on ~0p",
|
||||
[Application, StartedAt]};
|
||||
format_application_progress(#{label := {_, exit},
|
||||
report := InternalReport}, _, _) ->
|
||||
Application = proplists:get_value(application, InternalReport),
|
||||
Exited = proplists:get_value(exited, InternalReport),
|
||||
{"Application ~w exited with reason: ~0p",
|
||||
[Application, Exited]}.
|
||||
|
||||
format_supervisor_progress(#{report := InternalReport}, _, _) ->
|
||||
Supervisor = proplists:get_value(supervisor, InternalReport),
|
||||
Started = proplists:get_value(started, InternalReport),
|
||||
Id = proplists:get_value(id, Started),
|
||||
Pid = proplists:get_value(pid, Started),
|
||||
Mfa = proplists:get_value(mfargs, Started),
|
||||
{"Supervisor ~w: child ~w started (~w): ~0p",
|
||||
[Supervisor, Id, Pid, Mfa]}.
|
||||
|
||||
format_meta(Meta, _) ->
|
||||
maps:fold(
|
||||
fun
|
||||
(time, _, Acc) ->
|
||||
Acc;
|
||||
(domain = Key, Components, Acc) ->
|
||||
Term = unicode:characters_to_binary(
|
||||
string:join(
|
||||
[atom_to_list(Cmp) || Cmp <- Components],
|
||||
".")),
|
||||
Acc#{Key => Term};
|
||||
(Key, Value, Acc) ->
|
||||
case convert_to_types_accepted_by_jsx(Value) of
|
||||
false -> Acc;
|
||||
Term -> Acc#{Key => Term}
|
||||
end
|
||||
end, #{}, Meta).
|
||||
|
||||
convert_to_types_accepted_by_jsx(Term) when is_map(Term) ->
|
||||
maps:map(
|
||||
fun(_, Value) -> convert_to_types_accepted_by_jsx(Value) end,
|
||||
Term);
|
||||
convert_to_types_accepted_by_jsx(Term) when is_list(Term) ->
|
||||
case io_lib:deep_char_list(Term) of
|
||||
true ->
|
||||
unicode:characters_to_binary(Term);
|
||||
false ->
|
||||
[convert_to_types_accepted_by_jsx(E) || E <- Term]
|
||||
end;
|
||||
convert_to_types_accepted_by_jsx(Term) when is_tuple(Term) ->
|
||||
convert_to_types_accepted_by_jsx(erlang:tuple_to_list(Term));
|
||||
convert_to_types_accepted_by_jsx(Term) when is_function(Term) ->
|
||||
String = erlang:fun_to_list(Term),
|
||||
unicode:characters_to_binary(String);
|
||||
convert_to_types_accepted_by_jsx(Term) when is_pid(Term) ->
|
||||
String = erlang:pid_to_list(Term),
|
||||
unicode:characters_to_binary(String);
|
||||
convert_to_types_accepted_by_jsx(Term) when is_port(Term) ->
|
||||
String = erlang:port_to_list(Term),
|
||||
unicode:characters_to_binary(String);
|
||||
convert_to_types_accepted_by_jsx(Term) when is_reference(Term) ->
|
||||
String = erlang:ref_to_list(Term),
|
||||
unicode:characters_to_binary(String);
|
||||
convert_to_types_accepted_by_jsx(Term) ->
|
||||
Term.
|
||||
|
|
@ -0,0 +1,841 @@
|
|||
%%
|
||||
%% %CopyrightBegin%
|
||||
%%
|
||||
%% Copyright Ericsson AB 2017-2020. All Rights Reserved.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%
|
||||
%% %CopyrightEnd%
|
||||
%%
|
||||
-module(rabbit_logger_std_h).
|
||||
|
||||
%-include("logger.hrl").
|
||||
%-include("logger_internal.hrl").
|
||||
%-include("logger_h_common.hrl").
|
||||
-ifdef(TEST).
|
||||
-define(io_put_chars(DEVICE, DATA), begin
|
||||
%% We log to Common Test log as well.
|
||||
%% This is the file we use to check
|
||||
%% the message made it to
|
||||
%% stdout/stderr.
|
||||
ct:log("~ts", [DATA]),
|
||||
io:put_chars(DEVICE, DATA)
|
||||
end).
|
||||
-else.
|
||||
-define(io_put_chars(DEVICE, DATA), io:put_chars(DEVICE, DATA)).
|
||||
-endif.
|
||||
-define(file_write(DEVICE, DATA), file:write(DEVICE, DATA)).
|
||||
-define(file_datasync(DEVICE), file:datasync(DEVICE)).
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
%% API
|
||||
-export([filesync/1]).
|
||||
-export([is_date_based_rotation_needed/3]).
|
||||
|
||||
%% logger_h_common callbacks
|
||||
-export([init/2, check_config/4, config_changed/3, reset_state/2,
|
||||
filesync/3, write/4, handle_info/3, terminate/3]).
|
||||
|
||||
%% logger callbacks
|
||||
-export([log/2, adding_handler/1, removing_handler/1, changing_config/3,
|
||||
filter_config/1]).
|
||||
|
||||
-define(DEFAULT_CALL_TIMEOUT, 5000).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%%
|
||||
-spec filesync(Name) -> ok | {error,Reason} when
|
||||
Name :: atom(),
|
||||
Reason :: handler_busy | {badarg,term()}.
|
||||
|
||||
filesync(Name) ->
|
||||
logger_h_common:filesync(?MODULE,Name).
|
||||
|
||||
%%%===================================================================
|
||||
%%% logger callbacks - just forward to logger_h_common
|
||||
%%%===================================================================
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% Handler being added
|
||||
-spec adding_handler(Config) -> {ok,Config} | {error,Reason} when
|
||||
Config :: logger:handler_config(),
|
||||
Reason :: term().
|
||||
|
||||
adding_handler(Config) ->
|
||||
logger_h_common:adding_handler(Config).
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% Updating handler config
|
||||
-spec changing_config(SetOrUpdate, OldConfig, NewConfig) ->
|
||||
{ok,Config} | {error,Reason} when
|
||||
SetOrUpdate :: set | update,
|
||||
OldConfig :: logger:handler_config(),
|
||||
NewConfig :: logger:handler_config(),
|
||||
Config :: logger:handler_config(),
|
||||
Reason :: term().
|
||||
|
||||
changing_config(SetOrUpdate, OldConfig, NewConfig) ->
|
||||
logger_h_common:changing_config(SetOrUpdate, OldConfig, NewConfig).
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% Handler being removed
|
||||
-spec removing_handler(Config) -> ok when
|
||||
Config :: logger:handler_config().
|
||||
|
||||
removing_handler(Config) ->
|
||||
logger_h_common:removing_handler(Config).
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% Log a string or report
|
||||
-spec log(LogEvent, Config) -> ok when
|
||||
LogEvent :: logger:log_event(),
|
||||
Config :: logger:handler_config().
|
||||
|
||||
log(LogEvent, Config) ->
|
||||
logger_h_common:log(LogEvent, Config).
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% Remove internal fields from configuration
|
||||
-spec filter_config(Config) -> Config when
|
||||
Config :: logger:handler_config().
|
||||
|
||||
filter_config(Config) ->
|
||||
logger_h_common:filter_config(Config).
|
||||
|
||||
%%%===================================================================
|
||||
%%% logger_h_common callbacks
|
||||
%%%===================================================================
|
||||
init(Name, Config) ->
|
||||
MyConfig = maps:with([type,file,modes,file_check,max_no_bytes,
|
||||
rotate_on_date,max_no_files,compress_on_rotate],
|
||||
Config),
|
||||
case file_ctrl_start(Name, MyConfig) of
|
||||
{ok,FileCtrlPid} ->
|
||||
{ok,MyConfig#{file_ctrl_pid=>FileCtrlPid}};
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
check_config(Name,set,undefined,NewHConfig) ->
|
||||
check_h_config(merge_default_config(Name,normalize_config(NewHConfig)));
|
||||
check_config(Name,SetOrUpdate,OldHConfig,NewHConfig0) ->
|
||||
WriteOnce = maps:with([type,file,modes],OldHConfig),
|
||||
Default =
|
||||
case SetOrUpdate of
|
||||
set ->
|
||||
%% Do not reset write-once fields to defaults
|
||||
merge_default_config(Name,WriteOnce);
|
||||
update ->
|
||||
OldHConfig
|
||||
end,
|
||||
|
||||
NewHConfig = maps:merge(Default, normalize_config(NewHConfig0)),
|
||||
|
||||
%% Fail if write-once fields are changed
|
||||
case maps:with([type,file,modes],NewHConfig) of
|
||||
WriteOnce ->
|
||||
check_h_config(NewHConfig);
|
||||
Other ->
|
||||
{error,{illegal_config_change,?MODULE,WriteOnce,Other}}
|
||||
end.
|
||||
|
||||
check_h_config(HConfig) ->
|
||||
case check_h_config(maps:get(type,HConfig),maps:to_list(HConfig)) of
|
||||
ok ->
|
||||
{ok,fix_file_opts(HConfig)};
|
||||
{error,{Key,Value}} ->
|
||||
{error,{invalid_config,?MODULE,#{Key=>Value}}}
|
||||
end.
|
||||
|
||||
check_h_config(Type,[{type,Type} | Config]) when Type =:= standard_io;
|
||||
Type =:= standard_error;
|
||||
Type =:= file ->
|
||||
check_h_config(Type,Config);
|
||||
check_h_config({device,Device},[{type,{device,Device}} | Config]) ->
|
||||
check_h_config({device,Device},Config);
|
||||
check_h_config(file,[{file,File} | Config]) when is_list(File) ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(file,[{modes,Modes} | Config]) when is_list(Modes) ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(file,[{max_no_bytes,Size} | Config])
|
||||
when (is_integer(Size) andalso Size>0) orelse Size=:=infinity ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(file,[{rotate_on_date,DateSpec}=Param | Config])
|
||||
when is_list(DateSpec) orelse DateSpec=:=false ->
|
||||
case parse_date_spec(DateSpec) of
|
||||
error -> {error,Param};
|
||||
_ -> check_h_config(file,Config)
|
||||
end;
|
||||
check_h_config(file,[{max_no_files,Num} | Config]) when is_integer(Num), Num>=0 ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(file,[{compress_on_rotate,Bool} | Config]) when is_boolean(Bool) ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(file,[{file_check,FileCheck} | Config])
|
||||
when is_integer(FileCheck), FileCheck>=0 ->
|
||||
check_h_config(file,Config);
|
||||
check_h_config(_Type,[Other | _]) ->
|
||||
{error,Other};
|
||||
check_h_config(_Type,[]) ->
|
||||
ok.
|
||||
|
||||
normalize_config(#{type:={file,File}}=HConfig) ->
|
||||
normalize_config(HConfig#{type=>file,file=>File});
|
||||
normalize_config(#{type:={file,File,Modes}}=HConfig) ->
|
||||
normalize_config(HConfig#{type=>file,file=>File,modes=>Modes});
|
||||
normalize_config(#{file:=File}=HConfig) ->
|
||||
HConfig#{file=>filename:absname(File)};
|
||||
normalize_config(HConfig) ->
|
||||
HConfig.
|
||||
|
||||
merge_default_config(Name,#{type:=Type}=HConfig) ->
|
||||
merge_default_config(Name,Type,HConfig);
|
||||
merge_default_config(Name,#{file:=_}=HConfig) ->
|
||||
merge_default_config(Name,file,HConfig);
|
||||
merge_default_config(Name,HConfig) ->
|
||||
merge_default_config(Name,standard_io,HConfig).
|
||||
|
||||
merge_default_config(Name,Type,HConfig) ->
|
||||
maps:merge(get_default_config(Name,Type),HConfig).
|
||||
|
||||
get_default_config(Name,file) ->
|
||||
#{type => file,
|
||||
file => filename:absname(atom_to_list(Name)),
|
||||
modes => [raw,append],
|
||||
file_check => 0,
|
||||
max_no_bytes => infinity,
|
||||
rotate_on_date => false,
|
||||
max_no_files => 0,
|
||||
compress_on_rotate => false};
|
||||
get_default_config(_Name,Type) ->
|
||||
#{type => Type}.
|
||||
|
||||
fix_file_opts(#{modes:=Modes}=HConfig) ->
|
||||
HConfig#{modes=>fix_modes(Modes)};
|
||||
fix_file_opts(HConfig) ->
|
||||
HConfig#{filesync_repeat_interval=>no_repeat}.
|
||||
|
||||
fix_modes(Modes) ->
|
||||
%% Ensure write|append|exclusive
|
||||
Modes1 =
|
||||
case [M || M <- Modes,
|
||||
lists:member(M,[write,append,exclusive])] of
|
||||
[] -> [append|Modes];
|
||||
_ -> Modes
|
||||
end,
|
||||
%% Ensure raw
|
||||
Modes2 =
|
||||
case lists:member(raw,Modes) of
|
||||
false -> [raw|Modes1];
|
||||
true -> Modes1
|
||||
end,
|
||||
%% Ensure delayed_write
|
||||
case lists:partition(fun(delayed_write) -> true;
|
||||
({delayed_write,_,_}) -> true;
|
||||
(_) -> false
|
||||
end, Modes2) of
|
||||
{[],_} ->
|
||||
[delayed_write|Modes2];
|
||||
_ ->
|
||||
Modes2
|
||||
end.
|
||||
|
||||
config_changed(_Name,
|
||||
#{file_check:=FileCheck,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress},
|
||||
#{file_check:=FileCheck,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress}=State) ->
|
||||
State;
|
||||
config_changed(_Name,
|
||||
#{file_check:=FileCheck,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress},
|
||||
#{file_ctrl_pid := FileCtrlPid} = State) ->
|
||||
FileCtrlPid ! {update_config,#{file_check=>FileCheck,
|
||||
max_no_bytes=>Size,
|
||||
rotate_on_date=>DateSpec,
|
||||
max_no_files=>Count,
|
||||
compress_on_rotate=>Compress}},
|
||||
State#{file_check:=FileCheck,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress};
|
||||
config_changed(_Name,_NewHConfig,State) ->
|
||||
State.
|
||||
|
||||
filesync(_Name, SyncAsync, #{file_ctrl_pid := FileCtrlPid} = State) ->
|
||||
Result = file_ctrl_filesync(SyncAsync, FileCtrlPid),
|
||||
{Result,State}.
|
||||
|
||||
write(_Name, SyncAsync, Bin, #{file_ctrl_pid:=FileCtrlPid} = State) ->
|
||||
Result = file_write(SyncAsync, FileCtrlPid, Bin),
|
||||
{Result,State}.
|
||||
|
||||
reset_state(_Name, State) ->
|
||||
State.
|
||||
|
||||
handle_info(_Name, {'EXIT',Pid,Why}, #{file_ctrl_pid := Pid}=State) ->
|
||||
%% file_ctrl_pid died, file error, terminate handler
|
||||
exit({error,{write_failed,maps:with([type,file,modes],State),Why}});
|
||||
handle_info(_, _, State) ->
|
||||
State.
|
||||
|
||||
terminate(_Name, _Reason, #{file_ctrl_pid:=FWPid}) ->
|
||||
case is_process_alive(FWPid) of
|
||||
true ->
|
||||
unlink(FWPid),
|
||||
_ = file_ctrl_stop(FWPid),
|
||||
MRef = erlang:monitor(process, FWPid),
|
||||
receive
|
||||
{'DOWN',MRef,_,_,_} ->
|
||||
ok
|
||||
after
|
||||
?DEFAULT_CALL_TIMEOUT ->
|
||||
exit(FWPid, kill),
|
||||
ok
|
||||
end;
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%%
|
||||
open_log_file(HandlerName,#{type:=file,
|
||||
file:=FileName,
|
||||
modes:=Modes,
|
||||
file_check:=FileCheck}) ->
|
||||
try
|
||||
case filelib:ensure_dir(FileName) of
|
||||
ok ->
|
||||
case file:open(FileName, Modes) of
|
||||
{ok, Fd} ->
|
||||
{ok,#file_info{inode=INode}} =
|
||||
file:read_file_info(FileName,[raw]),
|
||||
UpdateModes = [append | Modes--[write,append,exclusive]],
|
||||
{ok,#{handler_name=>HandlerName,
|
||||
file_name=>FileName,
|
||||
modes=>UpdateModes,
|
||||
file_check=>FileCheck,
|
||||
fd=>Fd,
|
||||
inode=>INode,
|
||||
last_check=>timestamp(),
|
||||
synced=>false,
|
||||
write_res=>ok,
|
||||
sync_res=>ok}};
|
||||
Error ->
|
||||
Error
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end
|
||||
catch
|
||||
_:Reason -> {error,Reason}
|
||||
end.
|
||||
|
||||
close_log_file(#{fd:=Fd}) ->
|
||||
_ = file:datasync(Fd), %% file:datasync may return error as it will flush the delayed_write buffer
|
||||
_ = file:close(Fd),
|
||||
ok;
|
||||
close_log_file(_) ->
|
||||
ok.
|
||||
|
||||
%% A special close that closes the FD properly when the delayed write close failed
|
||||
delayed_write_close(#{fd:=Fd}) ->
|
||||
case file:close(Fd) of
|
||||
%% We got an error while closing, could be a delayed write failing
|
||||
%% So we close again in order to make sure the file is closed.
|
||||
{error, _} ->
|
||||
file:close(Fd);
|
||||
Res ->
|
||||
Res
|
||||
end.
|
||||
|
||||
%%%-----------------------------------------------------------------
|
||||
%%% File control process
|
||||
|
||||
file_ctrl_start(HandlerName, HConfig) ->
|
||||
Starter = self(),
|
||||
FileCtrlPid =
|
||||
spawn_link(fun() ->
|
||||
file_ctrl_init(HandlerName, HConfig, Starter)
|
||||
end),
|
||||
receive
|
||||
{FileCtrlPid,ok} ->
|
||||
{ok,FileCtrlPid};
|
||||
{FileCtrlPid,Error} ->
|
||||
Error
|
||||
after
|
||||
?DEFAULT_CALL_TIMEOUT ->
|
||||
{error,file_ctrl_process_not_started}
|
||||
end.
|
||||
|
||||
file_ctrl_stop(Pid) ->
|
||||
Pid ! stop.
|
||||
|
||||
file_write(async, Pid, Bin) ->
|
||||
Pid ! {log,Bin},
|
||||
ok;
|
||||
file_write(sync, Pid, Bin) ->
|
||||
file_ctrl_call(Pid, {log,Bin}).
|
||||
|
||||
file_ctrl_filesync(async, Pid) ->
|
||||
Pid ! filesync,
|
||||
ok;
|
||||
file_ctrl_filesync(sync, Pid) ->
|
||||
file_ctrl_call(Pid, filesync).
|
||||
|
||||
file_ctrl_call(Pid, Msg) ->
|
||||
MRef = monitor(process, Pid),
|
||||
Pid ! {Msg,{self(),MRef}},
|
||||
receive
|
||||
{MRef,Result} ->
|
||||
demonitor(MRef, [flush]),
|
||||
Result;
|
||||
{'DOWN',MRef,_Type,_Object,Reason} ->
|
||||
{error,Reason}
|
||||
after
|
||||
?DEFAULT_CALL_TIMEOUT ->
|
||||
%% If this timeout triggers we will get a stray
|
||||
%% reply message in our mailbox eventually.
|
||||
%% That does not really matter though as it will
|
||||
%% end up in this module's handle_info and be ignored
|
||||
demonitor(MRef, [flush]),
|
||||
{error,{no_response,Pid}}
|
||||
end.
|
||||
|
||||
file_ctrl_init(HandlerName,
|
||||
#{type:=file,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress,
|
||||
file:=FileName} = HConfig,
|
||||
Starter) ->
|
||||
process_flag(message_queue_data, off_heap),
|
||||
case open_log_file(HandlerName,HConfig) of
|
||||
{ok,State} ->
|
||||
Starter ! {self(),ok},
|
||||
%% Do the initial rotate (if any) after we ack the starting
|
||||
%% process as otherwise startup of the system will be
|
||||
%% delayed/crash
|
||||
case parse_date_spec(DateSpec) of
|
||||
error ->
|
||||
Starter ! {self(),{error,{invalid_date_spec,DateSpec}}};
|
||||
ParsedDS ->
|
||||
RotState = update_rotation({Size,ParsedDS,Count,Compress},State),
|
||||
file_ctrl_loop(RotState)
|
||||
end;
|
||||
{error,Reason} ->
|
||||
Starter ! {self(),{error,{open_failed,FileName,Reason}}}
|
||||
end;
|
||||
file_ctrl_init(HandlerName, #{type:={device,Dev}}, Starter) ->
|
||||
Starter ! {self(),ok},
|
||||
file_ctrl_loop(#{handler_name=>HandlerName,dev=>Dev});
|
||||
file_ctrl_init(HandlerName, #{type:=StdDev}, Starter) ->
|
||||
Starter ! {self(),ok},
|
||||
file_ctrl_loop(#{handler_name=>HandlerName,dev=>StdDev}).
|
||||
|
||||
file_ctrl_loop(State) ->
|
||||
receive
|
||||
%% asynchronous event
|
||||
{log,Bin} ->
|
||||
State1 = write_to_dev(Bin,State),
|
||||
file_ctrl_loop(State1);
|
||||
|
||||
%% synchronous event
|
||||
{{log,Bin},{From,MRef}} ->
|
||||
State1 = ensure_file(State),
|
||||
State2 = write_to_dev(Bin,State1),
|
||||
From ! {MRef,ok},
|
||||
file_ctrl_loop(State2);
|
||||
|
||||
filesync ->
|
||||
State1 = sync_dev(State),
|
||||
file_ctrl_loop(State1);
|
||||
|
||||
{filesync,{From,MRef}} ->
|
||||
State1 = ensure_file(State),
|
||||
State2 = sync_dev(State1),
|
||||
From ! {MRef,ok},
|
||||
file_ctrl_loop(State2);
|
||||
|
||||
{update_config,#{file_check:=FileCheck,
|
||||
max_no_bytes:=Size,
|
||||
rotate_on_date:=DateSpec,
|
||||
max_no_files:=Count,
|
||||
compress_on_rotate:=Compress}} ->
|
||||
case parse_date_spec(DateSpec) of
|
||||
error ->
|
||||
%% FIXME: Report parsing error?
|
||||
file_ctrl_loop(State#{file_check=>FileCheck});
|
||||
ParsedDS ->
|
||||
State1 = update_rotation({Size,ParsedDS,Count,Compress},State),
|
||||
file_ctrl_loop(State1#{file_check=>FileCheck})
|
||||
end;
|
||||
|
||||
stop ->
|
||||
close_log_file(State),
|
||||
stopped
|
||||
end.
|
||||
|
||||
maybe_ensure_file(#{file_check:=0}=State) ->
|
||||
ensure_file(State);
|
||||
maybe_ensure_file(#{last_check:=T0,file_check:=CheckInt}=State)
|
||||
when is_integer(CheckInt) ->
|
||||
T = timestamp(),
|
||||
if T-T0 > CheckInt -> ensure_file(State);
|
||||
true -> State
|
||||
end;
|
||||
maybe_ensure_file(State) ->
|
||||
State.
|
||||
|
||||
%% In order to play well with tools like logrotate, we need to be able
|
||||
%% to re-create the file if it has disappeared (e.g. if rotated by
|
||||
%% logrotate)
|
||||
ensure_file(#{inode:=INode0,file_name:=FileName,modes:=Modes}=State) ->
|
||||
case file:read_file_info(FileName,[raw]) of
|
||||
{ok,#file_info{inode=INode0}} ->
|
||||
State#{last_check=>timestamp()};
|
||||
_ ->
|
||||
close_log_file(State),
|
||||
case file:open(FileName,Modes) of
|
||||
{ok,Fd} ->
|
||||
{ok,#file_info{inode=INode}} =
|
||||
file:read_file_info(FileName,[raw]),
|
||||
State#{fd=>Fd,inode=>INode,
|
||||
last_check=>timestamp(),
|
||||
synced=>true,sync_res=>ok};
|
||||
Error ->
|
||||
exit({could_not_reopen_file,Error})
|
||||
end
|
||||
end;
|
||||
ensure_file(State) ->
|
||||
State.
|
||||
|
||||
write_to_dev(Bin,#{dev:=DevName}=State) ->
|
||||
?io_put_chars(DevName, Bin),
|
||||
State;
|
||||
write_to_dev(Bin, State) ->
|
||||
State1 = #{fd:=Fd} = maybe_ensure_file(State),
|
||||
Result = ?file_write(Fd, Bin),
|
||||
State2 = maybe_rotate_file(Bin,State1),
|
||||
maybe_notify_error(write,Result,State2),
|
||||
State2#{synced=>false,write_res=>Result}.
|
||||
|
||||
sync_dev(#{synced:=false}=State) ->
|
||||
State1 = #{fd:=Fd} = maybe_ensure_file(State),
|
||||
Result = ?file_datasync(Fd),
|
||||
maybe_notify_error(filesync,Result,State1),
|
||||
State1#{synced=>true,sync_res=>Result};
|
||||
sync_dev(State) ->
|
||||
State.
|
||||
|
||||
update_rotation({infinity,false,_,_},State) ->
|
||||
maybe_remove_archives(0,State),
|
||||
maps:remove(rotation,State);
|
||||
update_rotation({Size,DateSpec,Count,Compress},#{file_name:=FileName}=State) ->
|
||||
maybe_remove_archives(Count,State),
|
||||
{ok,#file_info{size=CurrSize}} = file:read_file_info(FileName,[raw]),
|
||||
State1 = State#{rotation=>#{size=>Size,
|
||||
on_date=>DateSpec,
|
||||
count=>Count,
|
||||
compress=>Compress,
|
||||
curr_size=>CurrSize}},
|
||||
maybe_update_compress(0,State1),
|
||||
maybe_rotate_file(0,State1).
|
||||
|
||||
parse_date_spec(false) ->
|
||||
false;
|
||||
parse_date_spec("") ->
|
||||
false;
|
||||
parse_date_spec([$$,$D | DateSpec]) ->
|
||||
io:format(standard_error, "parse_date_spec: ~p (hour)~n", [DateSpec]),
|
||||
parse_hour(DateSpec, #{every=>day,
|
||||
hour=>0});
|
||||
parse_date_spec([$$,$W | DateSpec]) ->
|
||||
io:format(standard_error, "parse_date_spec: ~p (week)~n", [DateSpec]),
|
||||
parse_day_of_week(DateSpec, #{every=>week,
|
||||
hour=>0});
|
||||
parse_date_spec([$$,$M | DateSpec]) ->
|
||||
io:format(standard_error, "parse_date_spec: ~p (month)~n", [DateSpec]),
|
||||
parse_day_of_month(DateSpec, #{every=>month,
|
||||
hour=>0});
|
||||
parse_date_spec(DateSpec) ->
|
||||
io:format(standard_error, "parse_date_spec: ~p (error)~n", [DateSpec]),
|
||||
error.
|
||||
|
||||
parse_hour(Rest,Result) ->
|
||||
case date_string_to_int(Rest,0,23) of
|
||||
{Hour,""} -> Result#{hour=>Hour};
|
||||
error -> error
|
||||
end.
|
||||
|
||||
parse_day_of_week(Rest,Result) ->
|
||||
case date_string_to_int(Rest,0,6) of
|
||||
{DayOfWeek,Rest} -> parse_hour(Rest,Result#{day_of_week=>DayOfWeek});
|
||||
error -> error
|
||||
end.
|
||||
|
||||
parse_day_of_month([Last | Rest],Result)
|
||||
when Last=:=$l orelse Last=:=$L ->
|
||||
parse_hour(Rest,Result#{day_of_month=>last});
|
||||
parse_day_of_month(Rest,Result) ->
|
||||
case date_string_to_int(Rest,1,31) of
|
||||
{DayOfMonth,Rest} -> parse_hour(Rest,Result#{day_of_month=>DayOfMonth});
|
||||
error -> error
|
||||
end.
|
||||
|
||||
date_string_to_int(String,Min,Max) ->
|
||||
case string:to_integer(String) of
|
||||
{Int,Rest} when is_integer(Int) andalso Int>=Min andalso Int=<Max ->
|
||||
{Int,Rest};
|
||||
_ ->
|
||||
error
|
||||
end.
|
||||
|
||||
maybe_remove_archives(Count,#{file_name:=FileName}=State) ->
|
||||
Archive = rot_file_name(FileName,Count,false),
|
||||
CompressedArchive = rot_file_name(FileName,Count,true),
|
||||
case {file:read_file_info(Archive,[raw]),
|
||||
file:read_file_info(CompressedArchive,[raw])} of
|
||||
{{error,enoent},{error,enoent}} ->
|
||||
ok;
|
||||
_ ->
|
||||
_ = file:delete(Archive),
|
||||
_ = file:delete(CompressedArchive),
|
||||
maybe_remove_archives(Count+1,State)
|
||||
end.
|
||||
|
||||
maybe_update_compress(Count,#{rotation:=#{count:=Count}}) ->
|
||||
ok;
|
||||
maybe_update_compress(N,#{file_name:=FileName,
|
||||
rotation:=#{compress:=Compress}}=State) ->
|
||||
Archive = rot_file_name(FileName,N,not Compress),
|
||||
case file:read_file_info(Archive,[raw]) of
|
||||
{ok,_} when Compress ->
|
||||
compress_file(Archive);
|
||||
{ok,_} ->
|
||||
decompress_file(Archive);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
maybe_update_compress(N+1,State).
|
||||
|
||||
maybe_rotate_file(Bin,#{rotation:=_}=State) when is_binary(Bin) ->
|
||||
maybe_rotate_file(byte_size(Bin),State);
|
||||
maybe_rotate_file(AddSize,#{rotation:=#{size:=RotSize,
|
||||
curr_size:=CurrSize}=Rotation}=State) ->
|
||||
{DateBasedRotNeeded, Rotation1} = is_date_based_rotation_needed(Rotation),
|
||||
NewSize = CurrSize + AddSize,
|
||||
if NewSize>RotSize ->
|
||||
rotate_file(State#{rotation=>Rotation1#{curr_size=>NewSize}});
|
||||
DateBasedRotNeeded ->
|
||||
rotate_file(State#{rotation=>Rotation1#{curr_size=>NewSize}});
|
||||
true ->
|
||||
State#{rotation=>Rotation1#{curr_size=>NewSize}}
|
||||
end;
|
||||
maybe_rotate_file(_Bin,State) ->
|
||||
State.
|
||||
|
||||
is_date_based_rotation_needed(#{last_rotation_ts:=PrevTimestamp,
|
||||
on_date:=DateSpec}=Rotation) ->
|
||||
CurrTimestamp = rotation_timestamp(),
|
||||
case is_date_based_rotation_needed(DateSpec,PrevTimestamp,CurrTimestamp) of
|
||||
true -> {true,Rotation#{last_rotation_ts=>CurrTimestamp}};
|
||||
false -> {false,Rotation}
|
||||
end;
|
||||
is_date_based_rotation_needed(Rotation) ->
|
||||
{false,Rotation#{last_rotation_ts=>rotation_timestamp()}}.
|
||||
|
||||
is_date_based_rotation_needed(#{every:=day,hour:=Hour},
|
||||
{Date1,Time1},{Date2,Time2})
|
||||
when (Date1<Date2 orelse (Date1=:=Date2 andalso Time1<{Hour,0,0})) andalso
|
||||
Time2>={Hour,0,0} ->
|
||||
true;
|
||||
is_date_based_rotation_needed(#{every:=day,hour:=Hour},
|
||||
{Date1,_}=DateTime1,{Date2,Time2}=DateTime2)
|
||||
when Date1<Date2 andalso
|
||||
Time2<{Hour,0,0} ->
|
||||
GregDays2 = calendar:date_to_gregorian_days(Date2),
|
||||
TargetDate = calendar:gregorian_days_to_date(GregDays2 - 1),
|
||||
TargetDateTime = {TargetDate,{Hour,0,0}},
|
||||
DateTime1<TargetDateTime andalso DateTime2>=TargetDateTime;
|
||||
is_date_based_rotation_needed(#{every:=week,day_of_week:=TargetDoW,hour:=Hour},
|
||||
DateTime1,{Date2,_}=DateTime2) ->
|
||||
DoW2 = calendar:day_of_the_week(Date2) rem 7,
|
||||
DaysSinceTargetDoW = ((DoW2 - TargetDoW) + 7) rem 7,
|
||||
GregDays2 = calendar:date_to_gregorian_days(Date2),
|
||||
TargetGregDays = GregDays2 - DaysSinceTargetDoW,
|
||||
TargetDate = calendar:gregorian_days_to_date(TargetGregDays),
|
||||
TargetDateTime = {TargetDate,{Hour,0,0}},
|
||||
DateTime1<TargetDateTime andalso DateTime2>=TargetDateTime;
|
||||
is_date_based_rotation_needed(#{every:=month,day_of_month:=last,hour:=Hour},
|
||||
DateTime1,{{Year2,Month2,_}=Date2,_}=DateTime2) ->
|
||||
DoMA = calendar:last_day_of_the_month(Year2, Month2),
|
||||
DateA = {Year2,Month2,DoMA},
|
||||
TargetDate = if
|
||||
DateA>Date2 ->
|
||||
case Month2 - 1 of
|
||||
0 ->
|
||||
{Year2-1,12,31};
|
||||
MonthB ->
|
||||
{Year2,MonthB,
|
||||
calendar:last_day_of_the_month(Year2,MonthB)}
|
||||
end;
|
||||
true ->
|
||||
DateA
|
||||
end,
|
||||
TargetDateTime = {TargetDate,{Hour,0,0}},
|
||||
io:format(standard_error, "TargetDateTime=~p~n", [TargetDateTime]),
|
||||
DateTime1<TargetDateTime andalso DateTime2>=TargetDateTime;
|
||||
is_date_based_rotation_needed(#{every:=month,day_of_month:=DoM,hour:=Hour},
|
||||
DateTime1,{{Year2,Month2,_}=Date2,_}=DateTime2) ->
|
||||
DateA = {Year2,Month2,adapt_day_of_month(Year2,Month2,DoM)},
|
||||
TargetDate = if
|
||||
DateA>Date2 ->
|
||||
case Month2 - 1 of
|
||||
0 ->
|
||||
{Year2-1,12,31};
|
||||
MonthB ->
|
||||
{Year2,MonthB,
|
||||
adapt_day_of_month(Year2,MonthB,DoM)}
|
||||
end;
|
||||
true ->
|
||||
DateA
|
||||
end,
|
||||
TargetDateTime = {TargetDate,{Hour,0,0}},
|
||||
io:format(standard_error, "TargetDateTime=~p~n", [TargetDateTime]),
|
||||
DateTime1<TargetDateTime andalso DateTime2>=TargetDateTime;
|
||||
is_date_based_rotation_needed(_,_,_) ->
|
||||
false.
|
||||
|
||||
adapt_day_of_month(Year,Month,Day) ->
|
||||
LastDay = calendar:last_day_of_the_month(Year,Month),
|
||||
erlang:min(Day,LastDay).
|
||||
|
||||
rotate_file(#{file_name:=FileName,modes:=Modes,rotation:=Rotation}=State) ->
|
||||
State1 = sync_dev(State),
|
||||
_ = delayed_write_close(State),
|
||||
rotate_files(FileName,maps:get(count,Rotation),maps:get(compress,Rotation)),
|
||||
case file:open(FileName,Modes) of
|
||||
{ok,Fd} ->
|
||||
{ok,#file_info{inode=INode}} = file:read_file_info(FileName,[raw]),
|
||||
CurrTimestamp = rotation_timestamp(),
|
||||
State1#{fd=>Fd,inode=>INode,
|
||||
rotation=>Rotation#{curr_size=>0,
|
||||
last_rotation_ts=>CurrTimestamp}};
|
||||
Error ->
|
||||
exit({could_not_reopen_file,Error})
|
||||
end.
|
||||
|
||||
rotation_timestamp() ->
|
||||
calendar:now_to_local_time(erlang:timestamp()).
|
||||
|
||||
rotate_files(FileName,0,_Compress) ->
|
||||
_ = file:delete(FileName),
|
||||
ok;
|
||||
rotate_files(FileName,1,Compress) ->
|
||||
FileName0 = FileName++".0",
|
||||
_ = file:rename(FileName,FileName0),
|
||||
if Compress -> compress_file(FileName0);
|
||||
true -> ok
|
||||
end,
|
||||
ok;
|
||||
rotate_files(FileName,Count,Compress) ->
|
||||
_ = file:rename(rot_file_name(FileName,Count-2,Compress),
|
||||
rot_file_name(FileName,Count-1,Compress)),
|
||||
rotate_files(FileName,Count-1,Compress).
|
||||
|
||||
rot_file_name(FileName,Count,false) ->
|
||||
FileName ++ "." ++ integer_to_list(Count);
|
||||
rot_file_name(FileName,Count,true) ->
|
||||
rot_file_name(FileName,Count,false) ++ ".gz".
|
||||
|
||||
compress_file(FileName) ->
|
||||
{ok,In} = file:open(FileName,[read,binary]),
|
||||
{ok,Out} = file:open(FileName++".gz",[write]),
|
||||
Z = zlib:open(),
|
||||
zlib:deflateInit(Z, default, deflated, 31, 8, default),
|
||||
compress_data(Z,In,Out),
|
||||
zlib:deflateEnd(Z),
|
||||
zlib:close(Z),
|
||||
_ = file:close(In),
|
||||
_ = file:close(Out),
|
||||
_ = file:delete(FileName),
|
||||
ok.
|
||||
|
||||
compress_data(Z,In,Out) ->
|
||||
case file:read(In,100000) of
|
||||
{ok,Data} ->
|
||||
Compressed = zlib:deflate(Z, Data),
|
||||
_ = file:write(Out,Compressed),
|
||||
compress_data(Z,In,Out);
|
||||
eof ->
|
||||
Compressed = zlib:deflate(Z, <<>>, finish),
|
||||
_ = file:write(Out,Compressed),
|
||||
ok
|
||||
end.
|
||||
|
||||
decompress_file(FileName) ->
|
||||
{ok,In} = file:open(FileName,[read,binary]),
|
||||
{ok,Out} = file:open(filename:rootname(FileName,".gz"),[write]),
|
||||
Z = zlib:open(),
|
||||
zlib:inflateInit(Z, 31),
|
||||
decompress_data(Z,In,Out),
|
||||
zlib:inflateEnd(Z),
|
||||
zlib:close(Z),
|
||||
_ = file:close(In),
|
||||
_ = file:close(Out),
|
||||
_ = file:delete(FileName),
|
||||
ok.
|
||||
|
||||
decompress_data(Z,In,Out) ->
|
||||
case file:read(In,1000) of
|
||||
{ok,Data} ->
|
||||
Decompressed = zlib:inflate(Z, Data),
|
||||
_ = file:write(Out,Decompressed),
|
||||
decompress_data(Z,In,Out);
|
||||
eof ->
|
||||
ok
|
||||
end.
|
||||
|
||||
maybe_notify_error(_Op, ok, _State) ->
|
||||
ok;
|
||||
maybe_notify_error(Op, Result, #{write_res:=WR,sync_res:=SR})
|
||||
when (Op==write andalso Result==WR) orelse
|
||||
(Op==filesync andalso Result==SR) ->
|
||||
%% don't report same error twice
|
||||
ok;
|
||||
maybe_notify_error(Op, Error, #{handler_name:=HandlerName,file_name:=FileName}) ->
|
||||
logger_h_common:error_notify({HandlerName,Op,FileName,Error}),
|
||||
ok.
|
||||
|
||||
timestamp() ->
|
||||
erlang:monotonic_time(millisecond).
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_logger_text_fmt).
|
||||
|
||||
-export([format/2]).
|
||||
|
||||
format(#{msg := Msg, meta := Meta} = LogEvent, Config) ->
|
||||
Prefix = format_prefix(LogEvent, Config),
|
||||
Color = pick_color(LogEvent, Config),
|
||||
FormattedMsg = format_msg(Msg, Meta, Config),
|
||||
prepend_prefix_to_msg_and_add_color(Prefix, Color, FormattedMsg, Config).
|
||||
|
||||
format_prefix(_, #{prefix := false}) ->
|
||||
none;
|
||||
format_prefix(#{level := Level,
|
||||
meta := #{time := Timestamp,
|
||||
pid := Pid}},
|
||||
Config) ->
|
||||
Time = format_time(Timestamp, Config),
|
||||
LevelName = level_name(Level, Config),
|
||||
io_lib:format("~ts [~ts] ~p", [Time, LevelName, Pid]).
|
||||
|
||||
level_name(Level, #{level_name := full}) ->
|
||||
Level;
|
||||
level_name(Level, #{level_name := uc3}) ->
|
||||
level_3letter_uc_name(Level);
|
||||
level_name(Level, #{level_name := lc3}) ->
|
||||
level_3letter_lc_name(Level);
|
||||
level_name(Level, #{level_name := uc4}) ->
|
||||
level_4letter_uc_name(Level);
|
||||
level_name(Level, #{level_name := lc4}) ->
|
||||
level_4letter_lc_name(Level);
|
||||
level_name(Level, _) ->
|
||||
Level.
|
||||
|
||||
level_3letter_lc_name(debug) -> "dbg";
|
||||
level_3letter_lc_name(info) -> "inf";
|
||||
level_3letter_lc_name(notice) -> "ntc";
|
||||
level_3letter_lc_name(warning) -> "wrn";
|
||||
level_3letter_lc_name(error) -> "err";
|
||||
level_3letter_lc_name(critical) -> "crt";
|
||||
level_3letter_lc_name(alert) -> "alt";
|
||||
level_3letter_lc_name(emergency) -> "emg".
|
||||
|
||||
level_3letter_uc_name(debug) -> "DBG";
|
||||
level_3letter_uc_name(info) -> "INF";
|
||||
level_3letter_uc_name(notice) -> "NTC";
|
||||
level_3letter_uc_name(warning) -> "WRN";
|
||||
level_3letter_uc_name(error) -> "ERR";
|
||||
level_3letter_uc_name(critical) -> "CRT";
|
||||
level_3letter_uc_name(alert) -> "ALT";
|
||||
level_3letter_uc_name(emergency) -> "EMG".
|
||||
|
||||
level_4letter_lc_name(debug) -> "dbug";
|
||||
level_4letter_lc_name(info) -> "info";
|
||||
level_4letter_lc_name(notice) -> "noti";
|
||||
level_4letter_lc_name(warning) -> "warn";
|
||||
level_4letter_lc_name(error) -> "erro";
|
||||
level_4letter_lc_name(critical) -> "crit";
|
||||
level_4letter_lc_name(alert) -> "alrt";
|
||||
level_4letter_lc_name(emergency) -> "emgc".
|
||||
|
||||
level_4letter_uc_name(debug) -> "DBUG";
|
||||
level_4letter_uc_name(info) -> "INFO";
|
||||
level_4letter_uc_name(notice) -> "NOTI";
|
||||
level_4letter_uc_name(warning) -> "WARN";
|
||||
level_4letter_uc_name(error) -> "ERRO";
|
||||
level_4letter_uc_name(critical) -> "CRIT";
|
||||
level_4letter_uc_name(alert) -> "ALRT";
|
||||
level_4letter_uc_name(emergency) -> "EMGC".
|
||||
|
||||
format_time(Timestamp, _) ->
|
||||
Options = [{unit, microsecond},
|
||||
{time_designator, $\s}],
|
||||
calendar:system_time_to_rfc3339(Timestamp, Options).
|
||||
|
||||
format_msg({string, Chardata}, Meta, Config) ->
|
||||
format_msg({"~ts", [Chardata]}, Meta, Config);
|
||||
format_msg({report, Report}, Meta, Config) ->
|
||||
FormattedReport = format_report(Report, Meta, Config),
|
||||
format_msg(FormattedReport, Meta, Config);
|
||||
format_msg({Format, Args}, _, _) ->
|
||||
io_lib:format(Format, Args).
|
||||
|
||||
format_report(
|
||||
#{label := {application_controller, _}} = Report, Meta, Config) ->
|
||||
format_application_progress(Report, Meta, Config);
|
||||
format_report(
|
||||
#{label := {supervisor, progress}} = Report, Meta, Config) ->
|
||||
format_supervisor_progress(Report, Meta, Config);
|
||||
format_report(
|
||||
Report, #{report_cb := Cb} = Meta, Config) ->
|
||||
try
|
||||
case erlang:fun_info(Cb, arity) of
|
||||
{arity, 1} -> Cb(Report);
|
||||
{arity, 2} -> {"~ts", [Cb(Report, #{})]}
|
||||
end
|
||||
catch
|
||||
_:_:_ ->
|
||||
format_report(Report, maps:remove(report_cb, Meta), Config)
|
||||
end;
|
||||
format_report(Report, _, _) ->
|
||||
logger:format_report(Report).
|
||||
|
||||
format_application_progress(#{label := {_, progress},
|
||||
report := InternalReport}, _, _) ->
|
||||
Application = proplists:get_value(application, InternalReport),
|
||||
StartedAt = proplists:get_value(started_at, InternalReport),
|
||||
{"Application ~w started on ~0p",
|
||||
[Application, StartedAt]};
|
||||
format_application_progress(#{label := {_, exit},
|
||||
report := InternalReport}, _, _) ->
|
||||
Application = proplists:get_value(application, InternalReport),
|
||||
Exited = proplists:get_value(exited, InternalReport),
|
||||
{"Application ~w exited with reason: ~0p",
|
||||
[Application, Exited]}.
|
||||
|
||||
format_supervisor_progress(#{report := InternalReport}, _, _) ->
|
||||
Supervisor = proplists:get_value(supervisor, InternalReport),
|
||||
Started = proplists:get_value(started, InternalReport),
|
||||
Id = proplists:get_value(id, Started),
|
||||
Pid = proplists:get_value(pid, Started),
|
||||
Mfa = proplists:get_value(mfargs, Started),
|
||||
{"Supervisor ~w: child ~w started (~w): ~0p",
|
||||
[Supervisor, Id, Pid, Mfa]}.
|
||||
|
||||
pick_color(_, #{color := false}) ->
|
||||
{"", ""};
|
||||
pick_color(#{level := Level}, #{color := true} = Config) ->
|
||||
ColorStart = level_to_color(Level, Config),
|
||||
ColorEnd = "\033[0m",
|
||||
{ColorStart, ColorEnd}.
|
||||
|
||||
level_to_color(debug, _) -> "\033[38;5;246m";
|
||||
level_to_color(info, _) -> "";
|
||||
level_to_color(notice, _) -> "\033[38;5;87m";
|
||||
level_to_color(warning, _) -> "\033[38;5;214m";
|
||||
level_to_color(error, _) -> "\033[38;5;160m";
|
||||
level_to_color(critical, _) -> "\033[1;37m\033[48;5;20m";
|
||||
level_to_color(alert, _) -> "\033[1;37m\033[48;5;93m";
|
||||
level_to_color(emergency, _) -> "\033[1;37m\033[48;5;196m".
|
||||
|
||||
prepend_prefix_to_msg_and_add_color(
|
||||
none, {ColorStart, ColorEnd}, FormattedMsg, Config) ->
|
||||
Lines = split_lines(FormattedMsg, Config),
|
||||
[case Line of
|
||||
"" -> [$\n];
|
||||
_ -> [ColorStart, Line, ColorEnd, $\n]
|
||||
end
|
||||
|| Line <- Lines];
|
||||
prepend_prefix_to_msg_and_add_color(
|
||||
Prefix, {ColorStart, ColorEnd}, FormattedMsg, Config) ->
|
||||
Lines = split_lines(FormattedMsg, Config),
|
||||
[case Line of
|
||||
"" -> [ColorStart, Prefix, ColorEnd, $\n];
|
||||
_ -> [ColorStart, Prefix, " ", Line, ColorEnd, $\n]
|
||||
end
|
||||
|| Line <- Lines].
|
||||
|
||||
split_lines(FormattedMsg, _) ->
|
||||
FlattenMsg = lists:flatten(FormattedMsg),
|
||||
string:split(FlattenMsg, [$\n], all).
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
-module(rabbit_prelaunch).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([run_prelaunch_first_phase/0,
|
||||
assert_mnesia_is_stopped/0,
|
||||
get_context/0,
|
||||
|
|
@ -24,6 +27,8 @@
|
|||
|
||||
run_prelaunch_first_phase() ->
|
||||
try
|
||||
ok = logger:set_process_metadata(
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
do_run()
|
||||
catch
|
||||
throw:{error, _} = Error ->
|
||||
|
|
@ -67,26 +72,25 @@ do_run() ->
|
|||
?assertMatch(#{}, Context0),
|
||||
|
||||
%% Setup logging for the prelaunch phase.
|
||||
ok = rabbit_prelaunch_early_logging:setup_early_logging(Context0, true),
|
||||
ok = rabbit_prelaunch_early_logging:setup_early_logging(Context0),
|
||||
|
||||
IsInitialPass = is_initial_pass(),
|
||||
case IsInitialPass of
|
||||
true ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"== Prelaunch phase [1/2] (initial pass) =="),
|
||||
rabbit_log_prelaunch:debug("");
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Prelaunch phase [1/2] (initial pass) =="),
|
||||
?LOG_DEBUG("");
|
||||
false ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Prelaunch phase [1/2] =="),
|
||||
rabbit_log_prelaunch:debug("")
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Prelaunch phase [1/2] =="),
|
||||
?LOG_DEBUG("")
|
||||
end,
|
||||
rabbit_env:log_process_env(),
|
||||
|
||||
%% Load rabbitmq-env.conf, redo logging setup and continue.
|
||||
Context1 = rabbit_env:get_context_after_logging_init(Context0),
|
||||
?assertMatch(#{}, Context1),
|
||||
ok = rabbit_prelaunch_early_logging:setup_early_logging(Context1, true),
|
||||
ok = rabbit_prelaunch_early_logging:setup_early_logging(Context1),
|
||||
rabbit_env:log_process_env(),
|
||||
|
||||
%% Complete context now that we have the final environment loaded.
|
||||
|
|
@ -111,7 +115,7 @@ do_run() ->
|
|||
ok = rabbit_prelaunch_dist:setup(Context),
|
||||
|
||||
%% 4. Write PID file.
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
?LOG_DEBUG(""),
|
||||
_ = write_pid_file(Context),
|
||||
ignore.
|
||||
|
||||
|
|
@ -138,7 +142,7 @@ get_stop_reason() ->
|
|||
set_stop_reason(Reason) ->
|
||||
case get_stop_reason() of
|
||||
undefined ->
|
||||
rabbit_log_prelaunch:debug("Set stop reason to: ~p", [Reason]),
|
||||
?LOG_DEBUG("Set stop reason to: ~p", [Reason]),
|
||||
persistent_term:put(?PT_KEY_STOP_REASON, Reason);
|
||||
_ ->
|
||||
ok
|
||||
|
|
@ -161,7 +165,7 @@ setup_shutdown_func() ->
|
|||
{ok, {ThisMod, ThisFunc}} ->
|
||||
ok;
|
||||
{ok, {ExistingMod, ExistingFunc}} ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Setting up kernel shutdown function: ~s:~s/1 "
|
||||
"(chained with ~s:~s/1)",
|
||||
[ThisMod, ThisFunc, ExistingMod, ExistingFunc]),
|
||||
|
|
@ -170,7 +174,7 @@ setup_shutdown_func() ->
|
|||
ExistingShutdownFunc),
|
||||
ok = record_kernel_shutdown_func(ThisMod, ThisFunc);
|
||||
_ ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Setting up kernel shutdown function: ~s:~s/1",
|
||||
[ThisMod, ThisFunc]),
|
||||
ok = record_kernel_shutdown_func(ThisMod, ThisFunc)
|
||||
|
|
@ -182,7 +186,7 @@ record_kernel_shutdown_func(Mod, Func) ->
|
|||
[{persistent, true}]).
|
||||
|
||||
shutdown_func(Reason) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Running ~s:shutdown_func() as part of `kernel` shutdown", [?MODULE]),
|
||||
Context = get_context(),
|
||||
remove_pid_file(Context),
|
||||
|
|
@ -195,7 +199,7 @@ shutdown_func(Reason) ->
|
|||
end.
|
||||
|
||||
write_pid_file(#{pid_file := PidFile}) ->
|
||||
rabbit_log_prelaunch:debug("Writing PID file: ~s", [PidFile]),
|
||||
?LOG_DEBUG("Writing PID file: ~s", [PidFile]),
|
||||
case filelib:ensure_dir(PidFile) of
|
||||
ok ->
|
||||
OSPid = os:getpid(),
|
||||
|
|
@ -203,13 +207,13 @@ write_pid_file(#{pid_file := PidFile}) ->
|
|||
ok ->
|
||||
ok;
|
||||
{error, Reason} = Error ->
|
||||
rabbit_log_prelaunch:warning(
|
||||
?LOG_WARNING(
|
||||
"Failed to write PID file \"~s\": ~s",
|
||||
[PidFile, file:format_error(Reason)]),
|
||||
Error
|
||||
end;
|
||||
{error, Reason} = Error ->
|
||||
rabbit_log_prelaunch:warning(
|
||||
?LOG_WARNING(
|
||||
"Failed to create PID file \"~s\" directory: ~s",
|
||||
[PidFile, file:format_error(Reason)]),
|
||||
Error
|
||||
|
|
@ -218,10 +222,10 @@ write_pid_file(_) ->
|
|||
ok.
|
||||
|
||||
remove_pid_file(#{pid_file := PidFile, keep_pid_file_on_exit := true}) ->
|
||||
rabbit_log_prelaunch:debug("Keeping PID file: ~s", [PidFile]),
|
||||
?LOG_DEBUG("Keeping PID file: ~s", [PidFile]),
|
||||
ok;
|
||||
remove_pid_file(#{pid_file := PidFile}) ->
|
||||
rabbit_log_prelaunch:debug("Deleting PID file: ~s", [PidFile]),
|
||||
?LOG_DEBUG("Deleting PID file: ~s", [PidFile]),
|
||||
_ = file:delete(PidFile),
|
||||
ok;
|
||||
remove_pid_file(_) ->
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
-module(rabbit_prelaunch_conf).
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
-include_lib("stdlib/include/zip.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup/1,
|
||||
get_config_state/0,
|
||||
|
|
@ -15,8 +17,9 @@
|
|||
-endif.
|
||||
|
||||
setup(Context) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Configuration =="),
|
||||
?LOG_DEBUG(
|
||||
"\n== Configuration ==",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
|
||||
%% TODO: Check if directories/files are inside Mnesia dir.
|
||||
|
||||
|
|
@ -52,9 +55,10 @@ setup(Context) ->
|
|||
#{config_files => ConfigFiles,
|
||||
config_advanced_file => AdvancedConfigFile};
|
||||
undefined when AdvancedConfigFile =/= undefined ->
|
||||
rabbit_log_prelaunch:warning(
|
||||
?LOG_WARNING(
|
||||
"Using RABBITMQ_ADVANCED_CONFIG_FILE: ~s",
|
||||
[AdvancedConfigFile]),
|
||||
[AdvancedConfigFile],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
Config = load_cuttlefish_config_file(Context,
|
||||
AdditionalConfigFiles,
|
||||
AdvancedConfigFile),
|
||||
|
|
@ -66,10 +70,10 @@ setup(Context) ->
|
|||
#{config_files => [],
|
||||
config_advanced_file => undefined}
|
||||
end,
|
||||
ok = override_with_hard_coded_critical_config(),
|
||||
ok = set_credentials_obfuscation_secret(),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Saving config state to application env: ~p", [State]),
|
||||
?LOG_DEBUG(
|
||||
"Saving config state to application env: ~p", [State],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
store_config_state(State).
|
||||
|
||||
store_config_state(ConfigState) ->
|
||||
|
|
@ -83,7 +87,8 @@ get_config_state() ->
|
|||
%% -------------------------------------------------------------------
|
||||
|
||||
set_default_config() ->
|
||||
rabbit_log_prelaunch:debug("Setting default config"),
|
||||
?LOG_DEBUG("Setting default config",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
Config = [
|
||||
{ra,
|
||||
[
|
||||
|
|
@ -99,6 +104,8 @@ set_default_config() ->
|
|||
%% goes down it is still immediately detected
|
||||
{poll_interval, 5000}
|
||||
]},
|
||||
{syslog,
|
||||
[{app_name, "rabbitmq-server"}]},
|
||||
{sysmon_handler,
|
||||
[{process_limit, 100},
|
||||
{port_limit, 100},
|
||||
|
|
@ -126,15 +133,18 @@ find_actual_main_config_file(#{main_config_file := File}) ->
|
|||
true ->
|
||||
case filelib:is_regular(NewFormatFile) of
|
||||
true ->
|
||||
rabbit_log_prelaunch:warning(
|
||||
?LOG_WARNING(
|
||||
"Both old (.config) and new (.conf) format "
|
||||
"config files exist."),
|
||||
rabbit_log_prelaunch:warning(
|
||||
"config files exist.",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
?LOG_WARNING(
|
||||
"Using the old format config file: ~s",
|
||||
[OldFormatFile]),
|
||||
rabbit_log_prelaunch:warning(
|
||||
[OldFormatFile],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
?LOG_WARNING(
|
||||
"Please update your config files to the new "
|
||||
"format and remove the old file."),
|
||||
"format and remove the old file.",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
false ->
|
||||
ok
|
||||
|
|
@ -193,15 +203,18 @@ generate_config_from_cuttlefish_files(Context,
|
|||
SchemaFiles = find_cuttlefish_schemas(Context),
|
||||
case SchemaFiles of
|
||||
[] ->
|
||||
rabbit_log_prelaunch:error(
|
||||
"No configuration schema found~n", []),
|
||||
?LOG_ERROR(
|
||||
"No configuration schema found", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, no_configuration_schema_found});
|
||||
_ ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Configuration schemas found:~n", []),
|
||||
?LOG_DEBUG(
|
||||
"Configuration schemas found:~n", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
lists:foreach(
|
||||
fun(SchemaFile) ->
|
||||
rabbit_log_prelaunch:debug(" - ~ts", [SchemaFile])
|
||||
?LOG_DEBUG(" - ~ts", [SchemaFile],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end,
|
||||
SchemaFiles),
|
||||
ok
|
||||
|
|
@ -209,37 +222,44 @@ generate_config_from_cuttlefish_files(Context,
|
|||
Schema = cuttlefish_schema:files(SchemaFiles),
|
||||
|
||||
%% Load configuration.
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Loading configuration files (Cuttlefish based):"),
|
||||
?LOG_DEBUG(
|
||||
"Loading configuration files (Cuttlefish based):",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
lists:foreach(
|
||||
fun(ConfigFile) ->
|
||||
rabbit_log_prelaunch:debug(" - ~ts", [ConfigFile])
|
||||
?LOG_DEBUG(" - ~ts", [ConfigFile],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end, ConfigFiles),
|
||||
case cuttlefish_conf:files(ConfigFiles) of
|
||||
{errorlist, Errors} ->
|
||||
rabbit_log_prelaunch:error("Error parsing configuration:"),
|
||||
?LOG_ERROR("Error parsing configuration:",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
lists:foreach(
|
||||
fun(Error) ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
" - ~ts",
|
||||
[cuttlefish_error:xlate(Error)])
|
||||
[cuttlefish_error:xlate(Error)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end, Errors),
|
||||
rabbit_log_prelaunch:error(
|
||||
"Are these files using the Cuttlefish format?"),
|
||||
?LOG_ERROR(
|
||||
"Are these files using the Cuttlefish format?",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_parse_configuration_file});
|
||||
Config0 ->
|
||||
%% Finalize configuration, based on the schema.
|
||||
Config = case cuttlefish_generator:map(Schema, Config0) of
|
||||
{error, Phase, {errorlist, Errors}} ->
|
||||
%% TODO
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Error preparing configuration in phase ~ts:",
|
||||
[Phase]),
|
||||
[Phase],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
lists:foreach(
|
||||
fun(Error) ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
" - ~ts",
|
||||
[cuttlefish_error:xlate(Error)])
|
||||
[cuttlefish_error:xlate(Error)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end, Errors),
|
||||
throw(
|
||||
{error, failed_to_prepare_configuration});
|
||||
|
|
@ -253,8 +273,9 @@ generate_config_from_cuttlefish_files(Context,
|
|||
|
||||
find_cuttlefish_schemas(Context) ->
|
||||
Apps = list_apps(Context),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Looking up configuration schemas in the following applications:"),
|
||||
?LOG_DEBUG(
|
||||
"Looking up configuration schemas in the following applications:",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
find_cuttlefish_schemas(Apps, []).
|
||||
|
||||
find_cuttlefish_schemas([App | Rest], AllSchemas) ->
|
||||
|
|
@ -281,9 +302,10 @@ list_apps1([Dir | Rest], Apps) ->
|
|||
Apps1 = lists:umerge(Apps, lists:sort(NewApps)),
|
||||
list_apps1(Rest, Apps1);
|
||||
{error, Reason} ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Failed to list directory \"~ts\" content: ~ts",
|
||||
[Dir, file:format_error(Reason)]),
|
||||
[Dir, file:format_error(Reason)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
list_apps1(Rest, Apps)
|
||||
end;
|
||||
list_apps1([], AppInfos) ->
|
||||
|
|
@ -299,17 +321,19 @@ list_schemas_in_app(App) ->
|
|||
true ->
|
||||
case code:priv_dir(App) of
|
||||
{error, bad_name} ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
" [ ] ~s (no readable priv dir)", [App]),
|
||||
?LOG_DEBUG(
|
||||
" [ ] ~s (no readable priv dir)", [App],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
[];
|
||||
PrivDir ->
|
||||
SchemaDir = filename:join([PrivDir, "schema"]),
|
||||
do_list_schemas_in_app(App, SchemaDir)
|
||||
end;
|
||||
Reason1 ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
" [ ] ~s (failed to load application: ~p)",
|
||||
[App, Reason1]),
|
||||
[App, Reason1],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
[]
|
||||
end,
|
||||
case Unload of
|
||||
|
|
@ -322,74 +346,71 @@ list_schemas_in_app(App) ->
|
|||
do_list_schemas_in_app(App, SchemaDir) ->
|
||||
case erl_prim_loader:list_dir(SchemaDir) of
|
||||
{ok, Files} ->
|
||||
rabbit_log_prelaunch:debug(" [x] ~s", [App]),
|
||||
?LOG_DEBUG(" [x] ~s", [App],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
[filename:join(SchemaDir, File)
|
||||
|| [C | _] = File <- Files,
|
||||
C =/= $.];
|
||||
error ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
" [ ] ~s (no readable schema dir)", [App]),
|
||||
?LOG_DEBUG(
|
||||
" [ ] ~s (no readable schema dir)", [App],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
[]
|
||||
end.
|
||||
|
||||
override_with_advanced_config(Config, undefined) ->
|
||||
Config;
|
||||
override_with_advanced_config(Config, AdvancedConfigFile) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Override with advanced configuration file \"~ts\"",
|
||||
[AdvancedConfigFile]),
|
||||
[AdvancedConfigFile],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case file:consult(AdvancedConfigFile) of
|
||||
{ok, [AdvancedConfig]} ->
|
||||
cuttlefish_advanced:overlay(Config, AdvancedConfig);
|
||||
{ok, OtherTerms} ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Failed to load advanced configuration file \"~ts\", "
|
||||
"incorrect format: ~p",
|
||||
[AdvancedConfigFile, OtherTerms]),
|
||||
[AdvancedConfigFile, OtherTerms],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_parse_advanced_configuration_file});
|
||||
{error, Reason} ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Failed to load advanced configuration file \"~ts\": ~ts",
|
||||
[AdvancedConfigFile, file:format_error(Reason)]),
|
||||
[AdvancedConfigFile, file:format_error(Reason)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_read_advanced_configuration_file})
|
||||
end.
|
||||
|
||||
override_with_hard_coded_critical_config() ->
|
||||
rabbit_log_prelaunch:debug("Override with hard-coded critical config"),
|
||||
Config = [
|
||||
{ra,
|
||||
%% Make Ra use a custom logger that dispatches to lager
|
||||
%% instead of the default OTP logger
|
||||
[{logger_module, rabbit_log_ra_shim}]},
|
||||
{osiris,
|
||||
[{logger_module, rabbit_log_osiris_shim}]}
|
||||
],
|
||||
apply_erlang_term_based_config(Config).
|
||||
|
||||
apply_erlang_term_based_config([{_, []} | Rest]) ->
|
||||
apply_erlang_term_based_config(Rest);
|
||||
apply_erlang_term_based_config([{App, Vars} | Rest]) ->
|
||||
rabbit_log_prelaunch:debug(" Applying configuration for '~s':", [App]),
|
||||
?LOG_DEBUG(" Applying configuration for '~s':", [App],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = apply_app_env_vars(App, Vars),
|
||||
apply_erlang_term_based_config(Rest);
|
||||
apply_erlang_term_based_config([]) ->
|
||||
ok.
|
||||
|
||||
apply_app_env_vars(App, [{Var, Value} | Rest]) ->
|
||||
rabbit_log_prelaunch:debug(" - ~s = ~p", [Var, Value]),
|
||||
?LOG_DEBUG(" - ~s = ~p", [Var, Value],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = application:set_env(App, Var, Value, [{persistent, true}]),
|
||||
apply_app_env_vars(App, Rest);
|
||||
apply_app_env_vars(_, []) ->
|
||||
ok.
|
||||
|
||||
set_credentials_obfuscation_secret() ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Refreshing credentials obfuscation configuration from env: ~p",
|
||||
[application:get_all_env(credentials_obfuscation)]),
|
||||
[application:get_all_env(credentials_obfuscation)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = credentials_obfuscation:refresh_config(),
|
||||
CookieBin = rabbit_data_coercion:to_binary(erlang:get_cookie()),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Setting credentials obfuscation secret to '~s'", [CookieBin]),
|
||||
?LOG_DEBUG(
|
||||
"Setting credentials obfuscation secret to '~s'", [CookieBin],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = credentials_obfuscation:set_secret(CookieBin).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
@ -397,7 +418,8 @@ set_credentials_obfuscation_secret() ->
|
|||
%% -------------------------------------------------------------------
|
||||
|
||||
decrypt_config(Apps) ->
|
||||
rabbit_log_prelaunch:debug("Decoding encrypted config values (if any)"),
|
||||
?LOG_DEBUG("Decoding encrypted config values (if any)",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ConfigEntryDecoder = application:get_env(rabbit, config_entry_decoder, []),
|
||||
decrypt_config(Apps, ConfigEntryDecoder).
|
||||
|
||||
|
|
@ -415,8 +437,9 @@ decrypt_app(App, [{Key, Value} | Tail], Algo) ->
|
|||
{Value, Algo1} ->
|
||||
Algo1;
|
||||
{NewValue, Algo1} ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Value of `~s` decrypted", [Key]),
|
||||
?LOG_DEBUG(
|
||||
"Value of `~s` decrypted", [Key],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = application:set_env(App, Key, NewValue,
|
||||
[{persistent, true}]),
|
||||
Algo1
|
||||
|
|
@ -474,7 +497,8 @@ config_entry_decoder_to_algo(ConfigEntryDecoder) ->
|
|||
end.
|
||||
|
||||
get_passphrase(ConfigEntryDecoder) ->
|
||||
rabbit_log_prelaunch:debug("Getting encrypted config passphrase"),
|
||||
?LOG_DEBUG("Getting encrypted config passphrase",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case proplists:get_value(passphrase, ConfigEntryDecoder) of
|
||||
prompt ->
|
||||
IoDevice = get_input_iodevice(),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
-module(rabbit_prelaunch_dist).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup/1]).
|
||||
|
||||
setup(#{nodename := Node, nodename_type := NameType} = Context) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Erlang distribution =="),
|
||||
rabbit_log_prelaunch:debug("Rqeuested node name: ~s (type: ~s)",
|
||||
[Node, NameType]),
|
||||
?LOG_DEBUG(
|
||||
"~n== Erlang distribution ==", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
?LOG_DEBUG(
|
||||
"Rqeuested node name: ~s (type: ~s)",
|
||||
[Node, NameType],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case node() of
|
||||
nonode@nohost ->
|
||||
ok = rabbit_nodes_common:ensure_epmd(),
|
||||
|
|
@ -16,8 +23,9 @@ setup(#{nodename := Node, nodename_type := NameType} = Context) ->
|
|||
|
||||
ok = do_setup(Context);
|
||||
Node ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Erlang distribution already running", []),
|
||||
?LOG_DEBUG(
|
||||
"Erlang distribution already running", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
Unexpected ->
|
||||
throw({error, {erlang_dist_running_with_unexpected_nodename,
|
||||
|
|
@ -26,7 +34,9 @@ setup(#{nodename := Node, nodename_type := NameType} = Context) ->
|
|||
ok.
|
||||
|
||||
do_setup(#{nodename := Node, nodename_type := NameType}) ->
|
||||
rabbit_log_prelaunch:debug("Starting Erlang distribution", []),
|
||||
?LOG_DEBUG(
|
||||
"Starting Erlang distribution",
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case application:get_env(kernel, net_ticktime) of
|
||||
{ok, Ticktime} when is_integer(Ticktime) andalso Ticktime >= 1 ->
|
||||
%% The value passed to net_kernel:start/1 is the
|
||||
|
|
@ -43,8 +53,9 @@ do_setup(#{nodename := Node, nodename_type := NameType}) ->
|
|||
|
||||
%% Check whether a node with the same name is already running
|
||||
duplicate_node_check(#{split_nodename := {NodeName, NodeHost}}) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Checking if node name ~s is already used", [NodeName]),
|
||||
?LOG_DEBUG(
|
||||
"Checking if node name ~s is already used", [NodeName],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
PrelaunchName = rabbit_nodes_common:make(
|
||||
{NodeName ++ "_prelaunch_" ++ os:getpid(),
|
||||
"localhost"}),
|
||||
|
|
@ -63,8 +74,9 @@ duplicate_node_check(#{split_nodename := {NodeName, NodeHost}}) ->
|
|||
end.
|
||||
|
||||
dist_port_range_check(#{erlang_dist_tcp_port := DistTcpPort}) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Checking if TCP port ~b is valid", [DistTcpPort]),
|
||||
?LOG_DEBUG(
|
||||
"Checking if TCP port ~b is valid", [DistTcpPort],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case DistTcpPort of
|
||||
_ when DistTcpPort < 1 orelse DistTcpPort > 65535 ->
|
||||
throw({error, {invalid_dist_port_range, DistTcpPort}});
|
||||
|
|
@ -74,8 +86,9 @@ dist_port_range_check(#{erlang_dist_tcp_port := DistTcpPort}) ->
|
|||
|
||||
dist_port_use_check(#{split_nodename := {_, NodeHost},
|
||||
erlang_dist_tcp_port := DistTcpPort}) ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Checking if TCP port ~b is available", [DistTcpPort]),
|
||||
?LOG_DEBUG(
|
||||
"Checking if TCP port ~b is available", [DistTcpPort],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
dist_port_use_check_ipv4(NodeHost, DistTcpPort).
|
||||
|
||||
dist_port_use_check_ipv4(NodeHost, Port) ->
|
||||
|
|
|
|||
|
|
@ -1,60 +1,126 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2019-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_prelaunch_early_logging).
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit_log.hrl").
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-export([setup_early_logging/2,
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup_early_logging/1,
|
||||
default_formatter/1,
|
||||
default_console_formatter/1,
|
||||
default_file_formatter/1,
|
||||
default_syslog_formatter/1,
|
||||
enable_quick_dbg/1,
|
||||
use_colored_logging/0,
|
||||
use_colored_logging/1,
|
||||
list_expected_sinks/0]).
|
||||
use_colored_logging/1]).
|
||||
-export([filter_log_event/2]).
|
||||
|
||||
setup_early_logging(#{log_levels := undefined} = Context,
|
||||
LagerEventToStdout) ->
|
||||
setup_early_logging(Context#{log_levels => get_default_log_level()},
|
||||
LagerEventToStdout);
|
||||
setup_early_logging(Context, LagerEventToStdout) ->
|
||||
Configured = lists:member(
|
||||
lager_util:make_internal_sink_name(rabbit_log_prelaunch),
|
||||
lager:list_all_sinks()),
|
||||
case Configured of
|
||||
-define(CONFIGURED_KEY, {?MODULE, configured}).
|
||||
|
||||
setup_early_logging(#{log_levels := undefined} = Context) ->
|
||||
setup_early_logging(Context#{log_levels => get_default_log_level()});
|
||||
setup_early_logging(Context) ->
|
||||
case is_configured() of
|
||||
true -> ok;
|
||||
false -> do_setup_early_logging(Context, LagerEventToStdout)
|
||||
false -> do_setup_early_logging(Context)
|
||||
end.
|
||||
|
||||
get_default_log_level() ->
|
||||
#{"prelaunch" => warning}.
|
||||
#{"prelaunch" => notice}.
|
||||
|
||||
do_setup_early_logging(#{log_levels := LogLevels} = Context,
|
||||
LagerEventToStdout) ->
|
||||
redirect_logger_messages_to_lager(),
|
||||
Colored = use_colored_logging(Context),
|
||||
application:set_env(lager, colored, Colored),
|
||||
ConsoleBackend = lager_console_backend,
|
||||
case LagerEventToStdout of
|
||||
true ->
|
||||
GLogLevel = case LogLevels of
|
||||
#{global := Level} -> Level;
|
||||
_ -> warning
|
||||
end,
|
||||
_ = lager_app:start_handler(
|
||||
lager_event, ConsoleBackend, [{level, GLogLevel}]),
|
||||
ok;
|
||||
false ->
|
||||
ok
|
||||
end,
|
||||
lists:foreach(
|
||||
fun(Sink) ->
|
||||
CLogLevel = get_log_level(LogLevels, Sink),
|
||||
lager_app:configure_sink(
|
||||
Sink,
|
||||
[{handlers, [{ConsoleBackend, [{level, CLogLevel}]}]}])
|
||||
end, list_expected_sinks()),
|
||||
do_setup_early_logging(#{log_levels := LogLevels} = Context) ->
|
||||
add_rmqlog_filter(LogLevels),
|
||||
ok = logger:update_handler_config(
|
||||
default, main_handler_config(Context)).
|
||||
|
||||
is_configured() ->
|
||||
persistent_term:get(?CONFIGURED_KEY, false).
|
||||
|
||||
add_rmqlog_filter(LogLevels) ->
|
||||
add_erlang_specific_filters(LogLevels),
|
||||
FilterConfig0 = lists:foldl(
|
||||
fun
|
||||
({_, V}, FC) when is_boolean(V) -> FC;
|
||||
({K, V}, FC) when is_atom(K) -> FC#{K => V};
|
||||
({K, V}, FC) -> FC#{list_to_atom(K) => V}
|
||||
end, #{}, maps:to_list(LogLevels)),
|
||||
FilterConfig1 = case maps:is_key(global, FilterConfig0) of
|
||||
true -> FilterConfig0;
|
||||
false -> FilterConfig0#{global => ?DEFAULT_LOG_LEVEL}
|
||||
end,
|
||||
ok = logger:add_handler_filter(
|
||||
default, ?FILTER_NAME, {fun filter_log_event/2, FilterConfig1}),
|
||||
ok = logger:set_primary_config(level, all),
|
||||
ok = persistent_term:put(?CONFIGURED_KEY, true).
|
||||
|
||||
add_erlang_specific_filters(_) ->
|
||||
_ = logger:add_handler_filter(
|
||||
default, progress_reports, {fun logger_filters:progress/2, stop}),
|
||||
ok.
|
||||
|
||||
redirect_logger_messages_to_lager() ->
|
||||
io:format(standard_error, "Configuring logger redirection~n", []),
|
||||
ok = logger:add_handler(rabbit_log, rabbit_log, #{}),
|
||||
ok = logger:set_primary_config(level, all).
|
||||
filter_log_event(
|
||||
#{meta := #{domain := ?RMQLOG_DOMAIN_GLOBAL}} = LogEvent,
|
||||
FilterConfig) ->
|
||||
MinLevel = get_min_level(global, FilterConfig),
|
||||
do_filter_log_event(LogEvent, MinLevel);
|
||||
filter_log_event(
|
||||
#{meta := #{domain := [?RMQLOG_SUPER_DOMAIN_NAME, CatName | _]}} = LogEvent,
|
||||
FilterConfig) ->
|
||||
MinLevel = get_min_level(CatName, FilterConfig),
|
||||
do_filter_log_event(LogEvent, MinLevel);
|
||||
filter_log_event(
|
||||
#{meta := #{domain := [CatName | _]}} = LogEvent,
|
||||
FilterConfig) ->
|
||||
MinLevel = get_min_level(CatName, FilterConfig),
|
||||
do_filter_log_event(LogEvent, MinLevel);
|
||||
filter_log_event(LogEvent, FilterConfig) ->
|
||||
MinLevel = get_min_level(global, FilterConfig),
|
||||
do_filter_log_event(LogEvent, MinLevel).
|
||||
|
||||
get_min_level(global, FilterConfig) ->
|
||||
maps:get(global, FilterConfig, none);
|
||||
get_min_level(CatName, FilterConfig) ->
|
||||
case maps:is_key(CatName, FilterConfig) of
|
||||
true -> maps:get(CatName, FilterConfig);
|
||||
false -> get_min_level(global, FilterConfig)
|
||||
end.
|
||||
|
||||
do_filter_log_event(_, none) ->
|
||||
stop;
|
||||
do_filter_log_event(#{level := Level} = LogEvent, MinLevel) ->
|
||||
case logger:compare_levels(Level, MinLevel) of
|
||||
lt -> stop;
|
||||
_ -> LogEvent
|
||||
end.
|
||||
|
||||
main_handler_config(Context) ->
|
||||
#{filter_default => log,
|
||||
formatter => default_formatter(Context)}.
|
||||
|
||||
default_formatter(#{log_levels := #{json := true}}) ->
|
||||
{rabbit_logger_json_fmt, #{}};
|
||||
default_formatter(Context) ->
|
||||
Color = use_colored_logging(Context),
|
||||
{rabbit_logger_text_fmt, #{color => Color}}.
|
||||
|
||||
default_console_formatter(Context) ->
|
||||
default_formatter(Context).
|
||||
|
||||
default_file_formatter(Context) ->
|
||||
default_formatter(Context#{output_supports_colors => false}).
|
||||
|
||||
default_syslog_formatter(Context) ->
|
||||
{Module, Config} = default_file_formatter(Context),
|
||||
case Module of
|
||||
rabbit_logger_text_fmt -> {Module, Config#{prefix => false}};
|
||||
rabbit_logger_json_fmt -> {Module, Config}
|
||||
end.
|
||||
|
||||
use_colored_logging() ->
|
||||
use_colored_logging(rabbit_prelaunch:get_context()).
|
||||
|
|
@ -65,45 +131,6 @@ use_colored_logging(#{log_levels := #{color := true},
|
|||
use_colored_logging(_) ->
|
||||
false.
|
||||
|
||||
list_expected_sinks() ->
|
||||
Key = {?MODULE, lager_extra_sinks},
|
||||
case persistent_term:get(Key, undefined) of
|
||||
undefined ->
|
||||
CompileOptions = proplists:get_value(options,
|
||||
module_info(compile),
|
||||
[]),
|
||||
AutoList = [lager_util:make_internal_sink_name(M)
|
||||
|| M <- proplists:get_value(lager_extra_sinks,
|
||||
CompileOptions, [])],
|
||||
List = case lists:member(?LAGER_SINK, AutoList) of
|
||||
true -> AutoList;
|
||||
false -> [?LAGER_SINK | AutoList]
|
||||
end,
|
||||
%% Store the list in the application environment. If this
|
||||
%% module is later cover-compiled, the compile option will
|
||||
%% be lost, so we will be able to retrieve the list from the
|
||||
%% application environment.
|
||||
persistent_term:put(Key, List),
|
||||
List;
|
||||
List ->
|
||||
List
|
||||
end.
|
||||
|
||||
sink_to_category(Sink) when is_atom(Sink) ->
|
||||
re:replace(
|
||||
atom_to_list(Sink),
|
||||
"^rabbit_log_(.+)_lager_event$",
|
||||
"\\1",
|
||||
[{return, list}]).
|
||||
|
||||
get_log_level(LogLevels, Sink) ->
|
||||
Category = sink_to_category(Sink),
|
||||
case LogLevels of
|
||||
#{Category := Level} -> Level;
|
||||
#{global := Level} -> Level;
|
||||
_ -> warning
|
||||
end.
|
||||
|
||||
enable_quick_dbg(#{dbg_output := Output, dbg_mods := Mods}) ->
|
||||
case Output of
|
||||
stdout -> {ok, _} = dbg:tracer(),
|
||||
|
|
|
|||
|
|
@ -1,25 +1,32 @@
|
|||
-module(rabbit_prelaunch_erlang_compat).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([check/1]).
|
||||
|
||||
-define(OTP_MINIMUM, "23.0").
|
||||
-define(ERTS_MINIMUM, "11.1").
|
||||
|
||||
check(_Context) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Erlang/OTP compatibility check =="),
|
||||
?LOG_DEBUG(
|
||||
"~n== Erlang/OTP compatibility check ==", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
|
||||
ERTSVer = erlang:system_info(version),
|
||||
OTPRel = rabbit_misc:otp_release(),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Requiring: Erlang/OTP ~s (ERTS ~s)", [?OTP_MINIMUM, ?ERTS_MINIMUM]),
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Running: Erlang/OTP ~s (ERTS ~s)", [OTPRel, ERTSVer]),
|
||||
?LOG_DEBUG(
|
||||
"Requiring: Erlang/OTP ~s (ERTS ~s)~n"
|
||||
"Running: Erlang/OTP ~s (ERTS ~s)",
|
||||
[?OTP_MINIMUM, ?ERTS_MINIMUM, OTPRel, ERTSVer],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
|
||||
case rabbit_misc:version_compare(?ERTS_MINIMUM, ERTSVer, lte) of
|
||||
true when ?ERTS_MINIMUM =/= ERTSVer ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Erlang/OTP version requirement satisfied"),
|
||||
?LOG_DEBUG(
|
||||
"Erlang/OTP version requirement satisfied", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
true when ?ERTS_MINIMUM =:= ERTSVer andalso ?OTP_MINIMUM =< OTPRel ->
|
||||
%% When a critical regression or bug is found, a new OTP
|
||||
|
|
@ -35,7 +42,7 @@ check(_Context) ->
|
|||
"This RabbitMQ version cannot run on Erlang ~s (erts ~s): "
|
||||
"minimum required version is ~s (erts ~s)",
|
||||
Args = [OTPRel, ERTSVer, ?OTP_MINIMUM, ?ERTS_MINIMUM],
|
||||
rabbit_log_prelaunch:error(Msg, Args),
|
||||
?LOG_ERROR(Msg, Args, #{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
|
||||
%% Also print to stderr to make this more visible
|
||||
io:format(standard_error, "Error: " ++ Msg ++ "~n", Args),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
-module(rabbit_prelaunch_errors).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([format_error/1,
|
||||
format_exception/3,
|
||||
log_error/1,
|
||||
|
|
@ -94,9 +98,19 @@ log_exception(Class, Exception, Stacktrace) ->
|
|||
log_message(Message).
|
||||
|
||||
format_exception(Class, Exception, Stacktrace) ->
|
||||
StacktraceStrs = [case proplists:get_value(line, Props) of
|
||||
undefined ->
|
||||
io_lib:format(" ~ts:~ts/~b",
|
||||
[Mod, Fun, Arity]);
|
||||
Line ->
|
||||
io_lib:format(" ~ts:~ts/~b, line ~b",
|
||||
[Mod, Fun, Arity, Line])
|
||||
end
|
||||
|| {Mod, Fun, Arity, Props} <- Stacktrace],
|
||||
ExceptionStr = io_lib:format("~ts:~0p", [Class, Exception]),
|
||||
rabbit_misc:format(
|
||||
"Exception during startup:~n~s",
|
||||
[lager:pr_stacktrace(Stacktrace, {Class, Exception})]).
|
||||
"Exception during startup:~n~n~s~n~n~s",
|
||||
[ExceptionStr, string:join(StacktraceStrs, "\n")]).
|
||||
|
||||
log_message(Message) ->
|
||||
Lines = string:split(
|
||||
|
|
@ -105,9 +119,11 @@ log_message(Message) ->
|
|||
?BOOT_FAILED_FOOTER,
|
||||
[$\n],
|
||||
all),
|
||||
?LOG_ERROR(
|
||||
"~s", [string:join(Lines, "\n")],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
lists:foreach(
|
||||
fun(Line) ->
|
||||
rabbit_log_prelaunch:error("~s", [Line]),
|
||||
io:format(standard_error, "~s~n", [Line])
|
||||
end, Lines),
|
||||
timer:sleep(1000),
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@ handle_event(Signal, State) ->
|
|||
%% which should stop RabbitMQ.
|
||||
%
|
||||
%#{Signal := stop} ->
|
||||
% error_logger:info_msg(
|
||||
% "~s received - shutting down~n",
|
||||
% logger:info(
|
||||
% "~s received - shutting down",
|
||||
% [string:uppercase(atom_to_list(Signal))]),
|
||||
% ok = init:stop();
|
||||
_ ->
|
||||
error_logger:info_msg(
|
||||
"~s received - unhandled signal~n",
|
||||
logger:info(
|
||||
"~s received - unhandled signal",
|
||||
[string:uppercase(atom_to_list(Signal))])
|
||||
end,
|
||||
{ok, State}.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,212 @@
|
|||
-module(rabbit_logger_std_h_SUITE).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-export([all/0,
|
||||
groups/0,
|
||||
init_per_suite/2,
|
||||
end_per_suite/2,
|
||||
init_per_group/2,
|
||||
end_per_group/2,
|
||||
init_per_testcase/2,
|
||||
end_per_testcase/2,
|
||||
|
||||
every_day_rotation_is_detected/1,
|
||||
every_week_rotation_is_detected/1,
|
||||
every_month_rotation_is_detected/1
|
||||
]).
|
||||
|
||||
all() ->
|
||||
[
|
||||
{group, parallel_tests}
|
||||
].
|
||||
|
||||
groups() ->
|
||||
[
|
||||
{parallel_tests, [parallel], [every_day_rotation_is_detected,
|
||||
every_week_rotation_is_detected,
|
||||
every_month_rotation_is_detected]}
|
||||
].
|
||||
|
||||
init_per_suite(_, Config) -> Config.
|
||||
end_per_suite(_, Config) -> Config.
|
||||
|
||||
init_per_group(_, Config) -> Config.
|
||||
end_per_group(_, Config) -> Config.
|
||||
|
||||
init_per_testcase(_, Config) -> Config.
|
||||
end_per_testcase(_, Config) -> Config.
|
||||
|
||||
every_day_rotation_is_detected(_) ->
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 15}, {10, 00, 00}},
|
||||
{{2021, 01, 15}, {11, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 15}, {10, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 15}, {10, 00, 00}},
|
||||
{{2021, 01, 15}, {13, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 15}, {11, 00, 00}},
|
||||
{{2021, 01, 15}, {13, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 15}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {13, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 14}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2021, 01, 14}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {11, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2020, 11, 15}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {11, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => day, hour => 12},
|
||||
{{2020, 11, 15}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})).
|
||||
|
||||
every_week_rotation_is_detected(_) ->
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 11}, {12, 00, 00}},
|
||||
{{2021, 01, 12}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 11}, {12, 00, 00}},
|
||||
{{2021, 01, 13}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 11}, {12, 00, 00}},
|
||||
{{2021, 01, 14}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 13}, {12, 00, 00}},
|
||||
{{2021, 01, 14}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 14}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 13}, {11, 00, 00}},
|
||||
{{2021, 01, 13}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 06}, {12, 00, 00}},
|
||||
{{2021, 01, 13}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 07}, {12, 00, 00}},
|
||||
{{2021, 01, 14}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 06}, {12, 00, 00}},
|
||||
{{2021, 01, 12}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 06}, {11, 00, 00}},
|
||||
{{2021, 01, 12}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => week, day_of_week => 3, hour => 12},
|
||||
{{2021, 01, 06}, {12, 00, 00}},
|
||||
{{2021, 01, 13}, {11, 00, 00}})).
|
||||
|
||||
every_month_rotation_is_detected(_) ->
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 15}, {10, 00, 00}},
|
||||
{{2021, 01, 15}, {11, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 15}, {10, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 13}, {12, 00, 00}},
|
||||
{{2021, 01, 14}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 14}, {12, 00, 00}},
|
||||
{{2021, 01, 15}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 15}, {12, 00, 00}},
|
||||
{{2021, 01, 16}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 14}, {12, 00, 00}},
|
||||
{{2021, 02, 14}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 15, hour => 12},
|
||||
{{2021, 01, 16}, {12, 00, 00}},
|
||||
{{2021, 02, 16}, {12, 00, 00}})),
|
||||
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 30, hour => 12},
|
||||
{{2021, 01, 29}, {12, 00, 00}},
|
||||
{{2021, 01, 30}, {12, 00, 00}})),
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 30, hour => 12},
|
||||
{{2021, 01, 30}, {12, 00, 00}},
|
||||
{{2021, 01, 31}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => 30, hour => 12},
|
||||
{{2021, 02, 27}, {12, 00, 00}},
|
||||
{{2021, 02, 28}, {12, 00, 00}})),
|
||||
|
||||
?assertNot(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => last, hour => 12},
|
||||
{{2021, 01, 29}, {12, 00, 00}},
|
||||
{{2021, 01, 30}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => last, hour => 12},
|
||||
{{2021, 01, 30}, {12, 00, 00}},
|
||||
{{2021, 01, 31}, {12, 00, 00}})),
|
||||
?assert(
|
||||
rabbit_logger_std_h:is_date_based_rotation_needed(
|
||||
#{every => month, day_of_month => last, hour => 12},
|
||||
{{2021, 01, 30}, {12, 00, 00}},
|
||||
{{2021, 02, 01}, {12, 00, 00}})).
|
||||
|
|
@ -883,7 +883,7 @@
|
|||
|
||||
## Logging settings.
|
||||
##
|
||||
## See https://rabbitmq.com/logging.html and https://github.com/erlang-lager/lager for details.
|
||||
## See https://rabbitmq.com/logging.html for details.
|
||||
##
|
||||
|
||||
## Log directory, taken from the RABBITMQ_LOG_BASE env variable by default.
|
||||
|
|
|
|||
|
|
@ -146,25 +146,6 @@ For example, to reset the RabbitMQ node:
|
|||
.sp
|
||||
.Dl rabbitmqctl reset
|
||||
.\" ------------------------------------------------------------------
|
||||
.It Cm rotate_logs
|
||||
.Pp
|
||||
Instructs the RabbitMQ node to perform internal log rotation.
|
||||
.Pp
|
||||
Log rotation is performed according to lager settings specified in
|
||||
configuration file.
|
||||
.Pp
|
||||
Note that there is no need to call this command in case of external log
|
||||
rotation (e.g. from logrotate(8)), because lager detects renames and
|
||||
automatically reopens log files.
|
||||
.Pp
|
||||
For example, this command starts internal log rotation
|
||||
process:
|
||||
.sp
|
||||
.Dl rabbitmqctl rotate_logs
|
||||
.Pp
|
||||
Rotation is performed asynchronously, so there is no guarantee that it
|
||||
will be completed when this command returns.
|
||||
.\" ------------------------------------------------------------------
|
||||
.It Cm shutdown
|
||||
.Pp
|
||||
Shuts down the node, both RabbitMQ and its runtime.
|
||||
|
|
|
|||
|
|
@ -1179,10 +1179,10 @@ end}.
|
|||
]}.
|
||||
|
||||
% ==========================
|
||||
% Lager section
|
||||
% Logging section
|
||||
% ==========================
|
||||
|
||||
{mapping, "log.dir", "lager.log_root", [
|
||||
{mapping, "log.dir", "rabbit.log_root", [
|
||||
{datatype, string},
|
||||
{validators, ["dir_writable"]}]}.
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ dep_accept = hex 0.3.5
|
|||
dep_cowboy = hex 2.8.0
|
||||
dep_cowlib = hex 2.9.1
|
||||
dep_jsx = hex 2.11.0
|
||||
dep_lager = hex 3.9.1
|
||||
dep_prometheus = git https://github.com/deadtrickster/prometheus.erl.git master
|
||||
dep_ra = git https://github.com/rabbitmq/ra.git master
|
||||
dep_ranch = hex 2.0.0
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ start_rabbitmq_server() {
|
|||
${RABBITMQ_SERVER_ERL_ARGS} \
|
||||
${RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS} \
|
||||
${RABBITMQ_SERVER_START_ARGS} \
|
||||
-lager crash_log false \
|
||||
-lager handlers '[]' \
|
||||
-syslog logger '[]' \
|
||||
-syslog syslog_error_logger false \
|
||||
"$@"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ if "!RABBITMQ_ALLOW_INPUT!"=="" (
|
|||
!RABBITMQ_SERVER_ERL_ARGS! ^
|
||||
!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^
|
||||
!RABBITMQ_SERVER_START_ARGS! ^
|
||||
-lager crash_log false ^
|
||||
-lager handlers "[]" ^
|
||||
-syslog logger [] ^
|
||||
-syslog syslog_error_logger false ^
|
||||
!STAR!
|
||||
|
||||
if ERRORLEVEL 1 (
|
||||
|
|
|
|||
|
|
@ -198,8 +198,8 @@ set ERLANG_SERVICE_ARGUMENTS= ^
|
|||
!RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS! ^
|
||||
!RABBITMQ_SERVER_START_ARGS! ^
|
||||
!RABBITMQ_DIST_ARG! ^
|
||||
-lager crash_log false ^
|
||||
-lager handlers "[]" ^
|
||||
-syslog logger [] ^
|
||||
-syslog syslog_error_logger false ^
|
||||
!STARVAR!
|
||||
|
||||
set ERLANG_SERVICE_ARGUMENTS=!ERLANG_SERVICE_ARGUMENTS:\=\\!
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ handle_maybe_call_mfa(true, {Module, Function, Args, Default}, State) ->
|
|||
error:undef ->
|
||||
handle_maybe_call_mfa_error(Module, Default, State);
|
||||
Err:Reason ->
|
||||
rabbit_log:error("Calling ~p:~p failed: ~p:~p~n",
|
||||
rabbit_log:error("Calling ~p:~p failed: ~p:~p",
|
||||
[Module, Function, Err, Reason]),
|
||||
handle_maybe_call_mfa_error(Module, Default, State)
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -1,233 +0,0 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc RabbitMQ backend for lager.
|
||||
%% Configuration is a proplist with the following keys:
|
||||
%% <ul>
|
||||
%% <li>`level' - log level to use</li>
|
||||
%% <li>`formatter' - the module to use when formatting log messages. Defaults to
|
||||
%% `lager_default_formatter'</li>
|
||||
%% <li>`formatter_config' - the format configuration string. Defaults to
|
||||
%% `time [ severity ] message'</li>
|
||||
%% </ul>
|
||||
|
||||
-module(lager_exchange_backend).
|
||||
|
||||
-behaviour(gen_event).
|
||||
|
||||
-export([init/1, terminate/2, code_change/3,
|
||||
handle_call/2, handle_event/2, handle_info/2]).
|
||||
|
||||
-export([maybe_init_exchange/0]).
|
||||
|
||||
-include("rabbit.hrl").
|
||||
-include("rabbit_framing.hrl").
|
||||
|
||||
-include_lib("lager/include/lager.hrl").
|
||||
|
||||
-record(state, {level :: {'mask', integer()},
|
||||
formatter :: atom(),
|
||||
format_config :: any(),
|
||||
init_exchange_ts = undefined :: integer() | undefined,
|
||||
exchange = undefined :: #resource{} | undefined}).
|
||||
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-compile([{parse_transform, lager_transform}]).
|
||||
-endif.
|
||||
|
||||
-define(INIT_EXCHANGE_INTERVAL_SECS, 5).
|
||||
-define(TERSE_FORMAT, [time, " [", severity, "] ", message]).
|
||||
-define(DEFAULT_FORMAT_CONFIG, ?TERSE_FORMAT).
|
||||
-define(FORMAT_CONFIG_OFF, []).
|
||||
|
||||
-ifdef(TEST).
|
||||
-define(DEPRECATED(_Msg), ok).
|
||||
-else.
|
||||
-define(DEPRECATED(Msg),
|
||||
io:format(user, "WARNING: This is a deprecated lager_exchange_backend configuration. Please use \"~w\" instead.~n", [Msg])).
|
||||
-endif.
|
||||
|
||||
-define(LOG_EXCH_NAME, <<"amq.rabbitmq.log">>).
|
||||
|
||||
init([Level]) when is_atom(Level) ->
|
||||
?DEPRECATED([{level, Level}]),
|
||||
init([{level, Level}]);
|
||||
init([Level, true]) when is_atom(Level) -> % for backwards compatibility
|
||||
?DEPRECATED([{level, Level}, {formatter_config, [{eol, "\\r\\n\\"}]}]),
|
||||
init([{level, Level}, {formatter_config, ?FORMAT_CONFIG_OFF}]);
|
||||
init([Level, false]) when is_atom(Level) -> % for backwards compatibility
|
||||
?DEPRECATED([{level, Level}]),
|
||||
init([{level, Level}]);
|
||||
|
||||
init(Options) when is_list(Options) ->
|
||||
true = validate_options(Options),
|
||||
Level = get_option(level, Options, undefined),
|
||||
try lager_util:config_to_mask(Level) of
|
||||
L ->
|
||||
DefaultOptions = [{formatter, lager_default_formatter},
|
||||
{formatter_config, ?DEFAULT_FORMAT_CONFIG}],
|
||||
[Formatter, Config] = [get_option(K, Options, Default) || {K, Default} <- DefaultOptions],
|
||||
State0 = #state{level=L,
|
||||
formatter=Formatter,
|
||||
format_config=Config},
|
||||
% NB: this will probably always fail since the / vhost isn't available
|
||||
State1 = maybe_init_exchange(State0),
|
||||
{ok, State1}
|
||||
catch
|
||||
_:_ ->
|
||||
{error, {fatal, bad_log_level}}
|
||||
end;
|
||||
init(Level) when is_atom(Level) ->
|
||||
?DEPRECATED([{level, Level}]),
|
||||
init([{level, Level}]);
|
||||
init(Other) ->
|
||||
{error, {fatal, {bad_lager_exchange_backend_config, Other}}}.
|
||||
|
||||
% rabbitmq/rabbitmq-server#1973
|
||||
% This is called immediatly after the / vhost is created
|
||||
% or recovered
|
||||
maybe_init_exchange() ->
|
||||
case lists:member(?MODULE, gen_event:which_handlers(lager_event)) of
|
||||
true ->
|
||||
_ = init_exchange(true),
|
||||
ok;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
validate_options([]) -> true;
|
||||
validate_options([{level, L}|T]) when is_atom(L) ->
|
||||
case lists:member(L, ?LEVELS) of
|
||||
false ->
|
||||
throw({error, {fatal, {bad_level, L}}});
|
||||
true ->
|
||||
validate_options(T)
|
||||
end;
|
||||
validate_options([{formatter, M}|T]) when is_atom(M) ->
|
||||
validate_options(T);
|
||||
validate_options([{formatter_config, C}|T]) when is_list(C) ->
|
||||
validate_options(T);
|
||||
validate_options([H|_]) ->
|
||||
throw({error, {fatal, {bad_lager_exchange_backend_config, H}}}).
|
||||
|
||||
get_option(K, Options, Default) ->
|
||||
case lists:keyfind(K, 1, Options) of
|
||||
{K, V} -> V;
|
||||
false -> Default
|
||||
end.
|
||||
|
||||
handle_call(get_loglevel, #state{level=Level} = State) ->
|
||||
{ok, Level, State};
|
||||
handle_call({set_loglevel, Level}, State) ->
|
||||
try lager_util:config_to_mask(Level) of
|
||||
Levels ->
|
||||
{ok, ok, State#state{level=Levels}}
|
||||
catch
|
||||
_:_ ->
|
||||
{ok, {error, bad_log_level}, State}
|
||||
end;
|
||||
handle_call(_Request, State) ->
|
||||
{ok, ok, State}.
|
||||
|
||||
handle_event({log, _Message} = Event, State0) ->
|
||||
State1 = maybe_init_exchange(State0),
|
||||
handle_log_event(Event, State1);
|
||||
handle_event(_Event, State) ->
|
||||
{ok, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{ok, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%% @private
|
||||
handle_log_event({log, _Message}, #state{exchange=undefined} = State) ->
|
||||
% NB: tried to define the exchange but still undefined,
|
||||
% so not logging this message. Note: we can't log this dropped
|
||||
% message because it will start an infinite loop
|
||||
{ok, State};
|
||||
handle_log_event({log, Message},
|
||||
#state{level=L, exchange=LogExch,
|
||||
formatter=Formatter, format_config=FormatConfig} = State) ->
|
||||
case lager_util:is_loggable(Message, L, ?MODULE) of
|
||||
true ->
|
||||
%% 0-9-1 says the timestamp is a "64 bit POSIX timestamp". That's
|
||||
%% second resolution, not millisecond.
|
||||
RoutingKey = rabbit_data_coercion:to_binary(lager_msg:severity(Message)),
|
||||
Timestamp = os:system_time(seconds),
|
||||
Node = rabbit_data_coercion:to_binary(node()),
|
||||
Headers = [{<<"node">>, longstr, Node}],
|
||||
AmqpMsg = #'P_basic'{content_type = <<"text/plain">>,
|
||||
timestamp = Timestamp,
|
||||
headers = Headers},
|
||||
Body = rabbit_data_coercion:to_binary(Formatter:format(Message, FormatConfig)),
|
||||
case rabbit_basic:publish(LogExch, RoutingKey, AmqpMsg, Body) of
|
||||
ok -> ok;
|
||||
{error, not_found} -> ok
|
||||
end,
|
||||
{ok, State};
|
||||
false ->
|
||||
{ok, State}
|
||||
end.
|
||||
|
||||
%% @private
|
||||
maybe_init_exchange(#state{exchange=undefined, init_exchange_ts=undefined} = State) ->
|
||||
Now = erlang:monotonic_time(second),
|
||||
handle_init_exchange(init_exchange(true), Now, State);
|
||||
maybe_init_exchange(#state{exchange=undefined, init_exchange_ts=Timestamp} = State) ->
|
||||
Now = erlang:monotonic_time(second),
|
||||
% NB: since we may try to declare the exchange on every log message, this ensures
|
||||
% that we only try once every 5 seconds
|
||||
HasEnoughTimeElapsed = Now - Timestamp > ?INIT_EXCHANGE_INTERVAL_SECS,
|
||||
Result = init_exchange(HasEnoughTimeElapsed),
|
||||
handle_init_exchange(Result, Now, State);
|
||||
maybe_init_exchange(State) ->
|
||||
State.
|
||||
|
||||
%% @private
|
||||
init_exchange(true) ->
|
||||
{ok, DefaultVHost} = application:get_env(rabbit, default_vhost),
|
||||
Exchange = rabbit_misc:r(DefaultVHost, exchange, ?LOG_EXCH_NAME),
|
||||
try
|
||||
%% durable
|
||||
#exchange{} = rabbit_exchange:declare(Exchange, topic, true, false, true, [], ?INTERNAL_USER),
|
||||
rabbit_log:info("Declared exchange '~s' in vhost '~s'", [?LOG_EXCH_NAME, DefaultVHost]),
|
||||
{ok, Exchange}
|
||||
catch
|
||||
ErrType:Err ->
|
||||
rabbit_log:error("Could not declare exchange '~s' in vhost '~s', reason: ~p:~p",
|
||||
[?LOG_EXCH_NAME, DefaultVHost, ErrType, Err]),
|
||||
{ok, undefined}
|
||||
end;
|
||||
init_exchange(_) ->
|
||||
{ok, undefined}.
|
||||
|
||||
%% @private
|
||||
handle_init_exchange({ok, undefined}, Now, State) ->
|
||||
State#state{init_exchange_ts=Now};
|
||||
handle_init_exchange({ok, Exchange}, Now, State) ->
|
||||
State#state{exchange=Exchange, init_exchange_ts=Now}.
|
||||
|
||||
-ifdef(TEST).
|
||||
console_config_validation_test_() ->
|
||||
Good = [{level, info}],
|
||||
Bad1 = [{level, foo}],
|
||||
Bad2 = [{larval, info}],
|
||||
AllGood = [{level, info}, {formatter, my_formatter},
|
||||
{formatter_config, ["blort", "garbage"]}],
|
||||
[
|
||||
?_assertEqual(true, validate_options(Good)),
|
||||
?_assertThrow({error, {fatal, {bad_level, foo}}}, validate_options(Bad1)),
|
||||
?_assertThrow({error, {fatal, {bad_lager_exchange_backend_config, {larval, info}}}}, validate_options(Bad2)),
|
||||
?_assertEqual(true, validate_options(AllGood))
|
||||
].
|
||||
-endif.
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
-module(rabbit).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
%% Transitional step until we can require Erlang/OTP 21 and
|
||||
%% use the now recommended try/catch syntax for obtaining the stack trace.
|
||||
-compile(nowarn_deprecated_function).
|
||||
|
|
@ -28,7 +31,8 @@
|
|||
base_product_version/0,
|
||||
motd_file/0,
|
||||
motd/0]).
|
||||
-export([log_locations/0, config_files/0]). %% for testing and mgmt-agent
|
||||
%% For CLI, testing and mgmt-agent.
|
||||
-export([set_log_level/1, log_locations/0, config_files/0]).
|
||||
-export([is_booted/1, is_booted/0, is_booting/1, is_booting/0]).
|
||||
|
||||
%%---------------------------------------------------------------------------
|
||||
|
|
@ -261,7 +265,7 @@
|
|||
|
||||
-rabbit_boot_step({networking,
|
||||
[{description, "TCP and TLS listeners (backwards compatibility)"},
|
||||
{mfa, {rabbit_log, debug, ["'networking' boot step skipped and moved to end of startup", []]}},
|
||||
{mfa, {logger, debug, ["'networking' boot step skipped and moved to end of startup", [], #{domain => ?RMQLOG_DOMAIN_GLOBAL}]}},
|
||||
{requires, notify_cluster}]}).
|
||||
|
||||
%%---------------------------------------------------------------------------
|
||||
|
|
@ -335,12 +339,12 @@ run_prelaunch_second_phase() ->
|
|||
|
||||
case IsInitialPass of
|
||||
true ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG(
|
||||
"== Prelaunch phase [2/2] (initial pass) ==");
|
||||
false ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Prelaunch phase [2/2] =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Prelaunch phase [2/2] =="),
|
||||
ok
|
||||
end,
|
||||
|
||||
|
|
@ -357,11 +361,11 @@ run_prelaunch_second_phase() ->
|
|||
ok = rabbit_prelaunch_cluster:setup(Context),
|
||||
|
||||
%% Start Mnesia now that everything is ready.
|
||||
rabbit_log_prelaunch:debug("Starting Mnesia"),
|
||||
?LOG_DEBUG("Starting Mnesia"),
|
||||
ok = mnesia:start(),
|
||||
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Prelaunch DONE =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Prelaunch DONE =="),
|
||||
|
||||
case IsInitialPass of
|
||||
true -> rabbit_prelaunch:initial_pass_finished();
|
||||
|
|
@ -373,7 +377,8 @@ start_it(StartType) ->
|
|||
case spawn_boot_marker() of
|
||||
{ok, Marker} ->
|
||||
T0 = erlang:timestamp(),
|
||||
rabbit_log:info("RabbitMQ is asked to start...", []),
|
||||
?LOG_INFO("RabbitMQ is asked to start...", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
try
|
||||
{ok, _} = application:ensure_all_started(rabbitmq_prelaunch,
|
||||
StartType),
|
||||
|
|
@ -382,7 +387,7 @@ start_it(StartType) ->
|
|||
ok = wait_for_ready_or_stopped(),
|
||||
|
||||
T1 = erlang:timestamp(),
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Time to start RabbitMQ: ~p µs",
|
||||
[timer:now_diff(T1, T0)]),
|
||||
stop_boot_marker(Marker),
|
||||
|
|
@ -433,11 +438,13 @@ stop() ->
|
|||
case rabbit_boot_state:get() of
|
||||
ready ->
|
||||
Product = product_name(),
|
||||
rabbit_log:info("~s is asked to stop...", [Product]),
|
||||
?LOG_INFO("~s is asked to stop...", [Product],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
do_stop(),
|
||||
rabbit_log:info(
|
||||
?LOG_INFO(
|
||||
"Successfully stopped ~s and its dependencies",
|
||||
[Product]),
|
||||
[Product],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
stopped ->
|
||||
ok
|
||||
|
|
@ -461,19 +468,22 @@ stop_and_halt() ->
|
|||
try
|
||||
stop()
|
||||
catch Type:Reason ->
|
||||
rabbit_log:error(
|
||||
?LOG_ERROR(
|
||||
"Error trying to stop ~s: ~p:~p",
|
||||
[product_name(), Type, Reason]),
|
||||
[product_name(), Type, Reason],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
error({Type, Reason})
|
||||
after
|
||||
%% Enclose all the logging in the try block.
|
||||
%% init:stop() will be called regardless of any errors.
|
||||
try
|
||||
AppsLeft = [ A || {A, _, _} <- application:which_applications() ],
|
||||
rabbit_log:info(
|
||||
lists:flatten(["Halting Erlang VM with the following applications:~n",
|
||||
[" ~p~n" || _ <- AppsLeft]]),
|
||||
AppsLeft),
|
||||
?LOG_ERROR(
|
||||
lists:flatten(
|
||||
["Halting Erlang VM with the following applications:~n",
|
||||
[" ~p~n" || _ <- AppsLeft]]),
|
||||
AppsLeft,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
%% Also duplicate this information to stderr, so console where
|
||||
%% foreground broker was running (or systemd journal) will
|
||||
%% contain information about graceful termination.
|
||||
|
|
@ -518,10 +528,12 @@ start_apps(Apps, RestartTypes) ->
|
|||
stop_apps([]) ->
|
||||
ok;
|
||||
stop_apps(Apps) ->
|
||||
rabbit_log:info(
|
||||
lists:flatten(["Stopping ~s applications and their dependencies in the following order:~n",
|
||||
[" ~p~n" || _ <- Apps]]),
|
||||
[product_name() | lists:reverse(Apps)]),
|
||||
?LOG_INFO(
|
||||
lists:flatten(
|
||||
["Stopping ~s applications and their dependencies in the following order:~n",
|
||||
[" ~p~n" || _ <- Apps]]),
|
||||
[product_name() | lists:reverse(Apps)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = app_utils:stop_applications(
|
||||
Apps, handle_app_error(error_during_shutdown)),
|
||||
case lists:member(rabbit, Apps) of
|
||||
|
|
@ -785,28 +797,10 @@ environment(App) ->
|
|||
-spec rotate_logs() -> rabbit_types:ok_or_error(any()).
|
||||
|
||||
rotate_logs() ->
|
||||
rabbit_lager:fold_sinks(
|
||||
fun
|
||||
(_, [], Acc) ->
|
||||
Acc;
|
||||
(SinkName, FileNames, Acc) ->
|
||||
lager:log(SinkName, info, self(),
|
||||
"Log file rotation forced", []),
|
||||
%% FIXME: We use an internal message, understood by
|
||||
%% lager_file_backend. We should use a proper API, when
|
||||
%% it's added to Lager.
|
||||
%%
|
||||
%% FIXME: This call is effectively asynchronous: at the
|
||||
%% end of this function, we can't guaranty the rotation
|
||||
%% is completed.
|
||||
[ok = gen_event:call(SinkName,
|
||||
{lager_file_backend, FileName},
|
||||
rotate,
|
||||
infinity) || FileName <- FileNames],
|
||||
lager:log(SinkName, info, self(),
|
||||
"Log file re-opened after forced rotation", []),
|
||||
Acc
|
||||
end, ok).
|
||||
?LOG_ERROR(
|
||||
"Forcing log rotation is currently unsupported",
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
{error, unsupported}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
|
|
@ -835,14 +829,18 @@ start(normal, []) ->
|
|||
#{product_overridden := true,
|
||||
product_base_name := BaseName,
|
||||
product_base_version := BaseVersion} ->
|
||||
rabbit_log:info("~n Starting ~s ~s on Erlang ~s~n Based on ~s ~s~n ~s~n ~s~n",
|
||||
[product_name(), product_version(), rabbit_misc:otp_release(),
|
||||
BaseName, BaseVersion,
|
||||
?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE]);
|
||||
?LOG_INFO(
|
||||
"~n Starting ~s ~s on Erlang ~s~n Based on ~s ~s~n ~s~n ~s",
|
||||
[product_name(), product_version(), rabbit_misc:otp_release(),
|
||||
BaseName, BaseVersion,
|
||||
?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH});
|
||||
_ ->
|
||||
rabbit_log:info("~n Starting ~s ~s on Erlang ~s~n ~s~n ~s~n",
|
||||
[product_name(), product_version(), rabbit_misc:otp_release(),
|
||||
?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE])
|
||||
?LOG_INFO(
|
||||
"~n Starting ~s ~s on Erlang ~s~n ~s~n ~s",
|
||||
[product_name(), product_version(), rabbit_misc:otp_release(),
|
||||
?COPYRIGHT_MESSAGE, ?INFORMATION_MESSAGE],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end,
|
||||
log_motd(),
|
||||
{ok, SupPid} = rabbit_sup:start_link(),
|
||||
|
|
@ -860,7 +858,7 @@ start(normal, []) ->
|
|||
%%
|
||||
%% Note that plugins were not taken care of at this point
|
||||
%% either.
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Register `rabbit` process (~p) for rabbit_node_monitor",
|
||||
[self()]),
|
||||
true = register(rabbit, self()),
|
||||
|
|
@ -870,15 +868,15 @@ start(normal, []) ->
|
|||
warn_if_kernel_config_dubious(),
|
||||
warn_if_disc_io_options_dubious(),
|
||||
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Plugins (prelaunch phase) =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Plugins (prelaunch phase) =="),
|
||||
|
||||
rabbit_log_prelaunch:debug("Setting plugins up"),
|
||||
?LOG_DEBUG("Setting plugins up"),
|
||||
%% `Plugins` contains all the enabled plugins, plus their
|
||||
%% dependencies. The order is important: dependencies appear
|
||||
%% before plugin which depend on them.
|
||||
Plugins = rabbit_plugins:setup(),
|
||||
rabbit_log_prelaunch:debug(
|
||||
?LOG_DEBUG(
|
||||
"Loading the following plugins: ~p", [Plugins]),
|
||||
%% We can load all plugins and refresh their feature flags at
|
||||
%% once, because it does not involve running code from the
|
||||
|
|
@ -887,8 +885,8 @@ start(normal, []) ->
|
|||
ok = rabbit_feature_flags:refresh_feature_flags_after_app_load(
|
||||
Plugins),
|
||||
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Boot steps =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Boot steps =="),
|
||||
|
||||
ok = rabbit_boot_steps:run_boot_steps([rabbit | Plugins]),
|
||||
run_postlaunch_phase(Plugins),
|
||||
|
|
@ -917,23 +915,22 @@ run_postlaunch_phase(Plugins) ->
|
|||
do_run_postlaunch_phase(Plugins) ->
|
||||
%% Once RabbitMQ itself is started, we need to run a few more steps,
|
||||
%% in particular start plugins.
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Postlaunch phase =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Postlaunch phase =="),
|
||||
|
||||
try
|
||||
%% Successful boot resets node maintenance state.
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:info("Resetting node maintenance status"),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_INFO("Resetting node maintenance status"),
|
||||
_ = rabbit_maintenance:unmark_as_being_drained(),
|
||||
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Plugins (postlaunch phase) =="),
|
||||
?LOG_DEBUG(""),
|
||||
?LOG_DEBUG("== Plugins (postlaunch phase) =="),
|
||||
|
||||
%% However, we want to run their boot steps and actually start
|
||||
%% them one by one, to ensure a dependency is fully started
|
||||
%% before a plugin which depends on it gets a chance to start.
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Starting the following plugins: ~p", [Plugins]),
|
||||
?LOG_DEBUG("Starting the following plugins: ~p", [Plugins]),
|
||||
lists:foreach(
|
||||
fun(Plugin) ->
|
||||
case application:ensure_all_started(Plugin) of
|
||||
|
|
@ -951,18 +948,16 @@ do_run_postlaunch_phase(Plugins) ->
|
|||
|
||||
%% Start listeners after all plugins have been enabled,
|
||||
%% see rabbitmq/rabbitmq-server#2405.
|
||||
rabbit_log_prelaunch:info(
|
||||
"Ready to start client connection listeners"),
|
||||
?LOG_INFO("Ready to start client connection listeners"),
|
||||
ok = rabbit_networking:boot(),
|
||||
|
||||
%% The node is ready: mark it as such and log it.
|
||||
%% NOTE: PLEASE DO NOT ADD CRITICAL NODE STARTUP CODE AFTER THIS.
|
||||
ok = rabbit_lager:broker_is_started(),
|
||||
ActivePlugins = rabbit_plugins:active(),
|
||||
StrictlyPlugins = rabbit_plugins:strictly_plugins(ActivePlugins),
|
||||
ok = log_broker_started(StrictlyPlugins),
|
||||
|
||||
rabbit_log_prelaunch:debug("Marking ~s as running", [product_name()]),
|
||||
?LOG_DEBUG("Marking ~s as running", [product_name()]),
|
||||
rabbit_boot_state:set(ready)
|
||||
catch
|
||||
throw:{error, _} = Error ->
|
||||
|
|
@ -1011,7 +1006,7 @@ boot_delegate() ->
|
|||
recover() ->
|
||||
ok = rabbit_policy:recover(),
|
||||
ok = rabbit_vhost:recover(),
|
||||
ok = lager_exchange_backend:maybe_init_exchange().
|
||||
ok.
|
||||
|
||||
-spec maybe_insert_default_data() -> 'ok'.
|
||||
|
||||
|
|
@ -1019,10 +1014,12 @@ maybe_insert_default_data() ->
|
|||
NoDefsToImport = not rabbit_definitions:has_configured_definitions_to_load(),
|
||||
case rabbit_table:needs_default_data() andalso NoDefsToImport of
|
||||
true ->
|
||||
rabbit_log:info("Will seed default virtual host and user..."),
|
||||
?LOG_INFO("Will seed default virtual host and user...",
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
insert_default_data();
|
||||
false ->
|
||||
rabbit_log:info("Will not seed default virtual host and user: have definitions to load..."),
|
||||
?LOG_INFO("Will not seed default virtual host and user: have definitions to load...",
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
ok
|
||||
end.
|
||||
|
||||
|
|
@ -1042,7 +1039,6 @@ insert_default_data() ->
|
|||
DefaultReadPermBin = rabbit_data_coercion:to_binary(DefaultReadPerm),
|
||||
|
||||
ok = rabbit_vhost:add(DefaultVHostBin, <<"Default virtual host">>, [], ?INTERNAL_USER),
|
||||
ok = lager_exchange_backend:maybe_init_exchange(),
|
||||
ok = rabbit_auth_backend_internal:add_user(
|
||||
DefaultUserBin,
|
||||
DefaultPassBin,
|
||||
|
|
@ -1061,9 +1057,13 @@ insert_default_data() ->
|
|||
%%---------------------------------------------------------------------------
|
||||
%% logging
|
||||
|
||||
-spec log_locations() -> [rabbit_lager:log_location()].
|
||||
-spec set_log_level(logger:level()) -> ok.
|
||||
set_log_level(Level) ->
|
||||
rabbit_prelaunch_logging:set_log_level(Level).
|
||||
|
||||
-spec log_locations() -> [rabbit_prelaunch_logging:log_location()].
|
||||
log_locations() ->
|
||||
rabbit_lager:log_locations().
|
||||
rabbit_prelaunch_logging:log_locations().
|
||||
|
||||
-spec config_locations() -> [rabbit_config:config_location()].
|
||||
config_locations() ->
|
||||
|
|
@ -1094,7 +1094,8 @@ log_broker_started(Plugins) ->
|
|||
Message = string:strip(rabbit_misc:format(
|
||||
"Server startup complete; ~b plugins started.~n~s",
|
||||
[length(Plugins), PluginList]), right, $\n),
|
||||
rabbit_log:info(Message),
|
||||
?LOG_INFO(Message,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
io:format(" completed with ~p plugins.~n", [length(Plugins)]).
|
||||
|
||||
-define(RABBIT_TEXT_LOGO,
|
||||
|
|
@ -1185,7 +1186,8 @@ log_motd() ->
|
|||
_ -> [" ", Line, "\n"]
|
||||
end
|
||||
|| Line <- Lines],
|
||||
rabbit_log:info("~n~ts", [string:trim(Padded, trailing, [$\r, $\n])])
|
||||
?LOG_INFO("~n~ts", [string:trim(Padded, trailing, [$\r, $\n])],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})
|
||||
end.
|
||||
|
||||
log_banner() ->
|
||||
|
|
@ -1216,7 +1218,8 @@ log_banner() ->
|
|||
{K, V} ->
|
||||
Format(K, V)
|
||||
end || S <- Settings]), right, $\n),
|
||||
rabbit_log:info("~n~ts", [Banner]).
|
||||
?LOG_INFO("~n~ts", [Banner],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}).
|
||||
|
||||
warn_if_kernel_config_dubious() ->
|
||||
case os:type() of
|
||||
|
|
@ -1225,16 +1228,18 @@ warn_if_kernel_config_dubious() ->
|
|||
_ ->
|
||||
case erlang:system_info(kernel_poll) of
|
||||
true -> ok;
|
||||
false -> rabbit_log:warning(
|
||||
"Kernel poll (epoll, kqueue, etc) is disabled. Throughput "
|
||||
"and CPU utilization may worsen.~n")
|
||||
false -> ?LOG_WARNING(
|
||||
"Kernel poll (epoll, kqueue, etc) is disabled. "
|
||||
"Throughput and CPU utilization may worsen.",
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})
|
||||
end
|
||||
end,
|
||||
DirtyIOSchedulers = erlang:system_info(dirty_io_schedulers),
|
||||
case DirtyIOSchedulers < ?DIRTY_IO_SCHEDULERS_WARNING_THRESHOLD of
|
||||
true -> rabbit_log:warning(
|
||||
true -> ?LOG_WARNING(
|
||||
"Erlang VM is running with ~b dirty I/O schedulers, "
|
||||
"file I/O performance may worsen~n", [DirtyIOSchedulers]);
|
||||
"file I/O performance may worsen", [DirtyIOSchedulers],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL});
|
||||
false -> ok
|
||||
end,
|
||||
IDCOpts = case application:get_env(kernel, inet_default_connect_options) of
|
||||
|
|
@ -1242,8 +1247,9 @@ warn_if_kernel_config_dubious() ->
|
|||
{ok, Val} -> Val
|
||||
end,
|
||||
case proplists:get_value(nodelay, IDCOpts, false) of
|
||||
false -> rabbit_log:warning("Nagle's algorithm is enabled for sockets, "
|
||||
"network I/O latency will be higher~n");
|
||||
false -> ?LOG_WARNING("Nagle's algorithm is enabled for sockets, "
|
||||
"network I/O latency will be higher",
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL});
|
||||
true -> ok
|
||||
end.
|
||||
|
||||
|
|
@ -1259,7 +1265,8 @@ warn_if_disc_io_options_dubious() ->
|
|||
CreditDiscBound, IoBatchSize) of
|
||||
ok -> ok;
|
||||
{error, {Reason, Vars}} ->
|
||||
rabbit_log:warning(Reason, Vars)
|
||||
?LOG_WARNING(Reason, Vars,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})
|
||||
end.
|
||||
|
||||
validate_msg_store_io_batch_size_and_credit_disc_bound(CreditDiscBound,
|
||||
|
|
@ -1271,7 +1278,7 @@ validate_msg_store_io_batch_size_and_credit_disc_bound(CreditDiscBound,
|
|||
if IoBatchSize < ?IO_BATCH_SIZE ->
|
||||
throw({error,
|
||||
{"io_batch_size of ~b lower than recommended value ~b, "
|
||||
"paging performance may worsen~n",
|
||||
"paging performance may worsen",
|
||||
[IoBatchSize, ?IO_BATCH_SIZE]}});
|
||||
true ->
|
||||
ok
|
||||
|
|
@ -1292,7 +1299,7 @@ validate_msg_store_io_batch_size_and_credit_disc_bound(CreditDiscBound,
|
|||
throw({error,
|
||||
{"msg_store_credit_disc_bound {~b, ~b} lower than"
|
||||
"recommended value {~b, ~b},"
|
||||
" paging performance may worsen~n",
|
||||
" paging performance may worsen",
|
||||
[IC, MCA, RIC, RMCA]}});
|
||||
true ->
|
||||
ok
|
||||
|
|
@ -1320,7 +1327,7 @@ validate_msg_store_io_batch_size_and_credit_disc_bound(CreditDiscBound,
|
|||
{error,
|
||||
{"msg_store_io_batch_size ~b should be bigger than the initial "
|
||||
"credit value from msg_store_credit_disc_bound ~b,"
|
||||
" paging performance may worsen~n",
|
||||
" paging performance may worsen",
|
||||
[IoBatchSize, InitialCredit]}});
|
||||
true ->
|
||||
ok
|
||||
|
|
@ -1498,8 +1505,10 @@ ensure_working_fhc() ->
|
|||
{ok, true} -> "ON";
|
||||
{ok, false} -> "OFF"
|
||||
end,
|
||||
rabbit_log:info("FHC read buffering: ~s~n", [ReadBuf]),
|
||||
rabbit_log:info("FHC write buffering: ~s~n", [WriteBuf]),
|
||||
?LOG_INFO("FHC read buffering: ~s", [ReadBuf],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
?LOG_INFO("FHC write buffering: ~s", [WriteBuf],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
Filename = filename:join(code:lib_dir(kernel, ebin), "kernel.app"),
|
||||
{ok, Fd} = file_handle_cache:open(Filename, [raw, binary, read], []),
|
||||
{ok, _} = file_handle_cache:read(Fd, 1),
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ try_authenticate(Module, Username, AuthProps) ->
|
|||
case Module:user_login_authentication(Username, AuthProps) of
|
||||
{ok, AuthUser} -> {ok, AuthUser};
|
||||
{error, E} -> {refused, Username,
|
||||
"~s failed authenticating ~s: ~p~n",
|
||||
"~s failed authenticating ~s: ~p",
|
||||
[Module, Username, E]};
|
||||
{refused, F, A} -> {refused, Username, F, A}
|
||||
end.
|
||||
|
|
@ -97,7 +97,7 @@ try_authorize(Modules, Username, AuthProps) ->
|
|||
{ok, Impl, Tags}-> {ok, [{Module, Impl} | ModsImpls], ModsTags ++ Tags};
|
||||
{ok, Impl} -> {ok, [{Module, Impl} | ModsImpls], ModsTags};
|
||||
{error, E} -> {refused, Username,
|
||||
"~s failed authorizing ~s: ~p~n",
|
||||
"~s failed authorizing ~s: ~p",
|
||||
[Module, Username, E]};
|
||||
{refused, F, A} -> {refused, Username, F, A}
|
||||
end;
|
||||
|
|
@ -215,7 +215,7 @@ check_access(Fun, Module, ErrStr, ErrArgs, ErrName) ->
|
|||
false ->
|
||||
rabbit_misc:protocol_error(ErrName, ErrStr, ErrArgs);
|
||||
{error, E} ->
|
||||
FullErrStr = ErrStr ++ ", backend ~s returned an error: ~p~n",
|
||||
FullErrStr = ErrStr ++ ", backend ~s returned an error: ~p",
|
||||
FullErrArgs = ErrArgs ++ [Module, E],
|
||||
rabbit_log:error(FullErrStr, FullErrArgs),
|
||||
rabbit_misc:protocol_error(ErrName, FullErrStr, FullErrArgs)
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ handle_event({node_down, Node}, #alarms{alarmed_nodes = AN} = State) ->
|
|||
error -> []
|
||||
end,
|
||||
{ok, lists:foldr(fun(Source, AccState) ->
|
||||
rabbit_log:warning("~s resource limit alarm cleared for dead node ~p~n",
|
||||
rabbit_log:warning("~s resource limit alarm cleared for dead node ~p",
|
||||
[Source, Node]),
|
||||
maybe_alert(fun dict_unappend/3, Node, Source, false, AccState)
|
||||
end, State, AlarmsForDeadNode)};
|
||||
|
|
@ -284,7 +284,7 @@ maybe_alert(UpdateFun, Node, Source, WasAlertAdded,
|
|||
StillHasAlerts = lists:any(fun ({_Node, NodeAlerts}) -> lists:member(Source, NodeAlerts) end, dict:to_list(AN1)),
|
||||
case StillHasAlerts of
|
||||
true -> ok;
|
||||
false -> rabbit_log:warning("~s resource limit alarm cleared across the cluster~n", [Source])
|
||||
false -> rabbit_log:warning("~s resource limit alarm cleared across the cluster", [Source])
|
||||
end,
|
||||
Alert = {WasAlertAdded, StillHasAlerts, Node},
|
||||
case node() of
|
||||
|
|
@ -336,11 +336,11 @@ handle_set_alarm({file_descriptor_limit, []}, State) ->
|
|||
"********************************************************************~n"),
|
||||
{ok, State};
|
||||
handle_set_alarm(Alarm, State) ->
|
||||
rabbit_log:warning("alarm '~p' set~n", [Alarm]),
|
||||
rabbit_log:warning("alarm '~p' set", [Alarm]),
|
||||
{ok, State}.
|
||||
|
||||
handle_clear_resource_alarm(Source, Node, State) ->
|
||||
rabbit_log:warning("~s resource limit alarm cleared on node ~p~n",
|
||||
rabbit_log:warning("~s resource limit alarm cleared on node ~p",
|
||||
[Source, Node]),
|
||||
{ok, maybe_alert(fun dict_unappend/3, Node, Source, false, State)}.
|
||||
|
||||
|
|
@ -348,7 +348,7 @@ handle_clear_alarm(file_descriptor_limit, State) ->
|
|||
rabbit_log:warning("file descriptor limit alarm cleared~n"),
|
||||
{ok, State};
|
||||
handle_clear_alarm(Alarm, State) ->
|
||||
rabbit_log:warning("alarm '~p' cleared~n", [Alarm]),
|
||||
rabbit_log:warning("alarm '~p' cleared", [Alarm]),
|
||||
{ok, State}.
|
||||
|
||||
is_node_alarmed(Source, Node, #alarms{alarmed_nodes = AN}) ->
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ warn_file_limit() ->
|
|||
case file_handle_cache:get_limit() < L of
|
||||
true ->
|
||||
rabbit_log:warning(
|
||||
"Recovering ~p queues, available file handles: ~p. Please increase max open file handles limit to at least ~p!~n",
|
||||
"Recovering ~p queues, available file handles: ~p. Please increase max open file handles limit to at least ~p!",
|
||||
[L, file_handle_cache:get_limit(), L]);
|
||||
false ->
|
||||
ok
|
||||
|
|
@ -626,7 +626,7 @@ retry_wait(Q, F, E, RetriesLeft) ->
|
|||
% The old check would have crashed here,
|
||||
% instead, log it and run the exit fun. absent & alive is weird,
|
||||
% but better than crashing with badmatch,true
|
||||
rabbit_log:debug("Unexpected alive queue process ~p~n", [QPid]),
|
||||
rabbit_log:debug("Unexpected alive queue process ~p", [QPid]),
|
||||
E({absent, Q, alive});
|
||||
false ->
|
||||
ok % Expected result
|
||||
|
|
@ -1234,7 +1234,7 @@ count(VHost) ->
|
|||
%% that requires a proper consensus algorithm.
|
||||
length(list_for_count(VHost))
|
||||
catch _:Err ->
|
||||
rabbit_log:error("Failed to fetch number of queues in vhost ~p:~n~p~n",
|
||||
rabbit_log:error("Failed to fetch number of queues in vhost ~p:~n~p",
|
||||
[VHost, Err]),
|
||||
0
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ validate_and_alternate_credentials(Username, Password, ActingUser, Fun) ->
|
|||
ok ->
|
||||
Fun(Username, Password, ActingUser);
|
||||
{error, Err} ->
|
||||
rabbit_log:error("Credential validation for '~s' failed!~n", [Username]),
|
||||
rabbit_log:error("Credential validation for '~s' failed!", [Username]),
|
||||
{error, Err}
|
||||
end.
|
||||
|
||||
|
|
@ -334,7 +334,7 @@ change_password_sans_validation(Username, Password, ActingUser) ->
|
|||
-spec clear_password(rabbit_types:username(), rabbit_types:username()) -> 'ok'.
|
||||
|
||||
clear_password(Username, ActingUser) ->
|
||||
rabbit_log:info("Clearing password for '~s'~n", [Username]),
|
||||
rabbit_log:info("Clearing password for '~s'", [Username]),
|
||||
R = change_password_hash(Username, <<"">>),
|
||||
rabbit_event:notify(user_password_cleared,
|
||||
[{name, Username},
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ init() ->
|
|||
case State of
|
||||
{leader_waiting, Winner, _} ->
|
||||
rabbit_log:info(
|
||||
"Autoheal: in progress, requesting report from ~p~n", [Winner]),
|
||||
"Autoheal: in progress, requesting report from ~p", [Winner]),
|
||||
send(Winner, report_autoheal_status);
|
||||
_ ->
|
||||
ok
|
||||
|
|
@ -129,7 +129,7 @@ maybe_start(not_healing) ->
|
|||
case enabled() of
|
||||
true -> Leader = leader(),
|
||||
send(Leader, {request_start, node()}),
|
||||
rabbit_log:info("Autoheal request sent to ~p~n", [Leader]),
|
||||
rabbit_log:info("Autoheal request sent to ~p", [Leader]),
|
||||
not_healing;
|
||||
false -> not_healing
|
||||
end;
|
||||
|
|
@ -150,7 +150,7 @@ leader() ->
|
|||
%% This is the winner receiving its last notification that a node has
|
||||
%% stopped - all nodes can now start again
|
||||
rabbit_down(Node, {winner_waiting, [Node], Notify}) ->
|
||||
rabbit_log:info("Autoheal: final node has stopped, starting...~n",[]),
|
||||
rabbit_log:info("Autoheal: final node has stopped, starting...",[]),
|
||||
winner_finish(Notify);
|
||||
|
||||
rabbit_down(Node, {winner_waiting, WaitFor, Notify}) ->
|
||||
|
|
@ -173,25 +173,25 @@ node_down(Node, {winner_waiting, _, Notify}) ->
|
|||
|
||||
node_down(Node, {leader_waiting, Node, _Notify}) ->
|
||||
%% The winner went down, we don't know what to do so we simply abort.
|
||||
rabbit_log:info("Autoheal: aborting - winner ~p went down~n", [Node]),
|
||||
rabbit_log:info("Autoheal: aborting - winner ~p went down", [Node]),
|
||||
not_healing;
|
||||
|
||||
node_down(Node, {leader_waiting, _, _} = St) ->
|
||||
%% If it is a partial partition, the winner might continue with the
|
||||
%% healing process. If it is a full partition, the winner will also
|
||||
%% see it and abort. Let's wait for it.
|
||||
rabbit_log:info("Autoheal: ~p went down, waiting for winner decision ~n", [Node]),
|
||||
rabbit_log:info("Autoheal: ~p went down, waiting for winner decision ", [Node]),
|
||||
St;
|
||||
|
||||
node_down(Node, _State) ->
|
||||
rabbit_log:info("Autoheal: aborting - ~p went down~n", [Node]),
|
||||
rabbit_log:info("Autoheal: aborting - ~p went down", [Node]),
|
||||
not_healing.
|
||||
|
||||
%% If the process that has to restart the node crashes for an unexpected reason,
|
||||
%% we go back to a not healing state so the node is able to recover.
|
||||
process_down({'EXIT', Pid, Reason}, {restarting, Pid}) when Reason =/= normal ->
|
||||
rabbit_log:info("Autoheal: aborting - the process responsible for restarting the "
|
||||
"node terminated with reason: ~p~n", [Reason]),
|
||||
"node terminated with reason: ~p", [Reason]),
|
||||
not_healing;
|
||||
|
||||
process_down(_, State) ->
|
||||
|
|
@ -201,17 +201,17 @@ process_down(_, State) ->
|
|||
%% TODO should we try to debounce this?
|
||||
handle_msg({request_start, Node},
|
||||
not_healing, Partitions) ->
|
||||
rabbit_log:info("Autoheal request received from ~p~n", [Node]),
|
||||
rabbit_log:info("Autoheal request received from ~p", [Node]),
|
||||
case check_other_nodes(Partitions) of
|
||||
{error, E} ->
|
||||
rabbit_log:info("Autoheal request denied: ~s~n", [fmt_error(E)]),
|
||||
rabbit_log:info("Autoheal request denied: ~s", [fmt_error(E)]),
|
||||
not_healing;
|
||||
{ok, AllPartitions} ->
|
||||
{Winner, Losers} = make_decision(AllPartitions),
|
||||
rabbit_log:info("Autoheal decision~n"
|
||||
" * Partitions: ~p~n"
|
||||
" * Winner: ~p~n"
|
||||
" * Losers: ~p~n",
|
||||
" * Losers: ~p",
|
||||
[AllPartitions, Winner, Losers]),
|
||||
case node() =:= Winner of
|
||||
true -> handle_msg({become_winner, Losers},
|
||||
|
|
@ -224,12 +224,12 @@ handle_msg({request_start, Node},
|
|||
handle_msg({request_start, Node},
|
||||
State, _Partitions) ->
|
||||
rabbit_log:info("Autoheal request received from ~p when healing; "
|
||||
"ignoring~n", [Node]),
|
||||
"ignoring", [Node]),
|
||||
State;
|
||||
|
||||
handle_msg({become_winner, Losers},
|
||||
not_healing, _Partitions) ->
|
||||
rabbit_log:info("Autoheal: I am the winner, waiting for ~p to stop~n",
|
||||
rabbit_log:info("Autoheal: I am the winner, waiting for ~p to stop",
|
||||
[Losers]),
|
||||
stop_partition(Losers);
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ handle_msg({become_winner, Losers},
|
|||
%% The leader has aborted the healing, might have seen us down but
|
||||
%% we didn't see the same. Let's try again as it is the same partition.
|
||||
rabbit_log:info("Autoheal: I am the winner and received a duplicated "
|
||||
"request, waiting again for ~p to stop~n", [Losers]),
|
||||
"request, waiting again for ~p to stop", [Losers]),
|
||||
stop_partition(Losers);
|
||||
|
||||
handle_msg({become_winner, _},
|
||||
|
|
@ -246,7 +246,7 @@ handle_msg({become_winner, _},
|
|||
%% Something has happened to the leader, it might have seen us down but we
|
||||
%% are still alive. Partitions have changed, cannot continue.
|
||||
rabbit_log:info("Autoheal: I am the winner and received another healing "
|
||||
"request, partitions have changed to ~p. Aborting ~n", [Losers]),
|
||||
"request, partitions have changed to ~p. Aborting ", [Losers]),
|
||||
winner_finish(Losers),
|
||||
not_healing;
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ handle_msg({winner_is, Winner}, State = {leader_waiting, Winner, _},
|
|||
handle_msg(Request, {restarting, Pid} = St, _Partitions) ->
|
||||
%% ignore, we can contribute no further
|
||||
rabbit_log:info("Autoheal: Received the request ~p while waiting for ~p "
|
||||
"to restart the node. Ignoring it ~n", [Request, Pid]),
|
||||
"to restart the node. Ignoring it ", [Request, Pid]),
|
||||
St;
|
||||
|
||||
handle_msg(report_autoheal_status, not_healing, _Partitions) ->
|
||||
|
|
@ -286,14 +286,14 @@ handle_msg({autoheal_finished, Winner},
|
|||
%% The winner is finished with the autoheal process and notified us
|
||||
%% (the leader). We can transition to the "not_healing" state and
|
||||
%% accept new requests.
|
||||
rabbit_log:info("Autoheal finished according to winner ~p~n", [Winner]),
|
||||
rabbit_log:info("Autoheal finished according to winner ~p", [Winner]),
|
||||
not_healing;
|
||||
|
||||
handle_msg({autoheal_finished, Winner}, not_healing, _Partitions)
|
||||
when Winner =:= node() ->
|
||||
%% We are the leader and the winner. The state already transitioned
|
||||
%% to "not_healing" at the end of the autoheal process.
|
||||
rabbit_log:info("Autoheal finished according to winner ~p~n", [node()]),
|
||||
rabbit_log:info("Autoheal finished according to winner ~p", [node()]),
|
||||
not_healing;
|
||||
|
||||
handle_msg({autoheal_finished, Winner}, not_healing, _Partitions) ->
|
||||
|
|
@ -301,7 +301,7 @@ handle_msg({autoheal_finished, Winner}, not_healing, _Partitions) ->
|
|||
%% transitioned to not_healing. However, the winner was still able
|
||||
%% to finish. Let it pass.
|
||||
rabbit_log:info("Autoheal finished according to winner ~p."
|
||||
" Unexpected, I might have previously seen the winner down~n", [Winner]),
|
||||
" Unexpected, I might have previously seen the winner down", [Winner]),
|
||||
not_healing.
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
|
@ -309,7 +309,7 @@ handle_msg({autoheal_finished, Winner}, not_healing, _Partitions) ->
|
|||
send(Node, Msg) -> {?SERVER, Node} ! {autoheal_msg, Msg}.
|
||||
|
||||
abort(Down, Notify) ->
|
||||
rabbit_log:info("Autoheal: aborting - ~p down~n", [Down]),
|
||||
rabbit_log:info("Autoheal: aborting - ~p down", [Down]),
|
||||
%% Make sure any nodes waiting for us start - it won't necessarily
|
||||
%% heal the partition but at least they won't get stuck.
|
||||
%% If we are executing this, we are not stopping. Thus, don't wait
|
||||
|
|
@ -354,15 +354,14 @@ wait_for_supervisors(Monitors) ->
|
|||
60000 ->
|
||||
AliveLosers = [Node || {_, Node} <- pmon:monitored(Monitors)],
|
||||
rabbit_log:info("Autoheal: mnesia in nodes ~p is still up, sending "
|
||||
"winner notification again to these ~n", [AliveLosers]),
|
||||
"winner notification again to these ", [AliveLosers]),
|
||||
[send(L, {winner_is, node()}) || L <- AliveLosers],
|
||||
wait_for_mnesia_shutdown(AliveLosers)
|
||||
end
|
||||
end.
|
||||
|
||||
restart_loser(State, Winner) ->
|
||||
rabbit_log:warning(
|
||||
"Autoheal: we were selected to restart; winner is ~p~n", [Winner]),
|
||||
rabbit_log:warning("Autoheal: we were selected to restart; winner is ~p", [Winner]),
|
||||
NextStateTimeout = application:get_env(rabbit, autoheal_state_transition_timeout, 60000),
|
||||
rabbit_node_monitor:run_outside_applications(
|
||||
fun () ->
|
||||
|
|
|
|||
|
|
@ -948,7 +948,7 @@ handle_exception(Reason, State = #ch{cfg = #conf{protocol = Protocol,
|
|||
{Channel, CloseMethod} ->
|
||||
rabbit_log_channel:error(
|
||||
"Channel error on connection ~p (~s, vhost: '~s',"
|
||||
" user: '~s'), channel ~p:~n~s~n",
|
||||
" user: '~s'), channel ~p:~n~s",
|
||||
[ConnPid, ConnName, VHost, User#user.username,
|
||||
Channel, format_soft_error(Reason)]),
|
||||
ok = rabbit_writer:send_command(WriterPid, CloseMethod),
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ check_no_overlap1(Sets) ->
|
|||
case sets:size(Is) of
|
||||
0 -> ok;
|
||||
_ ->
|
||||
internal_error("Interceptor: more than one "
|
||||
"module handles ~p~n", [Is])
|
||||
internal_error("Interceptor: more than one module handles ~p", [Is])
|
||||
end,
|
||||
sets:union(Set, Union)
|
||||
end,
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ handle_cast({user_deleted, Details}) ->
|
|||
ok;
|
||||
handle_cast({node_deleted, Details}) ->
|
||||
Node = pget(node, Details),
|
||||
rabbit_log_connection:info(
|
||||
rabbit_log_channel:info(
|
||||
"Node '~s' was removed from the cluster, deleting"
|
||||
" its channel tracking tables...", [Node]),
|
||||
delete_tracked_channels_table_for_node(Node),
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ recover_durable_queues(QueuesAndRecoveryTerms) ->
|
|||
gen_server2:mcall(
|
||||
[{rabbit_amqqueue_sup_sup:start_queue_process(node(), Q, recovery),
|
||||
{init, {self(), Terms}}} || {Q, Terms} <- QueuesAndRecoveryTerms]),
|
||||
[rabbit_log:error("Queue ~p failed to initialise: ~p~n",
|
||||
[rabbit_log:error("Queue ~p failed to initialise: ~p",
|
||||
[Pid, Error]) || {Pid, Error} <- Failures],
|
||||
[Q || {_, {new, Q}} <- Results].
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ update_x_death_header(Info, Headers) ->
|
|||
[{table, rabbit_misc:sort_field_table(Info1)} | Others]);
|
||||
{<<"x-death">>, InvalidType, Header} ->
|
||||
rabbit_log:warning("Message has invalid x-death header (type: ~p)."
|
||||
" Resetting header ~p~n",
|
||||
" Resetting header ~p",
|
||||
[InvalidType, Header]),
|
||||
%% if x-death is something other than an array (list)
|
||||
%% then we reset it: this happens when some clients consume
|
||||
|
|
@ -247,7 +247,7 @@ log_cycle_once(Queues) ->
|
|||
true -> ok;
|
||||
undefined -> rabbit_log:warning(
|
||||
"Message dropped. Dead-letter queues cycle detected" ++
|
||||
": ~p~nThis cycle will NOT be reported again.~n",
|
||||
": ~p~nThis cycle will NOT be reported again.",
|
||||
[Queues]),
|
||||
put(Key, true)
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ dir() -> rabbit_mnesia:dir().
|
|||
set_disk_limits(State, Limit0) ->
|
||||
Limit = interpret_limit(Limit0),
|
||||
State1 = State#state { limit = Limit },
|
||||
rabbit_log:info("Disk free limit set to ~pMB~n",
|
||||
rabbit_log:info("Disk free limit set to ~pMB",
|
||||
[trunc(Limit / 1000000)]),
|
||||
internal_update(State1).
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ interpret_limit(Absolute) ->
|
|||
|
||||
emit_update_info(StateStr, CurrentFree, Limit) ->
|
||||
rabbit_log:info(
|
||||
"Free disk space is ~s. Free bytes: ~p. Limit: ~p~n",
|
||||
"Free disk space is ~s. Free bytes: ~p. Limit: ~p",
|
||||
[StateStr, CurrentFree, Limit]).
|
||||
|
||||
start_timer(State) ->
|
||||
|
|
@ -306,11 +306,11 @@ enable(#state{dir = Dir, interval = Interval, limit = Limit, retries = Retries}
|
|||
case {catch get_disk_free(Dir),
|
||||
vm_memory_monitor:get_total_memory()} of
|
||||
{N1, N2} when is_integer(N1), is_integer(N2) ->
|
||||
rabbit_log:info("Enabling free disk space monitoring~n", []),
|
||||
rabbit_log:info("Enabling free disk space monitoring", []),
|
||||
start_timer(set_disk_limits(State, Limit));
|
||||
Err ->
|
||||
rabbit_log:info("Free disk space monitor encountered an error "
|
||||
"(e.g. failed to parse output from OS tools): ~p, retries left: ~b~n",
|
||||
"(e.g. failed to parse output from OS tools): ~p, retries left: ~b",
|
||||
[Err, Retries]),
|
||||
erlang:send_after(Interval, self(), try_enable),
|
||||
State#state{enabled = false}
|
||||
|
|
|
|||
|
|
@ -86,10 +86,10 @@ check_epmd(State = #state{mod = Mod,
|
|||
{ok, State#state{port = Port1}}.
|
||||
|
||||
handle_port_please(init, noport, Me, Port) ->
|
||||
rabbit_log:info("epmd does not know us, re-registering as ~s~n", [Me]),
|
||||
rabbit_log:info("epmd does not know us, re-registering as ~s", [Me]),
|
||||
{ok, Port};
|
||||
handle_port_please(check, noport, Me, Port) ->
|
||||
rabbit_log:warning("epmd does not know us, re-registering ~s at port ~b~n", [Me, Port]),
|
||||
rabbit_log:warning("epmd does not know us, re-registering ~s at port ~b", [Me, Port]),
|
||||
{ok, Port};
|
||||
handle_port_please(_, closed, _Me, Port) ->
|
||||
rabbit_log:error("epmd monitor failed to retrieve our port from epmd: closed"),
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ peek_serial(XName, LockType) ->
|
|||
end.
|
||||
|
||||
invalid_module(T) ->
|
||||
rabbit_log:warning("Could not find exchange type ~s.~n", [T]),
|
||||
rabbit_log:warning("Could not find exchange type ~s.", [T]),
|
||||
put({xtype_to_module, T}, rabbit_exchange_type_invalid),
|
||||
rabbit_exchange_type_invalid.
|
||||
|
||||
|
|
|
|||
|
|
@ -682,7 +682,6 @@ maybe_add_action(Action, Acc, State) ->
|
|||
{[Action | Acc], State}.
|
||||
|
||||
do_resends(From, To, State) when From =< To ->
|
||||
% ?INFO("rabbit_fifo_client: doing resends From ~w To ~w~n", [From, To]),
|
||||
lists:foldl(fun resend/2, State, lists:seq(From, To));
|
||||
do_resends(_, _, State) ->
|
||||
State.
|
||||
|
|
|
|||
|
|
@ -1,719 +0,0 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_lager).
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit_log.hrl").
|
||||
|
||||
%% API
|
||||
-export([start_logger/0, log_locations/0, fold_sinks/2,
|
||||
broker_is_started/0, set_log_level/1]).
|
||||
|
||||
%% For test purposes
|
||||
-export([configure_lager/0]).
|
||||
|
||||
-export_type([log_location/0]).
|
||||
|
||||
-type log_location() :: string().
|
||||
|
||||
start_logger() ->
|
||||
ok = maybe_remove_logger_handler(),
|
||||
ok = app_utils:stop_applications([lager, syslog]),
|
||||
ok = ensure_lager_configured(),
|
||||
ok = app_utils:start_applications([lager]),
|
||||
fold_sinks(
|
||||
fun
|
||||
(_, [], Acc) ->
|
||||
Acc;
|
||||
(SinkName, _, Acc) ->
|
||||
lager:log(SinkName, info, self(),
|
||||
"Log file opened with Lager", []),
|
||||
Acc
|
||||
end, ok),
|
||||
ensure_log_working().
|
||||
|
||||
broker_is_started() ->
|
||||
{ok, HwmCurrent} = application:get_env(lager, error_logger_hwm),
|
||||
{ok, HwmOrig0} = application:get_env(lager, error_logger_hwm_original),
|
||||
HwmOrig = case get_most_verbose_log_level() of
|
||||
debug -> HwmOrig0 * 100;
|
||||
_ -> HwmOrig0
|
||||
end,
|
||||
case HwmOrig =:= HwmCurrent of
|
||||
false ->
|
||||
ok = application:set_env(lager, error_logger_hwm, HwmOrig),
|
||||
Handlers = gen_event:which_handlers(lager_event),
|
||||
lists:foreach(fun(Handler) ->
|
||||
lager:set_loghwm(Handler, HwmOrig)
|
||||
end, Handlers),
|
||||
ok;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
set_log_level(Level) ->
|
||||
IsValidLevel = lists:member(Level, lager_util:levels()),
|
||||
set_log_level(IsValidLevel, Level).
|
||||
|
||||
set_log_level(true, Level) ->
|
||||
SinksAndHandlers = [{Sink, gen_event:which_handlers(Sink)} ||
|
||||
Sink <- lager:list_all_sinks()],
|
||||
DefaultHwm = application:get_env(lager, error_logger_hwm_original, 50),
|
||||
Hwm = case Level of
|
||||
debug -> DefaultHwm * 100;
|
||||
_ -> DefaultHwm
|
||||
end,
|
||||
application:set_env(lager, error_logger_hwm, Hwm),
|
||||
set_sink_log_level(SinksAndHandlers, Level, Hwm);
|
||||
set_log_level(_, Level) ->
|
||||
{error, {invalid_log_level, Level}}.
|
||||
|
||||
set_sink_log_level([], _Level, _Hwm) ->
|
||||
ok;
|
||||
set_sink_log_level([{Sink, Handlers}|Rest], Level, Hwm) ->
|
||||
set_sink_handler_log_level(Sink, Handlers, Level, Hwm),
|
||||
set_sink_log_level(Rest, Level, Hwm).
|
||||
|
||||
set_sink_handler_log_level(_Sink, [], _Level, _Hwm) ->
|
||||
ok;
|
||||
set_sink_handler_log_level(Sink, [Handler|Rest], Level, Hwm)
|
||||
when is_atom(Handler) andalso is_integer(Hwm) ->
|
||||
lager:set_loghwm(Sink, Handler, undefined, Hwm),
|
||||
ok = lager:set_loglevel(Sink, Handler, undefined, Level),
|
||||
set_sink_handler_log_level(Sink, Rest, Level, Hwm);
|
||||
set_sink_handler_log_level(Sink, [{Handler, Id}|Rest], Level, Hwm) ->
|
||||
lager:set_loghwm(Sink, Handler, Id, Hwm),
|
||||
ok = lager:set_loglevel(Sink, Handler, Id, Level),
|
||||
set_sink_handler_log_level(Sink, Rest, Level, Hwm);
|
||||
set_sink_handler_log_level(Sink, [_|Rest], Level, Hwm) ->
|
||||
set_sink_handler_log_level(Sink, Rest, Level, Hwm).
|
||||
|
||||
log_locations() ->
|
||||
ensure_lager_configured(),
|
||||
DefaultHandlers = application:get_env(lager, handlers, []),
|
||||
Sinks = application:get_env(lager, extra_sinks, []),
|
||||
ExtraHandlers = [proplists:get_value(handlers, Props, [])
|
||||
|| {_, Props} <- Sinks],
|
||||
lists:sort(log_locations1([DefaultHandlers | ExtraHandlers], [])).
|
||||
|
||||
log_locations1([Handlers | Rest], Locations) ->
|
||||
Locations1 = log_locations2(Handlers, Locations),
|
||||
log_locations1(Rest, Locations1);
|
||||
log_locations1([], Locations) ->
|
||||
Locations.
|
||||
|
||||
log_locations2([{lager_file_backend, Settings} | Rest], Locations) ->
|
||||
FileName = lager_file_name1(Settings),
|
||||
Locations1 = case lists:member(FileName, Locations) of
|
||||
false -> [FileName | Locations];
|
||||
true -> Locations
|
||||
end,
|
||||
log_locations2(Rest, Locations1);
|
||||
log_locations2([{lager_console_backend, _} | Rest], Locations) ->
|
||||
Locations1 = case lists:member("<stdout>", Locations) of
|
||||
false -> ["<stdout>" | Locations];
|
||||
true -> Locations
|
||||
end,
|
||||
log_locations2(Rest, Locations1);
|
||||
log_locations2([_ | Rest], Locations) ->
|
||||
log_locations2(Rest, Locations);
|
||||
log_locations2([], Locations) ->
|
||||
Locations.
|
||||
|
||||
fold_sinks(Fun, Acc) ->
|
||||
Handlers = lager_config:global_get(handlers),
|
||||
Sinks = dict:to_list(lists:foldl(
|
||||
fun
|
||||
({{lager_file_backend, F}, _, S}, Dict) ->
|
||||
dict:append(S, F, Dict);
|
||||
({_, _, S}, Dict) ->
|
||||
case dict:is_key(S, Dict) of
|
||||
true -> dict:store(S, [], Dict);
|
||||
false -> Dict
|
||||
end
|
||||
end,
|
||||
dict:new(), Handlers)),
|
||||
fold_sinks(Sinks, Fun, Acc).
|
||||
|
||||
fold_sinks([{SinkName, FileNames} | Rest], Fun, Acc) ->
|
||||
Acc1 = Fun(SinkName, FileNames, Acc),
|
||||
fold_sinks(Rest, Fun, Acc1);
|
||||
fold_sinks([], _, Acc) ->
|
||||
Acc.
|
||||
|
||||
ensure_log_working() ->
|
||||
{ok, Handlers} = application:get_env(lager, handlers),
|
||||
[ ensure_lager_handler_file_exist(Handler)
|
||||
|| Handler <- Handlers ],
|
||||
Sinks = application:get_env(lager, extra_sinks, []),
|
||||
ensure_extra_sinks_working(Sinks, list_expected_sinks()).
|
||||
|
||||
ensure_extra_sinks_working(Sinks, [SinkName | Rest]) ->
|
||||
case proplists:get_value(SinkName, Sinks) of
|
||||
undefined -> throw({error, {cannot_log_to_file, unknown,
|
||||
rabbit_log_lager_event_sink_undefined}});
|
||||
Sink ->
|
||||
SinkHandlers = proplists:get_value(handlers, Sink, []),
|
||||
[ ensure_lager_handler_file_exist(Handler)
|
||||
|| Handler <- SinkHandlers ]
|
||||
end,
|
||||
ensure_extra_sinks_working(Sinks, Rest);
|
||||
ensure_extra_sinks_working(_Sinks, []) ->
|
||||
ok.
|
||||
|
||||
ensure_lager_handler_file_exist(Handler) ->
|
||||
case lager_file_name(Handler) of
|
||||
false -> ok;
|
||||
FileName -> ensure_logfile_exist(FileName)
|
||||
end.
|
||||
|
||||
lager_file_name({lager_file_backend, Settings}) ->
|
||||
lager_file_name1(Settings);
|
||||
lager_file_name(_) ->
|
||||
false.
|
||||
|
||||
lager_file_name1(Settings) when is_list(Settings) ->
|
||||
{file, FileName} = proplists:lookup(file, Settings),
|
||||
FileName;
|
||||
lager_file_name1({FileName, _}) -> FileName;
|
||||
lager_file_name1({FileName, _, _, _, _}) -> FileName;
|
||||
lager_file_name1(_) ->
|
||||
throw({error, {cannot_log_to_file, unknown,
|
||||
lager_file_backend_config_invalid}}).
|
||||
|
||||
|
||||
ensure_logfile_exist(LogFile) ->
|
||||
case rabbit_file:read_file_info(LogFile) of
|
||||
{ok,_} -> ok;
|
||||
{error, Err} -> throw({error, {cannot_log_to_file, LogFile, Err}})
|
||||
end.
|
||||
|
||||
ensure_lager_configured() ->
|
||||
case lager_configured() of
|
||||
false -> configure_lager();
|
||||
true -> ok
|
||||
end.
|
||||
|
||||
%% Lager should have handlers and sinks
|
||||
%% Error logger forwarding to syslog should be disabled
|
||||
lager_configured() ->
|
||||
Sinks = lager:list_all_sinks(),
|
||||
ExpectedSinks = list_expected_sinks(),
|
||||
application:get_env(lager, handlers) =/= undefined
|
||||
andalso
|
||||
lists:all(fun(S) -> lists:member(S, Sinks) end, ExpectedSinks)
|
||||
andalso
|
||||
application:get_env(syslog, syslog_error_logger) =/= undefined.
|
||||
|
||||
configure_lager() ->
|
||||
ok = app_utils:load_applications([lager]),
|
||||
%% Turn off reformatting for error_logger messages
|
||||
case application:get_env(lager, error_logger_redirect) of
|
||||
undefined -> application:set_env(lager, error_logger_redirect, true);
|
||||
_ -> ok
|
||||
end,
|
||||
case application:get_env(lager, error_logger_format_raw) of
|
||||
undefined -> application:set_env(lager, error_logger_format_raw, true);
|
||||
_ -> ok
|
||||
end,
|
||||
%% Setting env var to 'undefined' is different from not
|
||||
%% setting it at all, and lager is sensitive to this
|
||||
%% difference.
|
||||
case application:get_env(rabbit, lager_log_root) of
|
||||
{ok, Value} ->
|
||||
ok = application:set_env(lager, log_root, Value);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
case application:get_env(lager, colored) of
|
||||
undefined ->
|
||||
UseColor = rabbit_prelaunch_early_logging:use_colored_logging(),
|
||||
application:set_env(lager, colored, UseColor);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
%% Set rabbit.log config variable based on environment.
|
||||
prepare_rabbit_log_config(),
|
||||
%% Configure syslog library.
|
||||
ok = configure_syslog_error_logger(),
|
||||
%% At this point we should have rabbit.log application variable
|
||||
%% configured to generate RabbitMQ log handlers.
|
||||
GeneratedHandlers = generate_lager_handlers(),
|
||||
|
||||
%% If there are lager handlers configured,
|
||||
%% both lager and generate RabbitMQ handlers are used.
|
||||
%% This is because it's hard to decide clear preference rules.
|
||||
%% RabbitMQ handlers can be set to [] to use only lager handlers.
|
||||
Handlers = case application:get_env(lager, handlers, undefined) of
|
||||
undefined -> GeneratedHandlers;
|
||||
[] -> GeneratedHandlers;
|
||||
LagerHandlers ->
|
||||
%% Remove handlers generated in previous starts
|
||||
FormerRabbitHandlers = application:get_env(lager, rabbit_handlers, []),
|
||||
GeneratedHandlers ++ remove_rabbit_handlers(LagerHandlers,
|
||||
FormerRabbitHandlers)
|
||||
end,
|
||||
|
||||
ok = application:set_env(lager, handlers, Handlers),
|
||||
ok = application:set_env(lager, rabbit_handlers, GeneratedHandlers),
|
||||
|
||||
%% Setup extra sink/handlers. If they are not configured, redirect
|
||||
%% messages to the default sink. To know the list of expected extra
|
||||
%% sinks, we look at the 'lager_extra_sinks' compilation option.
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
LogLevels = application:get_env(rabbit, log_levels, []),
|
||||
Categories = proplists:get_value(categories, LogConfig, []),
|
||||
CategoriesConfig0 = case {Categories, LogLevels} of
|
||||
{[], []} -> [];
|
||||
{[], LogLevels} ->
|
||||
io:format("Using deprecated config parameter 'log_levels'. "
|
||||
"Please update your configuration file according to "
|
||||
"https://rabbitmq.com/logging.html"),
|
||||
lists:map(fun({Name, Level}) -> {Name, [{level, Level}]} end,
|
||||
LogLevels);
|
||||
{Categories, []} ->
|
||||
Categories;
|
||||
{Categories, _} ->
|
||||
io:format("Using the deprecated config parameter 'rabbit.log_levels' together "
|
||||
"with a new parameter for log categories."
|
||||
" 'rabbit.log_levels' will be ignored. Please remove it from the config. More at "
|
||||
"https://rabbitmq.com/logging.html"),
|
||||
Categories
|
||||
end,
|
||||
LogLevelsFromContext = case rabbit_prelaunch:get_context() of
|
||||
#{log_levels := LL} -> LL;
|
||||
_ -> undefined
|
||||
end,
|
||||
Fun = fun
|
||||
(global, _, CC) ->
|
||||
CC;
|
||||
(color, _, CC) ->
|
||||
CC;
|
||||
(CategoryS, LogLevel, CC) ->
|
||||
Category = list_to_atom(CategoryS),
|
||||
CCEntry = proplists:get_value(
|
||||
Category, CC, []),
|
||||
CCEntry1 = lists:ukeymerge(
|
||||
1,
|
||||
[{level, LogLevel}],
|
||||
lists:ukeysort(1, CCEntry)),
|
||||
lists:keystore(
|
||||
Category, 1, CC, {Category, CCEntry1})
|
||||
end,
|
||||
CategoriesConfig = case LogLevelsFromContext of
|
||||
undefined ->
|
||||
CategoriesConfig0;
|
||||
_ ->
|
||||
maps:fold(Fun,
|
||||
CategoriesConfig0,
|
||||
LogLevelsFromContext)
|
||||
end,
|
||||
SinkConfigs = lists:map(
|
||||
fun({Name, Config}) ->
|
||||
{rabbit_log:make_internal_sink_name(Name), Config}
|
||||
end,
|
||||
CategoriesConfig),
|
||||
LagerSinks = application:get_env(lager, extra_sinks, []),
|
||||
GeneratedSinks = generate_lager_sinks(
|
||||
[error_logger_lager_event | list_expected_sinks()],
|
||||
SinkConfigs),
|
||||
Sinks = merge_lager_sink_handlers(LagerSinks, GeneratedSinks, []),
|
||||
ok = application:set_env(lager, extra_sinks, Sinks),
|
||||
|
||||
case application:get_env(lager, error_logger_hwm) of
|
||||
undefined ->
|
||||
ok = application:set_env(lager, error_logger_hwm, 1000),
|
||||
% NB: 50 is the default value in lager.app.src
|
||||
ok = application:set_env(lager, error_logger_hwm_original, 50);
|
||||
{ok, Val} when is_integer(Val) andalso Val < 1000 ->
|
||||
ok = application:set_env(lager, error_logger_hwm, 1000),
|
||||
ok = application:set_env(lager, error_logger_hwm_original, Val);
|
||||
{ok, Val} when is_integer(Val) ->
|
||||
ok = application:set_env(lager, error_logger_hwm_original, Val),
|
||||
ok
|
||||
end,
|
||||
ok.
|
||||
|
||||
configure_syslog_error_logger() ->
|
||||
%% Disable error_logger forwarding to syslog if it's not configured
|
||||
case application:get_env(syslog, syslog_error_logger) of
|
||||
undefined ->
|
||||
application:set_env(syslog, syslog_error_logger, false);
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
remove_rabbit_handlers(Handlers, FormerHandlers) ->
|
||||
lists:filter(fun(Handler) ->
|
||||
not lists:member(Handler, FormerHandlers)
|
||||
end,
|
||||
Handlers).
|
||||
|
||||
generate_lager_handlers() ->
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
LogHandlersConfig = lists:keydelete(categories, 1, LogConfig),
|
||||
generate_lager_handlers(LogHandlersConfig).
|
||||
|
||||
generate_lager_handlers(LogHandlersConfig) ->
|
||||
lists:flatmap(
|
||||
fun
|
||||
({file, HandlerConfig}) ->
|
||||
case proplists:get_value(file, HandlerConfig, false) of
|
||||
false -> [];
|
||||
FileName when is_list(FileName) ->
|
||||
Backend = lager_backend(file),
|
||||
generate_handler(Backend, HandlerConfig)
|
||||
end;
|
||||
({Other, HandlerConfig}) when
|
||||
Other =:= console; Other =:= syslog; Other =:= exchange ->
|
||||
case proplists:get_value(enabled, HandlerConfig, false) of
|
||||
false -> [];
|
||||
true ->
|
||||
Backend = lager_backend(Other),
|
||||
generate_handler(Backend,
|
||||
lists:keydelete(enabled, 1, HandlerConfig))
|
||||
end
|
||||
end,
|
||||
LogHandlersConfig).
|
||||
|
||||
lager_backend(file) -> lager_file_backend;
|
||||
lager_backend(console) -> lager_console_backend;
|
||||
lager_backend(syslog) -> syslog_lager_backend;
|
||||
lager_backend(exchange) -> lager_exchange_backend.
|
||||
|
||||
%% Syslog backend is using an old API for configuration and
|
||||
%% does not support proplists.
|
||||
generate_handler(syslog_lager_backend=Backend, HandlerConfig) ->
|
||||
%% The default log level is set to `debug` because the actual
|
||||
%% filtering is made at the sink level. We want to accept all
|
||||
%% messages here.
|
||||
DefaultConfigVal = debug,
|
||||
Level = proplists:get_value(level, HandlerConfig, DefaultConfigVal),
|
||||
ok = configure_handler_backend(Backend),
|
||||
[{Backend,
|
||||
[Level,
|
||||
{},
|
||||
{lager_default_formatter, syslog_formatter_config()}]}];
|
||||
generate_handler(Backend, HandlerConfig) ->
|
||||
[{Backend,
|
||||
lists:ukeymerge(1, lists:ukeysort(1, HandlerConfig),
|
||||
lists:ukeysort(1, default_handler_config(Backend)))}].
|
||||
|
||||
configure_handler_backend(syslog_lager_backend) ->
|
||||
{ok, _} = application:ensure_all_started(syslog),
|
||||
ok;
|
||||
configure_handler_backend(_Backend) ->
|
||||
ok.
|
||||
|
||||
default_handler_config(lager_console_backend) ->
|
||||
%% The default log level is set to `debug` because the actual
|
||||
%% filtering is made at the sink level. We want to accept all
|
||||
%% messages here.
|
||||
DefaultConfigVal = debug,
|
||||
[{level, DefaultConfigVal},
|
||||
{formatter_config, default_config_value({formatter_config, console})}];
|
||||
default_handler_config(lager_exchange_backend) ->
|
||||
%% The default log level is set to `debug` because the actual
|
||||
%% filtering is made at the sink level. We want to accept all
|
||||
%% messages here.
|
||||
DefaultConfigVal = debug,
|
||||
[{level, DefaultConfigVal},
|
||||
{formatter_config, default_config_value({formatter_config, exchange})}];
|
||||
default_handler_config(lager_file_backend) ->
|
||||
%% The default log level is set to `debug` because the actual
|
||||
%% filtering is made at the sink level. We want to accept all
|
||||
%% messages here.
|
||||
DefaultConfigVal = debug,
|
||||
[{level, DefaultConfigVal},
|
||||
{formatter_config, default_config_value({formatter_config, file})},
|
||||
{date, ""},
|
||||
{size, 0}].
|
||||
|
||||
default_config_value(level) ->
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
FoldFun = fun
|
||||
({_, Cfg}, LL) when is_list(Cfg) ->
|
||||
NewLL = proplists:get_value(level, Cfg, LL),
|
||||
case LL of
|
||||
undefined ->
|
||||
NewLL;
|
||||
_ ->
|
||||
MoreVerbose = lager_util:level_to_num(NewLL) > lager_util:level_to_num(LL),
|
||||
case MoreVerbose of
|
||||
true -> NewLL;
|
||||
false -> LL
|
||||
end
|
||||
end;
|
||||
(_, LL) ->
|
||||
LL
|
||||
end,
|
||||
FoundLL = lists:foldl(FoldFun, undefined, LogConfig),
|
||||
case FoundLL of
|
||||
undefined -> info;
|
||||
_ -> FoundLL
|
||||
end;
|
||||
default_config_value({formatter_config, console}) ->
|
||||
EOL = case application:get_env(lager, colored) of
|
||||
{ok, true} -> "\e[0m\r\n";
|
||||
_ -> "\r\n"
|
||||
end,
|
||||
[date, " ", time, " ", color, "[", severity, "] ",
|
||||
{pid, ""},
|
||||
" ", message, EOL];
|
||||
default_config_value({formatter_config, _}) ->
|
||||
[date, " ", time, " ", color, "[", severity, "] ",
|
||||
{pid, ""},
|
||||
" ", message, "\n"].
|
||||
|
||||
syslog_formatter_config() ->
|
||||
[color, "[", severity, "] ",
|
||||
{pid, ""},
|
||||
" ", message, "\n"].
|
||||
|
||||
prepare_rabbit_log_config() ->
|
||||
%% If RABBIT_LOGS is not set, we should ignore it.
|
||||
DefaultFile = application:get_env(rabbit, lager_default_file, undefined),
|
||||
%% If RABBIT_UPGRADE_LOGS is not set, we should ignore it.
|
||||
UpgradeFile = application:get_env(rabbit, lager_upgrade_file, undefined),
|
||||
case DefaultFile of
|
||||
undefined -> ok;
|
||||
false ->
|
||||
set_env_default_log_disabled();
|
||||
tty ->
|
||||
set_env_default_log_console();
|
||||
FileName when is_list(FileName) ->
|
||||
case rabbit_prelaunch:get_context() of
|
||||
%% The user explicitly sets $RABBITMQ_LOGS;
|
||||
%% we should override a file location even
|
||||
%% if it's set in rabbitmq.config
|
||||
#{var_origins := #{main_log_file := environment}} ->
|
||||
set_env_default_log_file(FileName, override);
|
||||
_ ->
|
||||
set_env_default_log_file(FileName, keep)
|
||||
end
|
||||
end,
|
||||
|
||||
%% Upgrade log file never overrides the value set in rabbitmq.config
|
||||
case UpgradeFile of
|
||||
%% No special env for upgrade logs - redirect to the default sink
|
||||
undefined -> ok;
|
||||
%% Redirect logs to default output.
|
||||
DefaultFile -> ok;
|
||||
UpgradeFileName when is_list(UpgradeFileName) ->
|
||||
set_env_upgrade_log_file(UpgradeFileName)
|
||||
end.
|
||||
|
||||
set_env_default_log_disabled() ->
|
||||
%% Disabling all the logs.
|
||||
ok = application:set_env(rabbit, log, []).
|
||||
|
||||
set_env_default_log_console() ->
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
ConsoleConfig = proplists:get_value(console, LogConfig, []),
|
||||
LogConfigConsole =
|
||||
lists:keystore(console, 1, LogConfig,
|
||||
{console, lists:keystore(enabled, 1, ConsoleConfig,
|
||||
{enabled, true})}),
|
||||
%% Remove the file handler - disable logging to file
|
||||
LogConfigConsoleNoFile = lists:keydelete(file, 1, LogConfigConsole),
|
||||
ok = application:set_env(rabbit, log, LogConfigConsoleNoFile).
|
||||
|
||||
set_env_default_log_file(FileName, Override) ->
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
FileConfig = proplists:get_value(file, LogConfig, []),
|
||||
NewLogConfig = case proplists:get_value(file, FileConfig, undefined) of
|
||||
undefined ->
|
||||
lists:keystore(file, 1, LogConfig,
|
||||
{file, lists:keystore(file, 1, FileConfig,
|
||||
{file, FileName})});
|
||||
_ConfiguredFileName ->
|
||||
case Override of
|
||||
override ->
|
||||
lists:keystore(
|
||||
file, 1, LogConfig,
|
||||
{file, lists:keystore(file, 1, FileConfig,
|
||||
{file, FileName})});
|
||||
keep ->
|
||||
LogConfig
|
||||
end
|
||||
end,
|
||||
ok = application:set_env(rabbit, log, NewLogConfig).
|
||||
|
||||
set_env_upgrade_log_file(FileName) ->
|
||||
LogConfig = application:get_env(rabbit, log, []),
|
||||
SinksConfig = proplists:get_value(categories, LogConfig, []),
|
||||
UpgradeSinkConfig = proplists:get_value(upgrade, SinksConfig, []),
|
||||
FileConfig = proplists:get_value(file, SinksConfig, []),
|
||||
NewLogConfig = case proplists:get_value(file, FileConfig, undefined) of
|
||||
undefined ->
|
||||
lists:keystore(
|
||||
categories, 1, LogConfig,
|
||||
{categories,
|
||||
lists:keystore(
|
||||
upgrade, 1, SinksConfig,
|
||||
{upgrade,
|
||||
lists:keystore(file, 1, UpgradeSinkConfig,
|
||||
{file, FileName})})});
|
||||
%% No cahnge. We don't want to override the configured value.
|
||||
_File -> LogConfig
|
||||
end,
|
||||
ok = application:set_env(rabbit, log, NewLogConfig).
|
||||
|
||||
generate_lager_sinks(SinkNames, SinkConfigs) ->
|
||||
LogLevels = case rabbit_prelaunch:get_context() of
|
||||
#{log_levels := LL} -> LL;
|
||||
_ -> undefined
|
||||
end,
|
||||
DefaultLogLevel = case LogLevels of
|
||||
#{global := LogLevel} ->
|
||||
LogLevel;
|
||||
_ ->
|
||||
default_config_value(level)
|
||||
end,
|
||||
lists:map(fun(SinkName) ->
|
||||
SinkConfig = proplists:get_value(SinkName, SinkConfigs, []),
|
||||
SinkHandlers = case proplists:get_value(file, SinkConfig, false) of
|
||||
%% If no file defined - forward everything to the default backend
|
||||
false ->
|
||||
ForwarderLevel = proplists:get_value(level,
|
||||
SinkConfig,
|
||||
DefaultLogLevel),
|
||||
[{lager_forwarder_backend,
|
||||
[lager_util:make_internal_sink_name(lager), ForwarderLevel]}];
|
||||
%% If a file defined - add a file backend to handlers and remove all default file backends.
|
||||
File ->
|
||||
%% Use `debug` as a default handler to not override a handler level
|
||||
Level = proplists:get_value(level, SinkConfig, DefaultLogLevel),
|
||||
DefaultGeneratedHandlers = application:get_env(lager, rabbit_handlers, []),
|
||||
SinkFileHandlers = case proplists:get_value(lager_file_backend, DefaultGeneratedHandlers, undefined) of
|
||||
undefined ->
|
||||
%% Create a new file handler.
|
||||
%% `info` is a default level here.
|
||||
FileLevel = proplists:get_value(level, SinkConfig, DefaultLogLevel),
|
||||
generate_lager_handlers([{file, [{file, File}, {level, FileLevel}]}]);
|
||||
FileHandler ->
|
||||
%% Replace a filename in the handler
|
||||
FileHandlerChanges = case handler_level_more_verbose(FileHandler, Level) of
|
||||
true -> [{file, File}, {level, Level}];
|
||||
false -> [{file, File}]
|
||||
end,
|
||||
|
||||
[{lager_file_backend,
|
||||
lists:ukeymerge(1, FileHandlerChanges,
|
||||
lists:ukeysort(1, FileHandler))}]
|
||||
end,
|
||||
%% Remove all file handlers.
|
||||
AllLagerHandlers = application:get_env(lager, handlers, []),
|
||||
HandlersWithoutFile = lists:filter(
|
||||
fun({lager_file_backend, _}) -> false;
|
||||
({_, _}) -> true
|
||||
end,
|
||||
AllLagerHandlers),
|
||||
%% Set level for handlers which are more verbose.
|
||||
%% We don't increase verbosity in sinks so it works like forwarder backend.
|
||||
HandlersWithoutFileWithLevel = lists:map(fun({Name, Handler}) ->
|
||||
case handler_level_more_verbose(Handler, Level) of
|
||||
true -> {Name, lists:keystore(level, 1, Handler, {level, Level})};
|
||||
false -> {Name, Handler}
|
||||
end
|
||||
end,
|
||||
HandlersWithoutFile),
|
||||
|
||||
HandlersWithoutFileWithLevel ++ SinkFileHandlers
|
||||
end,
|
||||
{SinkName, [{handlers, SinkHandlers}, {rabbit_handlers, SinkHandlers}]}
|
||||
end,
|
||||
SinkNames).
|
||||
|
||||
handler_level_more_verbose(Handler, Level) ->
|
||||
HandlerLevel = proplists:get_value(level, Handler, default_config_value(level)),
|
||||
lager_util:level_to_num(HandlerLevel) > lager_util:level_to_num(Level).
|
||||
|
||||
merge_lager_sink_handlers([{Name, Sink} | RestSinks], GeneratedSinks, Agg) ->
|
||||
%% rabbitmq/rabbitmq-server#2044.
|
||||
%% We have to take into account that a sink's
|
||||
%% handler backend may need additional configuration here.
|
||||
%% {rabbit_log_federation_lager_event, [
|
||||
%% {handlers, [
|
||||
%% {lager_forwarder_backend, [lager_event,inherit]},
|
||||
%% {syslog_lager_backend, [debug]}
|
||||
%% ]},
|
||||
%% {rabbit_handlers, [
|
||||
%% {lager_forwarder_backend, [lager_event,inherit]}
|
||||
%% ]}
|
||||
%% ]}
|
||||
case lists:keytake(Name, 1, GeneratedSinks) of
|
||||
{value, {Name, GenSink}, RestGeneratedSinks} ->
|
||||
Handlers = proplists:get_value(handlers, Sink, []),
|
||||
GenHandlers = proplists:get_value(handlers, GenSink, []),
|
||||
FormerRabbitHandlers = proplists:get_value(rabbit_handlers, Sink, []),
|
||||
|
||||
%% Remove handlers defined in previous starts
|
||||
ConfiguredHandlers = remove_rabbit_handlers(Handlers, FormerRabbitHandlers),
|
||||
NewHandlers = GenHandlers ++ ConfiguredHandlers,
|
||||
ok = maybe_configure_handler_backends(NewHandlers),
|
||||
MergedSink = lists:keystore(rabbit_handlers, 1,
|
||||
lists:keystore(handlers, 1, Sink,
|
||||
{handlers, NewHandlers}),
|
||||
{rabbit_handlers, GenHandlers}),
|
||||
merge_lager_sink_handlers(
|
||||
RestSinks,
|
||||
RestGeneratedSinks,
|
||||
[{Name, MergedSink} | Agg]);
|
||||
false ->
|
||||
merge_lager_sink_handlers(
|
||||
RestSinks,
|
||||
GeneratedSinks,
|
||||
[{Name, Sink} | Agg])
|
||||
end;
|
||||
merge_lager_sink_handlers([], GeneratedSinks, Agg) -> GeneratedSinks ++ Agg.
|
||||
|
||||
maybe_configure_handler_backends([]) ->
|
||||
ok;
|
||||
maybe_configure_handler_backends([{Backend, _}|Backends]) ->
|
||||
ok = configure_handler_backend(Backend),
|
||||
maybe_configure_handler_backends(Backends).
|
||||
|
||||
list_expected_sinks() ->
|
||||
rabbit_prelaunch_early_logging:list_expected_sinks().
|
||||
|
||||
maybe_remove_logger_handler() ->
|
||||
M = logger,
|
||||
F = remove_handler,
|
||||
try
|
||||
ok = erlang:apply(M, F, [default])
|
||||
catch
|
||||
error:undef ->
|
||||
% OK since the logger module only exists in OTP 21.1 or later
|
||||
ok;
|
||||
error:{badmatch, {error, {not_found, default}}} ->
|
||||
% OK - this error happens when running a CLI command
|
||||
ok;
|
||||
Err:Reason ->
|
||||
error_logger:error_msg("calling ~p:~p failed: ~p:~p~n",
|
||||
[M, F, Err, Reason])
|
||||
end.
|
||||
|
||||
get_most_verbose_log_level() ->
|
||||
{ok, HandlersA} = application:get_env(lager, handlers),
|
||||
{ok, ExtraSinks} = application:get_env(lager, extra_sinks),
|
||||
HandlersB = lists:append(
|
||||
[H || {_, Keys} <- ExtraSinks,
|
||||
{handlers, H} <- Keys]),
|
||||
get_most_verbose_log_level(HandlersA ++ HandlersB,
|
||||
lager_util:level_to_num(none)).
|
||||
|
||||
get_most_verbose_log_level([{_, Props} | Rest], MostVerbose) ->
|
||||
LogLevel = proplists:get_value(level, Props, info),
|
||||
LogLevelNum = lager_util:level_to_num(LogLevel),
|
||||
case LogLevelNum > MostVerbose of
|
||||
true ->
|
||||
get_most_verbose_log_level(Rest, LogLevelNum);
|
||||
false ->
|
||||
get_most_verbose_log_level(Rest, MostVerbose)
|
||||
end;
|
||||
get_most_verbose_log_level([], MostVerbose) ->
|
||||
lager_util:num_to_level(MostVerbose).
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_channel).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CHAN}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_connection).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_CONN}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_feature_flags).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_FEAT_FLAGS}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_mirroring).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_MIRRORING}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_prelaunch).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_PRELAUNCH}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_queue).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_QUEUE}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
%% @doc Compatibility module for the old Lager-based logging API.
|
||||
-module(rabbit_log_upgrade).
|
||||
|
||||
-export([debug/1, debug/2, debug/3,
|
||||
info/1, info/2, info/3,
|
||||
notice/1, notice/2, notice/3,
|
||||
warning/1, warning/2, warning/3,
|
||||
error/1, error/2, error/3,
|
||||
critical/1, critical/2, critical/3,
|
||||
alert/1, alert/2, alert/3,
|
||||
emergency/1, emergency/2, emergency/3,
|
||||
none/1, none/2, none/3]).
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-compile({no_auto_import, [error/2, error/3]}).
|
||||
|
||||
%%----------------------------------------------------------------------------
|
||||
|
||||
-spec debug(string()) -> 'ok'.
|
||||
debug(Format) -> debug(Format, []).
|
||||
|
||||
-spec debug(string(), [any()]) -> 'ok'.
|
||||
debug(Format, Args) -> debug(self(), Format, Args).
|
||||
|
||||
-spec debug(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
debug(Pid, Format, Args) ->
|
||||
logger:debug(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec info(string()) -> 'ok'.
|
||||
info(Format) -> info(Format, []).
|
||||
|
||||
-spec info(string(), [any()]) -> 'ok'.
|
||||
info(Format, Args) -> info(self(), Format, Args).
|
||||
|
||||
-spec info(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
info(Pid, Format, Args) ->
|
||||
logger:info(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec notice(string()) -> 'ok'.
|
||||
notice(Format) -> notice(Format, []).
|
||||
|
||||
-spec notice(string(), [any()]) -> 'ok'.
|
||||
notice(Format, Args) -> notice(self(), Format, Args).
|
||||
|
||||
-spec notice(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
notice(Pid, Format, Args) ->
|
||||
logger:notice(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec warning(string()) -> 'ok'.
|
||||
warning(Format) -> warning(Format, []).
|
||||
|
||||
-spec warning(string(), [any()]) -> 'ok'.
|
||||
warning(Format, Args) -> warning(self(), Format, Args).
|
||||
|
||||
-spec warning(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
warning(Pid, Format, Args) ->
|
||||
logger:warning(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec error(string()) -> 'ok'.
|
||||
error(Format) -> error(Format, []).
|
||||
|
||||
-spec error(string(), [any()]) -> 'ok'.
|
||||
error(Format, Args) -> error(self(), Format, Args).
|
||||
|
||||
-spec error(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
error(Pid, Format, Args) ->
|
||||
logger:error(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec critical(string()) -> 'ok'.
|
||||
critical(Format) -> critical(Format, []).
|
||||
|
||||
-spec critical(string(), [any()]) -> 'ok'.
|
||||
critical(Format, Args) -> critical(self(), Format, Args).
|
||||
|
||||
-spec critical(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
critical(Pid, Format, Args) ->
|
||||
logger:critical(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec alert(string()) -> 'ok'.
|
||||
alert(Format) -> alert(Format, []).
|
||||
|
||||
-spec alert(string(), [any()]) -> 'ok'.
|
||||
alert(Format, Args) -> alert(self(), Format, Args).
|
||||
|
||||
-spec alert(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
alert(Pid, Format, Args) ->
|
||||
logger:alert(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec emergency(string()) -> 'ok'.
|
||||
emergency(Format) -> emergency(Format, []).
|
||||
|
||||
-spec emergency(string(), [any()]) -> 'ok'.
|
||||
emergency(Format, Args) -> emergency(self(), Format, Args).
|
||||
|
||||
-spec emergency(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
emergency(Pid, Format, Args) ->
|
||||
logger:emergency(Format, Args, #{pid => Pid,
|
||||
domain => ?RMQLOG_DOMAIN_UPGRADE}).
|
||||
|
||||
-spec none(string()) -> 'ok'.
|
||||
none(_Format) -> ok.
|
||||
|
||||
-spec none(string(), [any()]) -> 'ok'.
|
||||
none(_Format, _Args) -> ok.
|
||||
|
||||
-spec none(pid() | [tuple()], string(), [any()]) -> 'ok'.
|
||||
none(_Pid, _Format, _Args) -> ok.
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_logger_exchange_h).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
-include_lib("rabbit_common/include/rabbit_framing.hrl").
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
%% logger callbacks
|
||||
-export([log/2, adding_handler/1, removing_handler/1, changing_config/3,
|
||||
filter_config/1]).
|
||||
|
||||
-define(DECL_EXCHANGE_INTERVAL_SECS, 5).
|
||||
-define(LOG_EXCH_NAME, <<"amq.rabbitmq.log">>).
|
||||
-define(DEFAULT_FORMATTER, logger_formatter).
|
||||
-define(DEFAULT_FORMATTER_CONFIG, #{}).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Logger handler callbacks.
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
adding_handler(Config) ->
|
||||
Config1 = start_setup_proc(Config),
|
||||
{ok, Config1}.
|
||||
|
||||
changing_config(_SetOrUpdate, OldConfig, _NewConfig) ->
|
||||
{ok, OldConfig}.
|
||||
|
||||
filter_config(Config) ->
|
||||
Config.
|
||||
|
||||
log(#{meta := #{mfa := {?MODULE, _, _}}}, _) ->
|
||||
ok;
|
||||
log(LogEvent, Config) ->
|
||||
case rabbit_boot_state:get() of
|
||||
ready -> do_log(LogEvent, Config);
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
do_log(LogEvent, #{config := #{exchange := Exchange}} = Config) ->
|
||||
RoutingKey = make_routing_key(LogEvent, Config),
|
||||
AmqpMsg = log_event_to_amqp_msg(LogEvent, Config),
|
||||
Body = try_format_body(LogEvent, Config),
|
||||
case rabbit_basic:publish(Exchange, RoutingKey, AmqpMsg, Body) of
|
||||
ok -> ok;
|
||||
{error, not_found} -> ok
|
||||
end.
|
||||
|
||||
removing_handler(Config) ->
|
||||
unconfigure_exchange(Config),
|
||||
ok.
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Internal functions.
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
log_event_to_amqp_msg(LogEvent, Config) ->
|
||||
ContentType = guess_content_type(Config),
|
||||
Timestamp = make_timestamp(LogEvent, Config),
|
||||
Headers = make_headers(LogEvent, Config),
|
||||
#'P_basic'{
|
||||
content_type = ContentType,
|
||||
timestamp = Timestamp,
|
||||
headers = Headers
|
||||
}.
|
||||
|
||||
make_routing_key(#{level := Level}, _) ->
|
||||
rabbit_data_coercion:to_binary(Level).
|
||||
|
||||
guess_content_type(#{formatter := {rabbit_logger_json_fmt, _}}) ->
|
||||
<<"application/json">>;
|
||||
guess_content_type(_) ->
|
||||
<<"text/plain">>.
|
||||
|
||||
make_timestamp(#{meta := #{time := Timestamp}}, _) ->
|
||||
erlang:convert_time_unit(Timestamp, microsecond, second);
|
||||
make_timestamp(_, _) ->
|
||||
os:system_time(second).
|
||||
|
||||
make_headers(_, _) ->
|
||||
Node = rabbit_data_coercion:to_binary(node()),
|
||||
[{<<"node">>, longstr, Node}].
|
||||
|
||||
try_format_body(LogEvent, #{formatter := {Formatter, FormatterConfig}}) ->
|
||||
Formatted = try_format_body(LogEvent, Formatter, FormatterConfig),
|
||||
erlang:iolist_to_binary(Formatted).
|
||||
|
||||
try_format_body(LogEvent, Formatter, FormatterConfig) ->
|
||||
try
|
||||
Formatter:format(LogEvent, FormatterConfig)
|
||||
catch
|
||||
C:R:S ->
|
||||
case {?DEFAULT_FORMATTER, ?DEFAULT_FORMATTER_CONFIG} of
|
||||
{Formatter, FormatterConfig} ->
|
||||
"DEFAULT FORMATTER CRASHED\n";
|
||||
{DefaultFormatter, DefaultFormatterConfig} ->
|
||||
Msg = {"FORMATTER CRASH: ~tp -- ~p:~p:~p",
|
||||
[maps:get(msg, LogEvent), C, R, S]},
|
||||
LogEvent1 = LogEvent#{msg => Msg},
|
||||
try_format_body(
|
||||
LogEvent1,
|
||||
DefaultFormatter,
|
||||
DefaultFormatterConfig)
|
||||
end
|
||||
end.
|
||||
|
||||
start_setup_proc(#{config := InternalConfig} = Config) ->
|
||||
{ok, DefaultVHost} = application:get_env(rabbit, default_vhost),
|
||||
Exchange = rabbit_misc:r(DefaultVHost, exchange, ?LOG_EXCH_NAME),
|
||||
InternalConfig1 = InternalConfig#{exchange => Exchange},
|
||||
|
||||
Pid = spawn(fun() -> setup_proc(Config#{config => InternalConfig1}) end),
|
||||
InternalConfig2 = InternalConfig1#{setup_proc => Pid},
|
||||
Config#{config => InternalConfig2}.
|
||||
|
||||
setup_proc(
|
||||
#{config := #{exchange := #resource{name = Name,
|
||||
virtual_host = VHost}}} = Config) ->
|
||||
case declare_exchange(Config) of
|
||||
ok ->
|
||||
?LOG_INFO(
|
||||
"Logging to exchange '~s' in vhost '~s' ready", [Name, VHost],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL});
|
||||
error ->
|
||||
?LOG_DEBUG(
|
||||
"Logging to exchange '~s' in vhost '~s' not ready, "
|
||||
"trying again in ~b second(s)",
|
||||
[Name, VHost, ?DECL_EXCHANGE_INTERVAL_SECS],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
receive
|
||||
stop -> ok
|
||||
after ?DECL_EXCHANGE_INTERVAL_SECS * 1000 ->
|
||||
setup_proc(Config)
|
||||
end
|
||||
end.
|
||||
|
||||
declare_exchange(
|
||||
#{config := #{exchange := #resource{name = Name,
|
||||
virtual_host = VHost} = Exchange}}) ->
|
||||
try
|
||||
%% Durable.
|
||||
#exchange{} = rabbit_exchange:declare(
|
||||
Exchange, topic, true, false, true, [],
|
||||
?INTERNAL_USER),
|
||||
?LOG_DEBUG(
|
||||
"Declared exchange '~s' in vhost '~s'",
|
||||
[Name, VHost],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
ok
|
||||
catch
|
||||
Class:Reason ->
|
||||
?LOG_DEBUG(
|
||||
"Could not declare exchange '~s' in vhost '~s', "
|
||||
"reason: ~0p:~0p",
|
||||
[Name, VHost, Class, Reason],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}),
|
||||
error
|
||||
end.
|
||||
|
||||
unconfigure_exchange(
|
||||
#{config := #{exchange := #resource{name = Name,
|
||||
virtual_host = VHost} = Exchange,
|
||||
setup_proc := Pid}}) ->
|
||||
Pid ! stop,
|
||||
rabbit_exchange:delete(Exchange, false, ?INTERNAL_USER),
|
||||
?LOG_INFO(
|
||||
"Logging to exchange '~s' in vhost '~s' disabled",
|
||||
[Name, VHost],
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}).
|
||||
|
|
@ -150,7 +150,7 @@ sync_mirrors(HandleInfo, EmitStats,
|
|||
backing_queue_state = BQS }) ->
|
||||
Log = fun (Fmt, Params) ->
|
||||
rabbit_mirror_queue_misc:log_info(
|
||||
QName, "Synchronising: " ++ Fmt ++ "~n", Params)
|
||||
QName, "Synchronising: " ++ Fmt ++ "", Params)
|
||||
end,
|
||||
Log("~p messages to synchronise", [BQ:len(BQS)]),
|
||||
{ok, Q} = rabbit_amqqueue:lookup(QName),
|
||||
|
|
@ -198,7 +198,7 @@ terminate(Reason,
|
|||
true -> %% Remove the whole queue to avoid data loss
|
||||
rabbit_mirror_queue_misc:log_warning(
|
||||
QName, "Stopping all nodes on master shutdown since no "
|
||||
"synchronised mirror (replica) is available~n", []),
|
||||
"synchronised mirror (replica) is available", []),
|
||||
stop_all_slaves(Reason, State);
|
||||
false -> %% Just let some other mirror take over.
|
||||
ok
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ drop_mirror(QName, MirrorNode) ->
|
|||
[PrimaryPid] when MirrorPids =:= [] ->
|
||||
{error, cannot_drop_only_mirror};
|
||||
[Pid] ->
|
||||
log_info(Name, "Dropping queue mirror on node ~p~n",
|
||||
log_info(Name, "Dropping queue mirror on node ~p",
|
||||
[MirrorNode]),
|
||||
exit(Pid, {shutdown, dropped}),
|
||||
{ok, dropped}
|
||||
|
|
@ -238,7 +238,7 @@ add_mirror(QName, MirrorNode, SyncMode) ->
|
|||
{ok, _} ->
|
||||
try
|
||||
MirrorPid = rabbit_amqqueue_sup_sup:start_queue_process(MirrorNode, Q, slave),
|
||||
log_info(QName, "Adding mirror on node ~p: ~p~n", [MirrorNode, MirrorPid]),
|
||||
log_info(QName, "Adding mirror on node ~p: ~p", [MirrorNode, MirrorPid]),
|
||||
rabbit_mirror_queue_slave:go(MirrorPid, SyncMode)
|
||||
of
|
||||
_ -> ok
|
||||
|
|
@ -246,13 +246,13 @@ add_mirror(QName, MirrorNode, SyncMode) ->
|
|||
error:QError ->
|
||||
log_warning(QName,
|
||||
"Unable to start queue mirror on node '~p'. "
|
||||
"Target queue supervisor is not running: ~p~n",
|
||||
"Target queue supervisor is not running: ~p",
|
||||
[MirrorNode, QError])
|
||||
end;
|
||||
{error, Error} ->
|
||||
log_warning(QName,
|
||||
"Unable to start queue mirror on node '~p'. "
|
||||
"Target virtual host is not running: ~p~n",
|
||||
"Target virtual host is not running: ~p",
|
||||
[MirrorNode, Error]),
|
||||
ok
|
||||
end
|
||||
|
|
@ -264,7 +264,7 @@ add_mirror(QName, MirrorNode, SyncMode) ->
|
|||
report_deaths(_MirrorPid, _IsMaster, _QueueName, []) ->
|
||||
ok;
|
||||
report_deaths(MirrorPid, IsMaster, QueueName, DeadPids) ->
|
||||
log_info(QueueName, "~s replica of queue ~s detected replica ~s to be down~n",
|
||||
log_info(QueueName, "~s replica of queue ~s detected replica ~s to be down",
|
||||
[case IsMaster of
|
||||
true -> "Primary";
|
||||
false -> "Secondary"
|
||||
|
|
@ -342,7 +342,7 @@ stop_all_slaves(Reason, SPids, QName, GM, WaitTimeout) ->
|
|||
after WaitTimeout ->
|
||||
rabbit_mirror_queue_misc:log_warning(
|
||||
QName, "Missing 'DOWN' message from ~p in"
|
||||
" node ~p~n", [Pid, node(Pid)]),
|
||||
" node ~p", [Pid, node(Pid)]),
|
||||
[Pid | Acc]
|
||||
end;
|
||||
false ->
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ handle_go(Q0) when ?is_amqqueue(Q0) ->
|
|||
{ok, State};
|
||||
{stale, StalePid} ->
|
||||
rabbit_mirror_queue_misc:log_warning(
|
||||
QName, "Detected stale HA master: ~p~n", [StalePid]),
|
||||
QName, "Detected stale classic mirrored queue leader: ~p", [StalePid]),
|
||||
gm:leave(GM),
|
||||
{error, {stale_master_pid, StalePid}};
|
||||
duplicate_live_master ->
|
||||
|
|
@ -189,7 +189,7 @@ init_it(Self, GM, Node, QName) ->
|
|||
stop_pending_slaves(QName, Pids) ->
|
||||
[begin
|
||||
rabbit_mirror_queue_misc:log_warning(
|
||||
QName, "Detected a non-responsive classic queue mirror, stopping it: ~p~n", [Pid]),
|
||||
QName, "Detected a non-responsive classic queue mirror, stopping it: ~p", [Pid]),
|
||||
case erlang:process_info(Pid, dictionary) of
|
||||
undefined -> ok;
|
||||
{dictionary, Dict} ->
|
||||
|
|
@ -633,7 +633,7 @@ promote_me(From, #state { q = Q0,
|
|||
msg_id_status = MS,
|
||||
known_senders = KS}) when ?is_amqqueue(Q0) ->
|
||||
QName = amqqueue:get_name(Q0),
|
||||
rabbit_mirror_queue_misc:log_info(QName, "Promoting mirror ~s to master~n",
|
||||
rabbit_mirror_queue_misc:log_info(QName, "Promoting mirror ~s to leader",
|
||||
[rabbit_misc:pid_to_string(self())]),
|
||||
Q1 = amqqueue:set_pid(Q0, self()),
|
||||
DeathFun = rabbit_mirror_queue_master:sender_death_fun(),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ init() ->
|
|||
case is_virgin_node() of
|
||||
true ->
|
||||
rabbit_log:info("Node database directory at ~ts is empty. "
|
||||
"Assuming we need to join an existing cluster or initialise from scratch...~n",
|
||||
"Assuming we need to join an existing cluster or initialise from scratch...",
|
||||
[dir()]),
|
||||
rabbit_peer_discovery:log_configured_backend(),
|
||||
rabbit_peer_discovery:maybe_init(),
|
||||
|
|
@ -155,7 +155,7 @@ run_peer_discovery_with_retries(RetriesLeft, DelayInterval) ->
|
|||
e(invalid_cluster_nodes_conf)
|
||||
end,
|
||||
DiscoveredNodes = lists:usort(DiscoveredNodes0),
|
||||
rabbit_log:info("All discovered existing cluster peers: ~s~n",
|
||||
rabbit_log:info("All discovered existing cluster peers: ~s",
|
||||
[rabbit_peer_discovery:format_discovered_nodes(DiscoveredNodes)]),
|
||||
Peers = nodes_excl_me(DiscoveredNodes),
|
||||
case Peers of
|
||||
|
|
@ -165,7 +165,7 @@ run_peer_discovery_with_retries(RetriesLeft, DelayInterval) ->
|
|||
"Enabling debug logging might help troubleshoot."),
|
||||
init_db_and_upgrade([node()], disc, false, _Retry = true);
|
||||
_ ->
|
||||
rabbit_log:info("Peer nodes we can cluster with: ~s~n",
|
||||
rabbit_log:info("Peer nodes we can cluster with: ~s",
|
||||
[rabbit_peer_discovery:format_discovered_nodes(Peers)]),
|
||||
join_discovered_peers(Peers, NodeType)
|
||||
end.
|
||||
|
|
@ -180,13 +180,13 @@ join_discovered_peers(TryNodes, NodeType) ->
|
|||
join_discovered_peers_with_retries(TryNodes, _NodeType, 0, _DelayInterval) ->
|
||||
rabbit_log:warning(
|
||||
"Could not successfully contact any node of: ~s (as in Erlang distribution). "
|
||||
"Starting as a blank standalone node...~n",
|
||||
"Starting as a blank standalone node...",
|
||||
[string:join(lists:map(fun atom_to_list/1, TryNodes), ",")]),
|
||||
init_db_and_upgrade([node()], disc, false, _Retry = true);
|
||||
join_discovered_peers_with_retries(TryNodes, NodeType, RetriesLeft, DelayInterval) ->
|
||||
case find_reachable_peer_to_cluster_with(nodes_excl_me(TryNodes)) of
|
||||
{ok, Node} ->
|
||||
rabbit_log:info("Node '~s' selected for auto-clustering~n", [Node]),
|
||||
rabbit_log:info("Node '~s' selected for auto-clustering", [Node]),
|
||||
{ok, {_, DiscNodes, _}} = discover_cluster0(Node),
|
||||
init_db_and_upgrade(DiscNodes, NodeType, true, _Retry = true),
|
||||
rabbit_connection_tracking:boot(),
|
||||
|
|
@ -237,7 +237,7 @@ join_cluster(DiscoveryNode, NodeType) ->
|
|||
reset_gracefully(),
|
||||
|
||||
%% Join the cluster
|
||||
rabbit_log:info("Clustering with ~p as ~p node~n",
|
||||
rabbit_log:info("Clustering with ~p as ~p node",
|
||||
[ClusterNodes, NodeType]),
|
||||
ok = init_db_with_mnesia(ClusterNodes, NodeType,
|
||||
true, true, _Retry = true),
|
||||
|
|
@ -252,7 +252,7 @@ join_cluster(DiscoveryNode, NodeType) ->
|
|||
%% do we think so ourselves?
|
||||
case are_we_clustered_with(DiscoveryNode) of
|
||||
true ->
|
||||
rabbit_log:info("Asked to join a cluster but already a member of it: ~p~n", [ClusterNodes]),
|
||||
rabbit_log:info("Asked to join a cluster but already a member of it: ~p", [ClusterNodes]),
|
||||
{ok, already_member};
|
||||
false ->
|
||||
Msg = format_inconsistent_cluster_message(DiscoveryNode, node()),
|
||||
|
|
@ -269,14 +269,14 @@ join_cluster(DiscoveryNode, NodeType) ->
|
|||
|
||||
reset() ->
|
||||
ensure_mnesia_not_running(),
|
||||
rabbit_log:info("Resetting Rabbit~n", []),
|
||||
rabbit_log:info("Resetting Rabbit", []),
|
||||
reset_gracefully().
|
||||
|
||||
-spec force_reset() -> 'ok'.
|
||||
|
||||
force_reset() ->
|
||||
ensure_mnesia_not_running(),
|
||||
rabbit_log:info("Resetting Rabbit forcefully~n", []),
|
||||
rabbit_log:info("Resetting Rabbit forcefully", []),
|
||||
wipe().
|
||||
|
||||
reset_gracefully() ->
|
||||
|
|
@ -336,7 +336,7 @@ update_cluster_nodes(DiscoveryNode) ->
|
|||
%% nodes
|
||||
mnesia:delete_schema([node()]),
|
||||
rabbit_node_monitor:write_cluster_status(Status),
|
||||
rabbit_log:info("Updating cluster nodes from ~p~n",
|
||||
rabbit_log:info("Updating cluster nodes from ~p",
|
||||
[DiscoveryNode]),
|
||||
init_db_with_mnesia(AllNodes, node_type(), true, true, _Retry = false);
|
||||
false ->
|
||||
|
|
@ -367,7 +367,7 @@ forget_cluster_node(Node, RemoveWhenOffline, EmitNodeDeletedEvent) ->
|
|||
{true, true} -> e(online_node_offline_flag);
|
||||
{false, false} -> e(offline_node_no_offline_flag);
|
||||
{false, true} -> rabbit_log:info(
|
||||
"Removing node ~p from cluster~n", [Node]),
|
||||
"Removing node ~p from cluster", [Node]),
|
||||
case remove_node_if_mnesia_running(Node) of
|
||||
ok when EmitNodeDeletedEvent ->
|
||||
rabbit_event:notify(node_deleted, [{node, Node}]),
|
||||
|
|
@ -814,7 +814,7 @@ schema_ok_or_move() ->
|
|||
%% started yet
|
||||
rabbit_log:warning("schema integrity check failed: ~p~n"
|
||||
"moving database to backup location "
|
||||
"and recreating schema from scratch~n",
|
||||
"and recreating schema from scratch",
|
||||
[Reason]),
|
||||
ok = move_db(),
|
||||
ok = create_schema()
|
||||
|
|
@ -848,7 +848,7 @@ move_db() ->
|
|||
ok ->
|
||||
%% NB: we cannot use rabbit_log here since it may not have
|
||||
%% been started yet
|
||||
rabbit_log:warning("moved database from ~s to ~s~n",
|
||||
rabbit_log:warning("moved database from ~s to ~s",
|
||||
[MnesiaDir, BackupDir]),
|
||||
ok;
|
||||
{error, Reason} -> throw({error, {cannot_backup_mnesia,
|
||||
|
|
@ -895,7 +895,7 @@ leave_cluster(Node) ->
|
|||
end.
|
||||
|
||||
wait_for(Condition) ->
|
||||
rabbit_log:info("Waiting for ~p...~n", [Condition]),
|
||||
rabbit_log:info("Waiting for ~p...", [Condition]),
|
||||
timer:sleep(1000).
|
||||
|
||||
start_mnesia(CheckConsistency) ->
|
||||
|
|
@ -1040,15 +1040,15 @@ find_reachable_peer_to_cluster_with([Node | Nodes]) ->
|
|||
end,
|
||||
case remote_node_info(Node) of
|
||||
{badrpc, _} = Reason ->
|
||||
Fail("~p~n", [Reason]);
|
||||
Fail("~p", [Reason]);
|
||||
%% old delegate hash check
|
||||
{_OTP, RMQ, Hash, _} when is_binary(Hash) ->
|
||||
Fail("version ~s~n", [RMQ]);
|
||||
Fail("version ~s", [RMQ]);
|
||||
{_OTP, _RMQ, _Protocol, {error, _} = E} ->
|
||||
Fail("~p~n", [E]);
|
||||
Fail("~p", [E]);
|
||||
{OTP, RMQ, Protocol, _} ->
|
||||
case check_consistency(Node, OTP, RMQ, Protocol) of
|
||||
{error, _} -> Fail("versions ~p~n",
|
||||
{error, _} -> Fail("versions ~p",
|
||||
[{OTP, RMQ}]);
|
||||
ok -> {ok, Node}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ finish(FromNode, ToNode, AllNodes) ->
|
|||
end;
|
||||
FromNode ->
|
||||
rabbit_log:info(
|
||||
"Abandoning rename from ~s to ~s since we are still ~s~n",
|
||||
"Abandoning rename from ~s to ~s since we are still ~s",
|
||||
[FromNode, ToNode, FromNode]),
|
||||
[{ok, _} = file:copy(backup_of_conf(F), F) || F <- config_files()],
|
||||
ok = rabbit_file:recursive_delete([rabbit_mnesia:dir()]),
|
||||
|
|
@ -155,18 +155,18 @@ finish(FromNode, ToNode, AllNodes) ->
|
|||
%% Boot will almost certainly fail but we might as
|
||||
%% well just log this
|
||||
rabbit_log:info(
|
||||
"Rename attempted from ~s to ~s but we are ~s - ignoring.~n",
|
||||
"Rename attempted from ~s to ~s but we are ~s - ignoring.",
|
||||
[FromNode, ToNode, node()])
|
||||
end.
|
||||
|
||||
finish_primary(FromNode, ToNode) ->
|
||||
rabbit_log:info("Restarting as primary after rename from ~s to ~s~n",
|
||||
rabbit_log:info("Restarting as primary after rename from ~s to ~s",
|
||||
[FromNode, ToNode]),
|
||||
delete_rename_files(),
|
||||
ok.
|
||||
|
||||
finish_secondary(FromNode, ToNode, AllNodes) ->
|
||||
rabbit_log:info("Restarting as secondary after rename from ~s to ~s~n",
|
||||
rabbit_log:info("Restarting as secondary after rename from ~s to ~s",
|
||||
[FromNode, ToNode]),
|
||||
rabbit_upgrade:secondary_upgrade(AllNodes),
|
||||
rename_in_running_mnesia(FromNode, ToNode),
|
||||
|
|
|
|||
|
|
@ -717,7 +717,7 @@ init([Type, BaseDir, ClientRefs, StartupFunState]) ->
|
|||
Name = filename:join(filename:basename(BaseDir), atom_to_list(Type)),
|
||||
|
||||
{ok, IndexModule} = application:get_env(rabbit, msg_store_index_module),
|
||||
rabbit_log:info("Message store ~tp: using ~p to provide index~n", [Name, IndexModule]),
|
||||
rabbit_log:info("Message store ~tp: using ~p to provide index", [Name, IndexModule]),
|
||||
|
||||
AttemptFileSummaryRecovery =
|
||||
case ClientRefs of
|
||||
|
|
@ -794,11 +794,11 @@ init([Type, BaseDir, ClientRefs, StartupFunState]) ->
|
|||
true -> "clean";
|
||||
false -> "unclean"
|
||||
end,
|
||||
rabbit_log:debug("Rebuilding message location index after ~s shutdown...~n",
|
||||
rabbit_log:debug("Rebuilding message location index after ~s shutdown...",
|
||||
[Cleanliness]),
|
||||
{Offset, State1 = #msstate { current_file = CurFile }} =
|
||||
build_index(CleanShutdown, StartupFunState, State),
|
||||
rabbit_log:debug("Finished rebuilding index~n", []),
|
||||
rabbit_log:debug("Finished rebuilding index", []),
|
||||
%% read is only needed so that we can seek
|
||||
{ok, CurHdl} = open_file(Dir, filenum_to_name(CurFile),
|
||||
[read | ?WRITE_MODE]),
|
||||
|
|
@ -999,7 +999,7 @@ terminate(_Reason, State = #msstate { index_state = IndexState,
|
|||
{error, FSErr} ->
|
||||
rabbit_log:error("Unable to store file summary"
|
||||
" for vhost message store for directory ~p~n"
|
||||
"Error: ~p~n",
|
||||
"Error: ~p",
|
||||
[Dir, FSErr])
|
||||
end,
|
||||
[true = ets:delete(T) || T <- [FileSummaryEts, FileHandlesEts,
|
||||
|
|
@ -1012,7 +1012,7 @@ terminate(_Reason, State = #msstate { index_state = IndexState,
|
|||
ok;
|
||||
{error, RTErr} ->
|
||||
rabbit_log:error("Unable to save message store recovery terms"
|
||||
" for directory ~p~nError: ~p~n",
|
||||
" for directory ~p~nError: ~p",
|
||||
[Dir, RTErr])
|
||||
end,
|
||||
State3 #msstate { index_state = undefined,
|
||||
|
|
@ -1574,12 +1574,12 @@ index_clean_up_temporary_reference_count_entries(
|
|||
recover_index_and_client_refs(IndexModule, _Recover, undefined, Dir, _Name) ->
|
||||
{false, IndexModule:new(Dir), []};
|
||||
recover_index_and_client_refs(IndexModule, false, _ClientRefs, Dir, Name) ->
|
||||
rabbit_log:warning("Message store ~tp: rebuilding indices from scratch~n", [Name]),
|
||||
rabbit_log:warning("Message store ~tp: rebuilding indices from scratch", [Name]),
|
||||
{false, IndexModule:new(Dir), []};
|
||||
recover_index_and_client_refs(IndexModule, true, ClientRefs, Dir, Name) ->
|
||||
Fresh = fun (ErrorMsg, ErrorArgs) ->
|
||||
rabbit_log:warning("Message store ~tp : " ++ ErrorMsg ++ "~n"
|
||||
"rebuilding indices from scratch~n",
|
||||
"rebuilding indices from scratch",
|
||||
[Name | ErrorArgs]),
|
||||
{false, IndexModule:new(Dir), []}
|
||||
end,
|
||||
|
|
@ -1741,9 +1741,9 @@ build_index(true, _StartupFunState,
|
|||
end, {0, State}, FileSummaryEts);
|
||||
build_index(false, {MsgRefDeltaGen, MsgRefDeltaGenInit},
|
||||
State = #msstate { dir = Dir }) ->
|
||||
rabbit_log:debug("Rebuilding message refcount...~n", []),
|
||||
rabbit_log:debug("Rebuilding message refcount...", []),
|
||||
ok = count_msg_refs(MsgRefDeltaGen, MsgRefDeltaGenInit, State),
|
||||
rabbit_log:debug("Done rebuilding message refcount~n", []),
|
||||
rabbit_log:debug("Done rebuilding message refcount", []),
|
||||
{ok, Pid} = gatherer:start_link(),
|
||||
case [filename_to_num(FileName) ||
|
||||
FileName <- list_sorted_filenames(Dir, ?FILE_EXTENSION)] of
|
||||
|
|
@ -1757,7 +1757,7 @@ build_index(false, {MsgRefDeltaGen, MsgRefDeltaGenInit},
|
|||
build_index_worker(Gatherer, State = #msstate { dir = Dir },
|
||||
Left, File, Files) ->
|
||||
FileName = filenum_to_name(File),
|
||||
rabbit_log:debug("Rebuilding message location index from ~p (~B file(s) remaining)~n",
|
||||
rabbit_log:debug("Rebuilding message location index from ~p (~B file(s) remaining)",
|
||||
[form_filename(Dir, FileName), length(Files)]),
|
||||
{ok, Messages, FileSize} =
|
||||
scan_file_for_valid_messages(Dir, FileName),
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ terminate(#state { table = MsgLocations, dir = Dir }) ->
|
|||
ok -> ok;
|
||||
{error, Err} ->
|
||||
rabbit_log:error("Unable to save message store index"
|
||||
" for directory ~p.~nError: ~p~n",
|
||||
" for directory ~p.~nError: ~p",
|
||||
[Dir, Err])
|
||||
end,
|
||||
ets:delete(MsgLocations).
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ log_poodle_fail(Context) ->
|
|||
"better.~n~n"
|
||||
"If you cannot upgrade now and want to re-enable SSL listeners, you can~n"
|
||||
"set the config item 'ssl_allow_poodle_attack' to 'true' in the~n"
|
||||
"'rabbit' section of your configuration file.~n",
|
||||
"'rabbit' section of your configuration file.",
|
||||
[rabbit_misc:otp_release(), Context]).
|
||||
|
||||
fix_ssl_options(Config) ->
|
||||
|
|
@ -171,7 +171,7 @@ tcp_listener_addresses({Host, Port, Family0})
|
|||
[{IPAddress, Port, Family} ||
|
||||
{IPAddress, Family} <- getaddr(Host, Family0)];
|
||||
tcp_listener_addresses({_Host, Port, _Family0}) ->
|
||||
rabbit_log:error("invalid port ~p - not 0..65535~n", [Port]),
|
||||
rabbit_log:error("invalid port ~p - not 0..65535", [Port]),
|
||||
throw({error, {invalid_port, Port}}).
|
||||
|
||||
tcp_listener_addresses_auto(Port) ->
|
||||
|
|
@ -371,11 +371,11 @@ on_node_down(Node) ->
|
|||
case lists:member(Node, nodes()) of
|
||||
false ->
|
||||
rabbit_log:info(
|
||||
"Node ~s is down, deleting its listeners~n", [Node]),
|
||||
"Node ~s is down, deleting its listeners", [Node]),
|
||||
ok = mnesia:dirty_delete(rabbit_listener, Node);
|
||||
true ->
|
||||
rabbit_log:info(
|
||||
"Keeping ~s listeners: the node is already back~n", [Node])
|
||||
"Keeping ~s listeners: the node is already back", [Node])
|
||||
end.
|
||||
|
||||
-spec register_connection(pid()) -> ok.
|
||||
|
|
@ -457,11 +457,11 @@ close_connection(Pid, Explanation) ->
|
|||
case lists:member(Pid, connections()) of
|
||||
true ->
|
||||
Res = rabbit_reader:shutdown(Pid, Explanation),
|
||||
rabbit_log:info("Closing connection ~p because ~p~n", [Pid, Explanation]),
|
||||
rabbit_log:info("Closing connection ~p because ~p", [Pid, Explanation]),
|
||||
Res;
|
||||
false ->
|
||||
rabbit_log:warning("Asked to close connection ~p (reason: ~p) "
|
||||
"but no running cluster node reported it as an active connection. Was it already closed? ~n",
|
||||
"but no running cluster node reported it as an active connection. Was it already closed? ",
|
||||
[Pid, Explanation]),
|
||||
ok
|
||||
end.
|
||||
|
|
@ -578,7 +578,7 @@ gethostaddr(Host, Family) ->
|
|||
|
||||
-spec host_lookup_error(_, _) -> no_return().
|
||||
host_lookup_error(Host, Reason) ->
|
||||
rabbit_log:error("invalid host ~p - ~p~n", [Host, Reason]),
|
||||
rabbit_log:error("invalid host ~p - ~p", [Host, Reason]),
|
||||
throw({error, {invalid_host, Host, Reason}}).
|
||||
|
||||
resolve_family({_,_,_,_}, auto) -> inet;
|
||||
|
|
|
|||
|
|
@ -322,11 +322,11 @@ find_blocked_global_peers1([], _) ->
|
|||
unblock_global_peer(PeerNode) ->
|
||||
ThisNode = node(),
|
||||
PeerState = rpc:call(PeerNode, sys, get_status, [global_name_server]),
|
||||
error_logger:info_msg(
|
||||
logger:info(
|
||||
"Global hang workaround: global state on ~s seems broken~n"
|
||||
" * Peer global state: ~p~n"
|
||||
" * Local global state: ~p~n"
|
||||
"Faking nodedown/nodeup between ~s and ~s~n",
|
||||
"Faking nodedown/nodeup between ~s and ~s",
|
||||
[PeerNode, PeerState, sys:get_status(global_name_server),
|
||||
PeerNode, ThisNode]),
|
||||
{global_name_server, ThisNode} ! {nodedown, PeerNode},
|
||||
|
|
@ -434,7 +434,7 @@ handle_cast({check_partial_partition, Node, Rep, NodeGUID, MyGUID, RepGUID},
|
|||
_ ->
|
||||
rabbit_log:warning("Received a 'DOWN' message"
|
||||
" from ~p but still can"
|
||||
" communicate with it ~n",
|
||||
" communicate with it ",
|
||||
[Node]),
|
||||
cast(Rep, {partial_partition,
|
||||
Node, node(), RepGUID})
|
||||
|
|
@ -468,7 +468,7 @@ handle_cast({partial_partition, NotReallyDown, Proxy, MyGUID},
|
|||
{ok, pause_minority} ->
|
||||
rabbit_log:error(
|
||||
FmtBase ++ " * pause_minority mode enabled~n"
|
||||
"We will therefore pause until the *entire* cluster recovers~n",
|
||||
"We will therefore pause until the *entire* cluster recovers",
|
||||
ArgsBase),
|
||||
await_cluster_recovery(fun all_nodes_up/0),
|
||||
{noreply, State};
|
||||
|
|
@ -476,16 +476,16 @@ handle_cast({partial_partition, NotReallyDown, Proxy, MyGUID},
|
|||
case in_preferred_partition(PreferredNodes) of
|
||||
true -> rabbit_log:error(
|
||||
FmtBase ++ "We will therefore intentionally "
|
||||
"disconnect from ~s~n", ArgsBase ++ [Proxy]),
|
||||
"disconnect from ~s", ArgsBase ++ [Proxy]),
|
||||
upgrade_to_full_partition(Proxy);
|
||||
false -> rabbit_log:info(
|
||||
FmtBase ++ "We are about to pause, no need "
|
||||
"for further actions~n", ArgsBase)
|
||||
"for further actions", ArgsBase)
|
||||
end,
|
||||
{noreply, State};
|
||||
{ok, _} ->
|
||||
rabbit_log:error(
|
||||
FmtBase ++ "We will therefore intentionally disconnect from ~s~n",
|
||||
FmtBase ++ "We will therefore intentionally disconnect from ~s",
|
||||
ArgsBase ++ [Proxy]),
|
||||
upgrade_to_full_partition(Proxy),
|
||||
{noreply, State}
|
||||
|
|
@ -498,7 +498,7 @@ handle_cast({partial_partition, _GUID, _Reporter, _Proxy}, State) ->
|
|||
%% messages reliably when another node disconnects from us. Therefore
|
||||
%% we are told just before the disconnection so we can reciprocate.
|
||||
handle_cast({partial_partition_disconnect, Other}, State) ->
|
||||
rabbit_log:error("Partial partition disconnect from ~s~n", [Other]),
|
||||
rabbit_log:error("Partial partition disconnect from ~s", [Other]),
|
||||
disconnect(Other),
|
||||
{noreply, State};
|
||||
|
||||
|
|
@ -507,7 +507,7 @@ handle_cast({partial_partition_disconnect, Other}, State) ->
|
|||
%% mnesia propagation.
|
||||
handle_cast({node_up, Node, NodeType},
|
||||
State = #state{monitors = Monitors}) ->
|
||||
rabbit_log:info("rabbit on node ~p up~n", [Node]),
|
||||
rabbit_log:info("rabbit on node ~p up", [Node]),
|
||||
{AllNodes, DiscNodes, RunningNodes} = read_cluster_status(),
|
||||
write_cluster_status({add_node(Node, AllNodes),
|
||||
case NodeType of
|
||||
|
|
@ -551,7 +551,7 @@ handle_cast(_Msg, State) ->
|
|||
|
||||
handle_info({'DOWN', _MRef, process, {rabbit, Node}, _Reason},
|
||||
State = #state{monitors = Monitors, subscribers = Subscribers}) ->
|
||||
rabbit_log:info("rabbit on node ~p down~n", [Node]),
|
||||
rabbit_log:info("rabbit on node ~p down", [Node]),
|
||||
{AllNodes, DiscNodes, RunningNodes} = read_cluster_status(),
|
||||
write_cluster_status({AllNodes, DiscNodes, del_node(Node, RunningNodes)}),
|
||||
[P ! {node_down, Node} || P <- pmon:monitored(Subscribers)],
|
||||
|
|
@ -565,7 +565,7 @@ handle_info({'DOWN', _MRef, process, Pid, _Reason},
|
|||
|
||||
handle_info({nodedown, Node, Info}, State = #state{guid = MyGUID,
|
||||
node_guids = GUIDs}) ->
|
||||
rabbit_log:info("node ~p down: ~p~n",
|
||||
rabbit_log:info("node ~p down: ~p",
|
||||
[Node, proplists:get_value(nodedown_reason, Info)]),
|
||||
Check = fun (N, CheckGUID, DownGUID) ->
|
||||
cast(N, {check_partial_partition,
|
||||
|
|
@ -583,7 +583,7 @@ handle_info({nodedown, Node, Info}, State = #state{guid = MyGUID,
|
|||
{noreply, handle_dead_node(Node, State)};
|
||||
|
||||
handle_info({nodeup, Node, _Info}, State) ->
|
||||
rabbit_log:info("node ~p up~n", [Node]),
|
||||
rabbit_log:info("node ~p up", [Node]),
|
||||
{noreply, State};
|
||||
|
||||
handle_info({mnesia_system_event,
|
||||
|
|
@ -687,13 +687,13 @@ handle_dead_node(Node, State = #state{autoheal = Autoheal}) ->
|
|||
State#state{autoheal = rabbit_autoheal:node_down(Node, Autoheal)};
|
||||
{ok, Term} ->
|
||||
rabbit_log:warning("cluster_partition_handling ~p unrecognised, "
|
||||
"assuming 'ignore'~n", [Term]),
|
||||
"assuming 'ignore'", [Term]),
|
||||
State
|
||||
end.
|
||||
|
||||
await_cluster_recovery(Condition) ->
|
||||
rabbit_log:warning("Cluster minority/secondary status detected - "
|
||||
"awaiting recovery~n", []),
|
||||
"awaiting recovery", []),
|
||||
run_outside_applications(fun () ->
|
||||
rabbit:stop(),
|
||||
wait_for_cluster_recovery(Condition)
|
||||
|
|
@ -744,7 +744,7 @@ do_run_outside_app_fun(Fun) ->
|
|||
Fun()
|
||||
catch _:E:Stacktrace ->
|
||||
rabbit_log:error(
|
||||
"rabbit_outside_app_process:~n~p~n~p~n",
|
||||
"rabbit_outside_app_process:~n~p~n~p",
|
||||
[E, Stacktrace])
|
||||
end.
|
||||
|
||||
|
|
@ -920,7 +920,7 @@ possibly_partitioned_nodes() ->
|
|||
alive_rabbit_nodes() -- rabbit_nodes:all_running().
|
||||
|
||||
startup_log([]) ->
|
||||
rabbit_log:info("Starting rabbit_node_monitor~n", []);
|
||||
rabbit_log:info("Starting rabbit_node_monitor", []);
|
||||
startup_log(Nodes) ->
|
||||
rabbit_log:info("Starting rabbit_node_monitor, might be partitioned from ~p~n",
|
||||
rabbit_log:info("Starting rabbit_node_monitor, might be partitioned from ~p",
|
||||
[Nodes]).
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ lock_acquisition_failure_mode() ->
|
|||
-spec log_configured_backend() -> ok.
|
||||
|
||||
log_configured_backend() ->
|
||||
rabbit_log:info("Configured peer discovery backend: ~s~n", [backend()]).
|
||||
rabbit_log:info("Configured peer discovery backend: ~s", [backend()]).
|
||||
|
||||
maybe_init() ->
|
||||
Backend = backend(),
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ ensure1(FileJustChanged0) ->
|
|||
{[], []} ->
|
||||
ok;
|
||||
{[], _} ->
|
||||
rabbit_log:info("Plugins changed; disabled ~p~n",
|
||||
rabbit_log:info("Plugins changed; disabled ~p",
|
||||
[Stop]);
|
||||
{_, []} ->
|
||||
rabbit_log:info("Plugins changed; enabled ~p~n",
|
||||
rabbit_log:info("Plugins changed; enabled ~p",
|
||||
[Start]);
|
||||
{_, _} ->
|
||||
rabbit_log:info("Plugins changed; enabled ~p, disabled ~p~n",
|
||||
rabbit_log:info("Plugins changed; enabled ~p, disabled ~p",
|
||||
[Start, Stop])
|
||||
end,
|
||||
{ok, Start, Stop};
|
||||
|
|
@ -429,7 +429,7 @@ prepare_dir_plugin(PluginAppDescPath) ->
|
|||
rabbit_log:error("Failed to enable plugin \"~s\": "
|
||||
"it may have been built with an "
|
||||
"incompatible (more recent?) "
|
||||
"version of Erlang~n", [Plugin]),
|
||||
"version of Erlang", [Plugin]),
|
||||
throw({plugin_built_with_incompatible_erlang, Plugin});
|
||||
Error ->
|
||||
throw({plugin_module_unloadable, Plugin, Error})
|
||||
|
|
@ -459,11 +459,11 @@ prepare_plugin(#plugin{type = ez, name = Name, location = Location}, ExpandDir)
|
|||
[PluginAppDescPath|_] ->
|
||||
prepare_dir_plugin(PluginAppDescPath);
|
||||
_ ->
|
||||
rabbit_log:error("Plugin archive '~s' doesn't contain an .app file~n", [Location]),
|
||||
rabbit_log:error("Plugin archive '~s' doesn't contain an .app file", [Location]),
|
||||
throw({app_file_missing, Name, Location})
|
||||
end;
|
||||
{error, Reason} ->
|
||||
rabbit_log:error("Could not unzip plugin archive '~s': ~p~n", [Location, Reason]),
|
||||
rabbit_log:error("Could not unzip plugin archive '~s': ~p", [Location, Reason]),
|
||||
throw({failed_to_unzip_plugin, Name, Location, Reason})
|
||||
end;
|
||||
prepare_plugin(#plugin{type = dir, location = Location, name = Name},
|
||||
|
|
@ -472,7 +472,7 @@ prepare_plugin(#plugin{type = dir, location = Location, name = Name},
|
|||
[PluginAppDescPath|_] ->
|
||||
prepare_dir_plugin(PluginAppDescPath);
|
||||
_ ->
|
||||
rabbit_log:error("Plugin directory '~s' doesn't contain an .app file~n", [Location]),
|
||||
rabbit_log:error("Plugin directory '~s' doesn't contain an .app file", [Location]),
|
||||
throw({app_file_missing, Name, Location})
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
-module(rabbit_prelaunch_cluster).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup/1]).
|
||||
|
||||
setup(Context) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Clustering =="),
|
||||
rabbit_log_prelaunch:debug("Preparing cluster status files"),
|
||||
?LOG_DEBUG(
|
||||
"~n== Clustering ==", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
?LOG_DEBUG(
|
||||
"Preparing cluster status files", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
rabbit_node_monitor:prepare_cluster_status_files(),
|
||||
case Context of
|
||||
#{initial_pass := true} ->
|
||||
rabbit_log_prelaunch:debug("Upgrading Mnesia schema"),
|
||||
?LOG_DEBUG(
|
||||
"Upgrading Mnesia schema", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok = rabbit_upgrade:maybe_upgrade_mnesia();
|
||||
_ ->
|
||||
ok
|
||||
|
|
@ -17,6 +26,8 @@ setup(Context) ->
|
|||
%% It's important that the consistency check happens after
|
||||
%% the upgrade, since if we are a secondary node the
|
||||
%% primary node will have forgotten us
|
||||
rabbit_log_prelaunch:debug("Checking cluster consistency"),
|
||||
?LOG_DEBUG(
|
||||
"Checking cluster consistency", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
rabbit_mnesia:check_cluster_consistency(),
|
||||
ok.
|
||||
|
|
|
|||
|
|
@ -7,13 +7,17 @@
|
|||
|
||||
-module(rabbit_prelaunch_enabled_plugins_file).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup/1]).
|
||||
|
||||
setup(Context) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Enabled plugins file =="),
|
||||
?LOG_DEBUG(
|
||||
"~n== Enabled plugins file ==", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
update_enabled_plugins_file(Context).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
@ -33,21 +37,28 @@ do_update_enabled_plugins_file(#{enabled_plugins_file := File}, List) ->
|
|||
SortedList = lists:usort(List),
|
||||
case SortedList of
|
||||
[] ->
|
||||
rabbit_log_prelaunch:debug("Marking all plugins as disabled");
|
||||
?LOG_DEBUG(
|
||||
"Marking all plugins as disabled", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH});
|
||||
_ ->
|
||||
rabbit_log_prelaunch:debug(
|
||||
"Marking the following plugins as enabled:"),
|
||||
[rabbit_log_prelaunch:debug(" - ~s", [P]) || P <- SortedList]
|
||||
?LOG_DEBUG(
|
||||
lists:flatten(["Marking the following plugins as enabled:",
|
||||
["~n - ~s" || _ <- SortedList]]),
|
||||
SortedList,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})
|
||||
end,
|
||||
Content = io_lib:format("~p.~n", [SortedList]),
|
||||
case file:write_file(File, Content) of
|
||||
ok ->
|
||||
rabbit_log_prelaunch:debug("Wrote plugins file: ~ts", [File]),
|
||||
?LOG_DEBUG(
|
||||
"Wrote plugins file: ~ts", [File],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Failed to update enabled plugins file \"~ts\" "
|
||||
"from $RABBITMQ_ENABLED_PLUGINS: ~ts",
|
||||
[File, file:format_error(Reason)]),
|
||||
[File, file:format_error(Reason)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_update_enabled_plugins_file})
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -7,26 +7,35 @@
|
|||
|
||||
-module(rabbit_prelaunch_feature_flags).
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
|
||||
-export([setup/1]).
|
||||
|
||||
setup(#{feature_flags_file := FFFile}) ->
|
||||
rabbit_log_prelaunch:debug(""),
|
||||
rabbit_log_prelaunch:debug("== Feature flags =="),
|
||||
?LOG_DEBUG(
|
||||
"~n== Feature flags ==", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case filelib:ensure_dir(FFFile) of
|
||||
ok ->
|
||||
rabbit_log_prelaunch:debug("Initializing feature flags registry"),
|
||||
?LOG_DEBUG(
|
||||
"Initializing feature flags registry", [],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
case rabbit_feature_flags:initialize_registry() of
|
||||
ok ->
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Failed to initialize feature flags registry: ~p",
|
||||
[Reason]),
|
||||
[Reason],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_initialize_feature_flags_registry})
|
||||
end;
|
||||
{error, Reason} ->
|
||||
rabbit_log_prelaunch:error(
|
||||
?LOG_ERROR(
|
||||
"Failed to create feature flags file \"~ts\" directory: ~ts",
|
||||
[FFFile, file:format_error(Reason)]),
|
||||
[FFFile, file:format_error(Reason)],
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH}),
|
||||
throw({error, failed_to_create_feature_flags_file_directory})
|
||||
end.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -79,7 +79,7 @@ init(Q0, restart) when ?is_amqqueue(Q0) ->
|
|||
|
||||
crash_restart(Q0) when ?is_amqqueue(Q0) ->
|
||||
QueueName = amqqueue:get_name(Q0),
|
||||
rabbit_log:error("Restarting crashed ~s.~n", [rabbit_misc:rs(QueueName)]),
|
||||
rabbit_log:error("Restarting crashed ~s.", [rabbit_misc:rs(QueueName)]),
|
||||
gen_server2:cast(self(), init),
|
||||
Q1 = amqqueue:set_pid(Q0, self()),
|
||||
rabbit_amqqueue_process:init(Q1).
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ enable() ->
|
|||
{ok, RealBQ} = application:get_env(rabbit, backing_queue_module),
|
||||
case RealBQ of
|
||||
?MODULE -> ok;
|
||||
_ -> rabbit_log:info("Priority queues enabled, real BQ is ~s~n",
|
||||
_ -> rabbit_log:info("Priority queues enabled, real BQ is ~s",
|
||||
[RealBQ]),
|
||||
application:set_env(
|
||||
rabbitmq_priority_queue, backing_queue_module, RealBQ),
|
||||
|
|
|
|||
|
|
@ -1478,7 +1478,7 @@ move_to_per_vhost_stores(#resource{virtual_host = VHost} = QueueName) ->
|
|||
ok = rabbit_file:rename(OldQueueDir, NewQueueDir),
|
||||
ok = ensure_queue_name_stub_file(NewQueueDir, QueueName);
|
||||
false ->
|
||||
Msg = "Queue index directory '~s' not found for ~s~n",
|
||||
Msg = "Queue index directory '~s' not found for ~s",
|
||||
Args = [OldQueueDir, rabbit_misc:rs(QueueName)],
|
||||
rabbit_log_upgrade:error(Msg, Args),
|
||||
rabbit_log:error(Msg, Args)
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ handle_tick(QName,
|
|||
[] ->
|
||||
ok;
|
||||
Stale ->
|
||||
rabbit_log:info("~s: stale nodes detected. Purging ~w~n",
|
||||
rabbit_log:info("~s: stale nodes detected. Purging ~w",
|
||||
[rabbit_misc:rs(QName), Stale]),
|
||||
%% pipeline purge command
|
||||
{ok, Q} = rabbit_amqqueue:lookup(QName),
|
||||
|
|
@ -618,7 +618,7 @@ force_delete_queue(Servers) ->
|
|||
Err ->
|
||||
rabbit_log:warning(
|
||||
"Force delete of ~w failed with: ~w"
|
||||
"This may require manual data clean up~n",
|
||||
"This may require manual data clean up",
|
||||
[S, Err]),
|
||||
ok
|
||||
end
|
||||
|
|
|
|||
|
|
@ -272,19 +272,16 @@ server_capabilities(_) ->
|
|||
%%--------------------------------------------------------------------------
|
||||
|
||||
socket_error(Reason) when is_atom(Reason) ->
|
||||
rabbit_log_connection:error("Error on AMQP connection ~p: ~s~n",
|
||||
rabbit_log_connection:error("Error on AMQP connection ~p: ~s",
|
||||
[self(), rabbit_misc:format_inet_error(Reason)]);
|
||||
socket_error(Reason) ->
|
||||
Fmt = "Error on AMQP connection ~p:~n~p~n",
|
||||
Fmt = "Error on AMQP connection ~p:~n~p",
|
||||
Args = [self(), Reason],
|
||||
case Reason of
|
||||
%% The socket was closed while upgrading to SSL.
|
||||
%% This is presumably a TCP healthcheck, so don't log
|
||||
%% it unless specified otherwise.
|
||||
{ssl_upgrade_error, closed} ->
|
||||
%% Lager sinks (rabbit_log_connection)
|
||||
%% are handled by the lager parse_transform.
|
||||
%% Hence have to define the loglevel as a function call.
|
||||
rabbit_log_connection:debug(Fmt, Args);
|
||||
_ ->
|
||||
rabbit_log_connection:error(Fmt, Args)
|
||||
|
|
@ -365,11 +362,11 @@ start_connection(Parent, HelperSup, Deb, Sock) ->
|
|||
%% connection was closed cleanly by the client
|
||||
#v1{connection = #connection{user = #user{username = Username},
|
||||
vhost = VHost}} ->
|
||||
rabbit_log_connection:info("closing AMQP connection ~p (~s, vhost: '~s', user: '~s')~n",
|
||||
rabbit_log_connection:info("closing AMQP connection ~p (~s, vhost: '~s', user: '~s')",
|
||||
[self(), dynamic_connection_name(Name), VHost, Username]);
|
||||
%% just to be more defensive
|
||||
_ ->
|
||||
rabbit_log_connection:info("closing AMQP connection ~p (~s)~n",
|
||||
rabbit_log_connection:info("closing AMQP connection ~p (~s)",
|
||||
[self(), dynamic_connection_name(Name)])
|
||||
end
|
||||
catch
|
||||
|
|
@ -419,36 +416,36 @@ log_connection_exception(Severity, Name, {heartbeat_timeout, TimeoutSec}) ->
|
|||
%% Long line to avoid extra spaces and line breaks in log
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s):~n"
|
||||
"missed heartbeats from client, timeout: ~ps~n",
|
||||
"missed heartbeats from client, timeout: ~ps",
|
||||
[self(), Name, TimeoutSec]);
|
||||
log_connection_exception(Severity, Name, {connection_closed_abruptly,
|
||||
#v1{connection = #connection{user = #user{username = Username},
|
||||
vhost = VHost}}}) ->
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s, vhost: '~s', user: '~s'):~nclient unexpectedly closed TCP connection~n",
|
||||
"closing AMQP connection ~p (~s, vhost: '~s', user: '~s'):~nclient unexpectedly closed TCP connection",
|
||||
[self(), Name, VHost, Username]);
|
||||
%% when client abruptly closes connection before connection.open/authentication/authorization
|
||||
%% succeeded, don't log username and vhost as 'none'
|
||||
log_connection_exception(Severity, Name, {connection_closed_abruptly, _}) ->
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s):~nclient unexpectedly closed TCP connection~n",
|
||||
"closing AMQP connection ~p (~s):~nclient unexpectedly closed TCP connection",
|
||||
[self(), Name]);
|
||||
%% failed connection.tune negotiations
|
||||
log_connection_exception(Severity, Name, {handshake_error, tuning, _Channel,
|
||||
{exit, #amqp_error{explanation = Explanation},
|
||||
_Method, _Stacktrace}}) ->
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s):~nfailed to negotiate connection parameters: ~s~n",
|
||||
"closing AMQP connection ~p (~s):~nfailed to negotiate connection parameters: ~s",
|
||||
[self(), Name, Explanation]);
|
||||
%% old exception structure
|
||||
log_connection_exception(Severity, Name, connection_closed_abruptly) ->
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s):~n"
|
||||
"client unexpectedly closed TCP connection~n",
|
||||
"client unexpectedly closed TCP connection",
|
||||
[self(), Name]);
|
||||
log_connection_exception(Severity, Name, Ex) ->
|
||||
log_connection_exception_with_severity(Severity,
|
||||
"closing AMQP connection ~p (~s):~n~p~n",
|
||||
"closing AMQP connection ~p (~s):~n~p",
|
||||
[self(), Name, Ex]).
|
||||
|
||||
log_connection_exception_with_severity(Severity, Fmt, Args) ->
|
||||
|
|
@ -508,7 +505,7 @@ mainloop(Deb, Buf, BufLen, State = #v1{sock = Sock,
|
|||
%%
|
||||
%% The goal is to not log TCP healthchecks (a connection
|
||||
%% with no data received) unless specified otherwise.
|
||||
Fmt = "accepting AMQP connection ~p (~s)~n",
|
||||
Fmt = "accepting AMQP connection ~p (~s)",
|
||||
Args = [self(), ConnName],
|
||||
case Recv of
|
||||
closed -> rabbit_log_connection:debug(Fmt, Args);
|
||||
|
|
@ -756,7 +753,7 @@ wait_for_channel_termination(N, TimerRef,
|
|||
rabbit_log_connection:error(
|
||||
"Error on AMQP connection ~p (~s, vhost: '~s',"
|
||||
" user: '~s', state: ~p), channel ~p:"
|
||||
"error while terminating:~n~p~n",
|
||||
"error while terminating:~n~p",
|
||||
[self(), ConnName, VHost, User#user.username,
|
||||
CS, Channel, Reason]),
|
||||
handle_uncontrolled_channel_close(ChPid),
|
||||
|
|
@ -797,7 +794,7 @@ log_hard_error(#v1{connection_state = CS,
|
|||
vhost = VHost}}, Channel, Reason) ->
|
||||
rabbit_log_connection:error(
|
||||
"Error on AMQP connection ~p (~s, vhost: '~s',"
|
||||
" user: '~s', state: ~p), channel ~p:~n ~s~n",
|
||||
" user: '~s', state: ~p), channel ~p:~n ~s",
|
||||
[self(), ConnName, VHost, User#user.username, CS, Channel, format_hard_error(Reason)]).
|
||||
|
||||
handle_exception(State = #v1{connection_state = closed}, Channel, Reason) ->
|
||||
|
|
@ -816,7 +813,7 @@ handle_exception(State = #v1{connection = #connection{protocol = Protocol,
|
|||
Channel, Reason = #amqp_error{name = access_refused,
|
||||
explanation = ErrMsg}) ->
|
||||
rabbit_log_connection:error(
|
||||
"Error on AMQP connection ~p (~s, state: ~p):~n~s~n",
|
||||
"Error on AMQP connection ~p (~s, state: ~p):~n~s",
|
||||
[self(), ConnName, starting, ErrMsg]),
|
||||
%% respect authentication failure notification capability
|
||||
case rabbit_misc:table_lookup(Capabilities,
|
||||
|
|
@ -835,7 +832,7 @@ handle_exception(State = #v1{connection = #connection{protocol = Protocol,
|
|||
Channel, Reason = #amqp_error{name = not_allowed,
|
||||
explanation = ErrMsg}) ->
|
||||
rabbit_log_connection:error(
|
||||
"Error on AMQP connection ~p (~s, user: '~s', state: ~p):~n~s~n",
|
||||
"Error on AMQP connection ~p (~s, user: '~s', state: ~p):~n~s",
|
||||
[self(), ConnName, User#user.username, opening, ErrMsg]),
|
||||
send_error_on_channel0_and_close(Channel, Protocol, Reason, State);
|
||||
handle_exception(State = #v1{connection = #connection{protocol = Protocol},
|
||||
|
|
@ -853,7 +850,7 @@ handle_exception(State = #v1{connection = #connection{protocol = Protocol,
|
|||
explanation = ErrMsg}) ->
|
||||
rabbit_log_connection:error(
|
||||
"Error on AMQP connection ~p (~s,"
|
||||
" user: '~s', state: ~p):~n~s~n",
|
||||
" user: '~s', state: ~p):~n~s",
|
||||
[self(), ConnName, User#user.username, tuning, ErrMsg]),
|
||||
send_error_on_channel0_and_close(Channel, Protocol, Reason, State);
|
||||
handle_exception(State, Channel, Reason) ->
|
||||
|
|
@ -1256,7 +1253,7 @@ handle_method0(#'connection.open'{virtual_host = VHost},
|
|||
maybe_emit_stats(State1),
|
||||
rabbit_log_connection:info(
|
||||
"connection ~p (~s): "
|
||||
"user '~s' authenticated and granted access to vhost '~s'~n",
|
||||
"user '~s' authenticated and granted access to vhost '~s'",
|
||||
[self(), dynamic_connection_name(ConnName), Username, VHost]),
|
||||
State1;
|
||||
handle_method0(#'connection.close'{}, State) when ?IS_RUNNING(State) ->
|
||||
|
|
@ -1282,7 +1279,7 @@ handle_method0(#'connection.update_secret'{new_secret = NewSecret, reason = Reas
|
|||
sock = Sock}) when ?IS_RUNNING(State) ->
|
||||
rabbit_log_connection:debug(
|
||||
"connection ~p (~s) of user '~s': "
|
||||
"asked to update secret, reason: ~s~n",
|
||||
"asked to update secret, reason: ~s",
|
||||
[self(), dynamic_connection_name(ConnName), Username, Reason]),
|
||||
case rabbit_access_control:update_state(User, NewSecret) of
|
||||
{ok, User1} ->
|
||||
|
|
@ -1299,15 +1296,15 @@ handle_method0(#'connection.update_secret'{new_secret = NewSecret, reason = Reas
|
|||
ok = send_on_channel0(Sock, #'connection.update_secret_ok'{}, Protocol),
|
||||
rabbit_log_connection:info(
|
||||
"connection ~p (~s): "
|
||||
"user '~s' updated secret, reason: ~s~n",
|
||||
"user '~s' updated secret, reason: ~s",
|
||||
[self(), dynamic_connection_name(ConnName), Username, Reason]),
|
||||
State#v1{connection = Conn#connection{user = User1}};
|
||||
{refused, Message} ->
|
||||
rabbit_log_connection:error("Secret update was refused for user '~p': ~p",
|
||||
rabbit_log_connection:error("Secret update was refused for user '~s': ~p",
|
||||
[Username, Message]),
|
||||
rabbit_misc:protocol_error(not_allowed, "New secret was refused by one of the backends", []);
|
||||
{error, Message} ->
|
||||
rabbit_log_connection:error("Secret update for user '~p' failed: ~p",
|
||||
rabbit_log_connection:error("Secret update for user '~s' failed: ~p",
|
||||
[Username, Message]),
|
||||
rabbit_misc:protocol_error(not_allowed,
|
||||
"Secret update failed", [])
|
||||
|
|
@ -1772,7 +1769,7 @@ augment_connection_log_name(#connection{name = Name} = Connection) ->
|
|||
Connection;
|
||||
UserSpecifiedName ->
|
||||
LogName = <<Name/binary, " - ", UserSpecifiedName/binary>>,
|
||||
rabbit_log_connection:info("Connection ~p (~s) has a client-provided name: ~s~n", [self(), Name, UserSpecifiedName]),
|
||||
rabbit_log_connection:info("Connection ~p (~s) has a client-provided name: ~s", [self(), Name, UserSpecifiedName]),
|
||||
?store_proc_name(LogName),
|
||||
Connection#connection{log_name = LogName}
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ wait(TableNames, Retry) ->
|
|||
wait(TableNames, Timeout, Retries) ->
|
||||
%% We might be in ctl here for offline ops, in which case we can't
|
||||
%% get_env() for the rabbit app.
|
||||
rabbit_log:info("Waiting for Mnesia tables for ~p ms, ~p retries left~n",
|
||||
rabbit_log:info("Waiting for Mnesia tables for ~p ms, ~p retries left",
|
||||
[Timeout, Retries - 1]),
|
||||
Result = case mnesia:wait_for_tables(TableNames, Timeout) of
|
||||
ok ->
|
||||
|
|
@ -120,7 +120,7 @@ wait(TableNames, Timeout, Retries) ->
|
|||
{1, {error, _} = Error} ->
|
||||
throw(Error);
|
||||
{_, {error, Error}} ->
|
||||
rabbit_log:warning("Error while waiting for Mnesia tables: ~p~n", [Error]),
|
||||
rabbit_log:warning("Error while waiting for Mnesia tables: ~p", [Error]),
|
||||
wait(TableNames, Timeout, Retries - 1)
|
||||
end.
|
||||
|
||||
|
|
|
|||
|
|
@ -74,13 +74,13 @@ tap_out({#resource{name = QName, virtual_host = VHost},
|
|||
-spec start(rabbit_types:vhost()) -> 'ok'.
|
||||
|
||||
start(VHost) ->
|
||||
rabbit_log:info("Enabling tracing for vhost '~s'~n", [VHost]),
|
||||
rabbit_log:info("Enabling tracing for vhost '~s'", [VHost]),
|
||||
update_config(fun (VHosts) -> [VHost | VHosts -- [VHost]] end).
|
||||
|
||||
-spec stop(rabbit_types:vhost()) -> 'ok'.
|
||||
|
||||
stop(VHost) ->
|
||||
rabbit_log:info("Disabling tracing for vhost '~s'~n", [VHost]),
|
||||
rabbit_log:info("Disabling tracing for vhost '~s'", [VHost]),
|
||||
update_config(fun (VHosts) -> VHosts -- [VHost] end).
|
||||
|
||||
update_config(Fun) ->
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ count_tracked_items(TableNameFun, CountRecPosition, Key, ContextMsg) ->
|
|||
Acc + N
|
||||
catch _:Err ->
|
||||
rabbit_log:error(
|
||||
"Failed to fetch number of ~p ~p on node ~p:~n~p~n",
|
||||
"Failed to fetch number of ~p ~p on node ~p:~n~p",
|
||||
[ContextMsg, Key, Node, Err]),
|
||||
Acc
|
||||
end
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ ensure_backup_taken() ->
|
|||
|
||||
take_backup() ->
|
||||
BackupDir = backup_dir(),
|
||||
info("upgrades: Backing up mnesia dir to ~p~n", [BackupDir]),
|
||||
info("upgrades: Backing up mnesia dir to ~p", [BackupDir]),
|
||||
case rabbit_mnesia:copy_db(BackupDir) of
|
||||
ok -> info("upgrades: Mnesia dir backed up to ~p~n",
|
||||
ok -> info("upgrades: Mnesia dir backed up to ~p",
|
||||
[BackupDir]);
|
||||
{error, E} -> throw({could_not_back_up_mnesia_dir, E, BackupDir})
|
||||
end.
|
||||
|
|
@ -106,7 +106,7 @@ ensure_backup_removed() ->
|
|||
|
||||
remove_backup() ->
|
||||
ok = rabbit_file:recursive_delete([backup_dir()]),
|
||||
info("upgrades: Mnesia backup removed~n", []).
|
||||
info("upgrades: Mnesia backup removed", []).
|
||||
|
||||
-spec maybe_upgrade_mnesia() -> 'ok'.
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ primary_upgrade(Upgrades, Nodes) ->
|
|||
rabbit_table:force_load(),
|
||||
case Others of
|
||||
[] -> ok;
|
||||
_ -> info("mnesia upgrades: Breaking cluster~n", []),
|
||||
_ -> info("mnesia upgrades: Breaking cluster", []),
|
||||
[{atomic, ok} = mnesia:del_table_copy(schema, Node)
|
||||
|| Node <- Others]
|
||||
end
|
||||
|
|
@ -280,16 +280,16 @@ maybe_migrate_queues_to_per_vhost_storage() ->
|
|||
|
||||
apply_upgrades(Scope, Upgrades, Fun) ->
|
||||
ok = rabbit_file:lock_file(lock_filename()),
|
||||
info("~s upgrades: ~w to apply~n", [Scope, length(Upgrades)]),
|
||||
info("~s upgrades: ~w to apply", [Scope, length(Upgrades)]),
|
||||
rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia),
|
||||
Fun(),
|
||||
[apply_upgrade(Scope, Upgrade) || Upgrade <- Upgrades],
|
||||
info("~s upgrades: All upgrades applied successfully~n", [Scope]),
|
||||
info("~s upgrades: All upgrades applied successfully", [Scope]),
|
||||
ok = rabbit_version:record_desired_for_scope(Scope),
|
||||
ok = file:delete(lock_filename()).
|
||||
|
||||
apply_upgrade(Scope, {M, F}) ->
|
||||
info("~s upgrades: Applying ~w:~w~n", [Scope, M, F]),
|
||||
info("~s upgrades: Applying ~w:~w", [Scope, M, F]),
|
||||
ok = apply(M, F, []).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -426,9 +426,9 @@ cluster_name_tx() ->
|
|||
case Tl of
|
||||
[] -> ok;
|
||||
_ -> {VHost, _, _} = K,
|
||||
error_logger:warning_msg(
|
||||
logger:warning(
|
||||
"Multiple local-nodenames found, picking '~s' "
|
||||
"from '~s' for cluster name~n", [Name, VHost])
|
||||
"from '~s' for cluster name", [Name, VHost])
|
||||
end
|
||||
end,
|
||||
[mnesia:delete(T, K, write) || K <- Ks],
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ stop(VHost) ->
|
|||
ok = rabbit_queue_index:stop(VHost).
|
||||
|
||||
start_msg_store(VHost, Refs, StartFunState) when is_list(Refs); Refs == undefined ->
|
||||
rabbit_log:info("Starting message stores for vhost '~s'~n", [VHost]),
|
||||
rabbit_log:info("Starting message stores for vhost '~s'", [VHost]),
|
||||
do_start_msg_store(VHost, ?TRANSIENT_MSG_STORE, undefined, ?EMPTY_START_FUN_STATE),
|
||||
do_start_msg_store(VHost, ?PERSISTENT_MSG_STORE, Refs, StartFunState),
|
||||
ok.
|
||||
|
|
@ -492,13 +492,13 @@ start_msg_store(VHost, Refs, StartFunState) when is_list(Refs); Refs == undefine
|
|||
do_start_msg_store(VHost, Type, Refs, StartFunState) ->
|
||||
case rabbit_vhost_msg_store:start(VHost, Type, Refs, StartFunState) of
|
||||
{ok, _} ->
|
||||
rabbit_log:info("Started message store of type ~s for vhost '~s'~n", [abbreviated_type(Type), VHost]);
|
||||
rabbit_log:info("Started message store of type ~s for vhost '~s'", [abbreviated_type(Type), VHost]);
|
||||
{error, {no_such_vhost, VHost}} = Err ->
|
||||
rabbit_log:error("Failed to start message store of type ~s for vhost '~s': the vhost no longer exists!~n",
|
||||
rabbit_log:error("Failed to start message store of type ~s for vhost '~s': the vhost no longer exists!",
|
||||
[Type, VHost]),
|
||||
exit(Err);
|
||||
{error, Error} ->
|
||||
rabbit_log:error("Failed to start message store of type ~s for vhost '~s': ~p~n",
|
||||
rabbit_log:error("Failed to start message store of type ~s for vhost '~s': ~p",
|
||||
[Type, VHost, Error]),
|
||||
exit({error, Error})
|
||||
end.
|
||||
|
|
@ -2846,7 +2846,7 @@ move_messages_to_vhost_store(Queues) ->
|
|||
in_batches(MigrationBatchSize,
|
||||
{rabbit_variable_queue, migrate_queue, [OldStore, NewMsgStore]},
|
||||
QueuesWithTerms,
|
||||
"message_store upgrades: Migrating batch ~p of ~p queues. Out of total ~p ~n",
|
||||
"message_store upgrades: Migrating batch ~p of ~p queues. Out of total ~p ",
|
||||
"message_store upgrades: Batch ~p of ~p queues migrated ~n. ~p total left"),
|
||||
|
||||
log_upgrade("Message store migration finished"),
|
||||
|
|
@ -2882,7 +2882,7 @@ migrate_queue({QueueName = #resource{virtual_host = VHost, name = Name},
|
|||
RecoveryTerm},
|
||||
OldStore, NewStore) ->
|
||||
log_upgrade_verbose(
|
||||
"Migrating messages in queue ~s in vhost ~s to per-vhost message store~n",
|
||||
"Migrating messages in queue ~s in vhost ~s to per-vhost message store",
|
||||
[Name, VHost]),
|
||||
OldStoreClient = get_global_store_client(OldStore),
|
||||
NewStoreClient = get_per_vhost_store_client(QueueName, NewStore),
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ recover() ->
|
|||
|
||||
recover(VHost) ->
|
||||
VHostDir = msg_store_dir_path(VHost),
|
||||
rabbit_log:info("Making sure data directory '~ts' for vhost '~s' exists~n",
|
||||
rabbit_log:info("Making sure data directory '~ts' for vhost '~s' exists",
|
||||
[VHostDir, VHost]),
|
||||
VHostStubFile = filename:join(VHostDir, ".vhost"),
|
||||
ok = rabbit_file:ensure_dir(VHostStubFile),
|
||||
|
|
@ -147,7 +147,7 @@ delete(VHost, ActingUser) ->
|
|||
%% process, which in turn results in further mnesia actions and
|
||||
%% eventually the termination of that process. Exchange deletion causes
|
||||
%% notifications which must be sent outside the TX
|
||||
rabbit_log:info("Deleting vhost '~s'~n", [VHost]),
|
||||
rabbit_log:info("Deleting vhost '~s'", [VHost]),
|
||||
QDelFun = fun (Q) -> rabbit_amqqueue:delete(Q, false, false, ActingUser) end,
|
||||
[begin
|
||||
Name = amqqueue:get_name(Q),
|
||||
|
|
@ -257,7 +257,7 @@ vhost_down(VHost) ->
|
|||
|
||||
delete_storage(VHost) ->
|
||||
VhostDir = msg_store_dir_path(VHost),
|
||||
rabbit_log:info("Deleting message store directory for vhost '~s' at '~s'~n", [VHost, VhostDir]),
|
||||
rabbit_log:info("Deleting message store directory for vhost '~s' at '~s'", [VHost, VhostDir]),
|
||||
%% Message store should be closed when vhost supervisor is closed.
|
||||
case rabbit_file:recursive_delete([VhostDir]) of
|
||||
ok -> ok;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ start_link(VHost) ->
|
|||
|
||||
init([VHost]) ->
|
||||
process_flag(trap_exit, true),
|
||||
rabbit_log:debug("Recovering data for VHost ~p~n", [VHost]),
|
||||
rabbit_log:debug("Recovering data for VHost ~p", [VHost]),
|
||||
try
|
||||
%% Recover the vhost data and save it to vhost registry.
|
||||
ok = rabbit_vhost:recover(VHost),
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ stop_and_delete_vhost(VHost) ->
|
|||
false -> ok;
|
||||
true ->
|
||||
rabbit_log:info("Stopping vhost supervisor ~p"
|
||||
" for vhost '~s'~n",
|
||||
" for vhost '~s'",
|
||||
[VHostSupPid, VHost]),
|
||||
case supervisor2:terminate_child(?MODULE, WrapperPid) of
|
||||
ok ->
|
||||
|
|
|
|||
|
|
@ -65,9 +65,7 @@ start_link(IPAddress, Port,
|
|||
|
||||
init({IPAddress, Port, {M,F,A} = OnStartup, OnShutdown, Label}) ->
|
||||
process_flag(trap_exit, true),
|
||||
error_logger:info_msg(
|
||||
"started ~s on ~s:~p~n",
|
||||
[Label, rabbit_misc:ntoab(IPAddress), Port]),
|
||||
logger:info("started ~s on ~s:~p", [Label, rabbit_misc:ntoab(IPAddress), Port]),
|
||||
apply(M, F, A ++ [IPAddress, Port]),
|
||||
{ok, #state{on_startup = OnStartup, on_shutdown = OnShutdown,
|
||||
label = Label, ip=IPAddress, port=Port}}.
|
||||
|
|
@ -82,8 +80,7 @@ handle_info(_Info, State) ->
|
|||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, #state{on_shutdown = {M,F,A}, label=Label, ip=IPAddress, port=Port}) ->
|
||||
error_logger:info_msg("stopped ~s on ~s:~p~n",
|
||||
[Label, rabbit_misc:ntoab(IPAddress), Port]),
|
||||
logger:info("stopped ~s on ~s:~p", [Label, rabbit_misc:ntoab(IPAddress), Port]),
|
||||
apply(M, F, A ++ [IPAddress, Port]).
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
|
|
|
|||
|
|
@ -141,20 +141,7 @@ init_per_testcase(Testcase, Config) ->
|
|||
TestNumber = rabbit_ct_helpers:testcase_number(Config, ?MODULE, Testcase),
|
||||
case ?config(tc_group_properties, Config) of
|
||||
[{name, registry} | _] ->
|
||||
application:set_env(lager, colored, true),
|
||||
application:set_env(
|
||||
lager,
|
||||
handlers, [{lager_console_backend, [{level, debug}]}]),
|
||||
application:set_env(
|
||||
lager,
|
||||
extra_sinks,
|
||||
[{rabbit_log_lager_event,
|
||||
[{handlers, [{lager_console_backend, [{level, debug}]}]}]
|
||||
},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers, [{lager_console_backend, [{level, debug}]}]}]
|
||||
}]),
|
||||
lager:start(),
|
||||
logger:set_primary_config(level, debug),
|
||||
FeatureFlagsFile = filename:join(?config(priv_dir, Config),
|
||||
rabbit_misc:format(
|
||||
"feature_flags-~s",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,642 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2016-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(logging_SUITE).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-include_lib("kernel/include/logger.hrl").
|
||||
-include_lib("rabbit_common/include/logging.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
|
||||
-export([all/0,
|
||||
init_per_suite/1,
|
||||
end_per_suite/1,
|
||||
init_per_group/2,
|
||||
end_per_group/2,
|
||||
init_per_testcase/2,
|
||||
end_per_testcase/2,
|
||||
|
||||
logging_with_default_config_works/1,
|
||||
logging_to_stdout_configured_in_env_works/1,
|
||||
logging_to_stdout_configured_in_config_works/1,
|
||||
logging_to_stderr_configured_in_env_works/1,
|
||||
logging_to_exchange_works/1,
|
||||
setting_log_levels_in_env_works/1,
|
||||
setting_log_levels_in_config_works/1,
|
||||
format_messages_as_json_works/1]).
|
||||
|
||||
all() ->
|
||||
[logging_with_default_config_works,
|
||||
logging_to_stdout_configured_in_env_works,
|
||||
logging_to_stdout_configured_in_config_works,
|
||||
logging_to_stderr_configured_in_env_works,
|
||||
logging_to_exchange_works,
|
||||
setting_log_levels_in_env_works,
|
||||
setting_log_levels_in_config_works,
|
||||
format_messages_as_json_works].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
rabbit_ct_helpers:log_environment(),
|
||||
rabbit_ct_helpers:run_setup_steps(Config).
|
||||
|
||||
end_per_suite(Config) ->
|
||||
Config.
|
||||
|
||||
init_per_group(_, Config) ->
|
||||
Config.
|
||||
|
||||
end_per_group(_, Config) ->
|
||||
Config.
|
||||
|
||||
init_per_testcase(logging_to_exchange_works = Testcase, Config) ->
|
||||
rabbit_ct_helpers:testcase_started(Config, Testcase),
|
||||
Config1 = rabbit_ct_helpers:set_config(
|
||||
Config,
|
||||
[{rmq_nodes_count, 1},
|
||||
{rmq_nodename_suffix, Testcase}]),
|
||||
Config2 = rabbit_ct_helpers:merge_app_env(
|
||||
Config1,
|
||||
{rabbit, [{log, [{exchange, [{enabled, true},
|
||||
{level, info}]},
|
||||
{file, [{level, info}]}]}]}),
|
||||
rabbit_ct_helpers:run_steps(
|
||||
Config2,
|
||||
rabbit_ct_broker_helpers:setup_steps() ++
|
||||
rabbit_ct_client_helpers:setup_steps());
|
||||
init_per_testcase(Testcase, Config) ->
|
||||
remove_all_handlers(),
|
||||
application:unset_env(rabbit, log),
|
||||
LogBaseDir = filename:join(
|
||||
?config(priv_dir, Config),
|
||||
atom_to_list(Testcase)),
|
||||
Config1 = rabbit_ct_helpers:set_config(
|
||||
Config, {log_base_dir, LogBaseDir}),
|
||||
rabbit_ct_helpers:testcase_finished(Config1, Testcase).
|
||||
|
||||
end_per_testcase(logging_to_exchange_works, Config) ->
|
||||
rabbit_ct_helpers:run_steps(
|
||||
Config,
|
||||
rabbit_ct_client_helpers:teardown_steps() ++
|
||||
rabbit_ct_broker_helpers:teardown_steps());
|
||||
end_per_testcase(_, Config) ->
|
||||
application:unset_env(rabbit, log),
|
||||
Config.
|
||||
|
||||
remove_all_handlers() ->
|
||||
_ = [logger:remove_handler(Id)
|
||||
|| #{id := Id} <- logger:get_handler_config()].
|
||||
|
||||
logging_with_default_config_works(Config) ->
|
||||
Context = default_context(Config),
|
||||
rabbit_prelaunch_logging:clear_config_run_number(),
|
||||
rabbit_prelaunch_logging:setup(Context),
|
||||
|
||||
Handlers = logger:get_handler_config(),
|
||||
|
||||
MainFileHandler = get_handler_by_id(Handlers, rmq_1_file_1),
|
||||
MainFile = main_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, MainFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := info,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := MainFile}},
|
||||
MainFileHandler),
|
||||
|
||||
UpgradeFileHandler = get_handler_by_id(Handlers, rmq_1_file_2),
|
||||
UpgradeFile = upgrade_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, UpgradeFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := stop,
|
||||
filters := [{rmqlog_filter, {_, #{upgrade := info}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := UpgradeFile}},
|
||||
UpgradeFileHandler),
|
||||
|
||||
?assert(ping_log(rmq_1_file_1, info)),
|
||||
?assert(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
?assert(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ['3rd_party']})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
|
||||
?assert(ping_log(rmq_1_file_2, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
?assertNot(ping_log(rmq_1_file_2, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
ok.
|
||||
|
||||
logging_to_stdout_configured_in_env_works(Config) ->
|
||||
#{var_origins := Origins0} = Context0 = default_context(Config),
|
||||
Context = Context0#{main_log_file => "-",
|
||||
var_origins => Origins0#{
|
||||
main_log_file => environment}},
|
||||
logging_to_stddev_works(standard_io, rmq_1_stdout, Config, Context).
|
||||
|
||||
logging_to_stdout_configured_in_config_works(Config) ->
|
||||
Context = default_context(Config),
|
||||
ok = application:set_env(
|
||||
rabbit, log,
|
||||
[{console, [{enabled, true}]}],
|
||||
[{persistent, true}]),
|
||||
logging_to_stddev_works(standard_io, rmq_1_stdout, Config, Context).
|
||||
|
||||
logging_to_stderr_configured_in_env_works(Config) ->
|
||||
#{var_origins := Origins0} = Context0 = default_context(Config),
|
||||
Context = Context0#{main_log_file => "-stderr",
|
||||
var_origins => Origins0#{
|
||||
main_log_file => environment}},
|
||||
logging_to_stddev_works(standard_error, rmq_1_stderr, Config, Context).
|
||||
|
||||
logging_to_stddev_works(Stddev, Id, Config, Context) ->
|
||||
rabbit_prelaunch_logging:clear_config_run_number(),
|
||||
rabbit_prelaunch_logging:setup(Context),
|
||||
|
||||
Handlers = logger:get_handler_config(),
|
||||
|
||||
StddevHandler = get_handler_by_id(Handlers, Id),
|
||||
?assertNotEqual(undefined, StddevHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := info,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := Stddev}},
|
||||
StddevHandler),
|
||||
|
||||
UpgradeFileHandler = get_handler_by_id(Handlers, rmq_1_file_1),
|
||||
UpgradeFile = upgrade_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, UpgradeFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := stop,
|
||||
filters := [{rmqlog_filter, {_, #{upgrade := info}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := UpgradeFile}},
|
||||
UpgradeFileHandler),
|
||||
|
||||
?assert(ping_log(Id, info, Config)),
|
||||
?assert(ping_log(Id, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}, Config)),
|
||||
?assert(ping_log(Id, info,
|
||||
#{domain => ['3rd_party']}, Config)),
|
||||
?assertNot(ping_log(Id, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE}, Config)),
|
||||
|
||||
?assert(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
ok.
|
||||
|
||||
logging_to_exchange_works(Config) ->
|
||||
Context = rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
rabbit_prelaunch, get_context, []),
|
||||
Handlers = rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
logger, get_handler_config, []),
|
||||
|
||||
ExchangeHandler = get_handler_by_id(Handlers, rmq_1_exchange),
|
||||
?assertNotEqual(undefined, ExchangeHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_exchange_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := info,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{exchange := _}},
|
||||
ExchangeHandler),
|
||||
#{config :=
|
||||
#{exchange := #resource{name = XName} = Exchange}} = ExchangeHandler,
|
||||
|
||||
UpgradeFileHandler = get_handler_by_id(Handlers, rmq_1_file_2),
|
||||
UpgradeFile = upgrade_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, UpgradeFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := stop,
|
||||
filters := [{rmqlog_filter, {_, #{upgrade := info}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := UpgradeFile}},
|
||||
UpgradeFileHandler),
|
||||
|
||||
%% Wait for the expected exchange to be automatically declared.
|
||||
lists:any(
|
||||
fun(_) ->
|
||||
Ret = rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
rabbit_exchange, lookup, [Exchange]),
|
||||
case Ret of
|
||||
{ok, _} -> true;
|
||||
_ -> timer:sleep(500),
|
||||
false
|
||||
end
|
||||
end, lists:seq(1, 20)),
|
||||
|
||||
%% Declare a queue to collect all logged messages.
|
||||
{Conn, Chan} = rabbit_ct_client_helpers:open_connection_and_channel(
|
||||
Config),
|
||||
QName = <<"log-messages">>,
|
||||
?assertMatch(
|
||||
#'queue.declare_ok'{},
|
||||
amqp_channel:call(Chan, #'queue.declare'{queue = QName,
|
||||
durable = false})),
|
||||
?assertMatch(
|
||||
#'queue.bind_ok'{},
|
||||
amqp_channel:call(Chan, #'queue.bind'{queue = QName,
|
||||
exchange = XName,
|
||||
routing_key = <<"#">>})),
|
||||
Config1 = rabbit_ct_helpers:set_config(
|
||||
Config, {test_channel_and_queue, {Chan, QName}}),
|
||||
|
||||
?assert(ping_log(rmq_1_exchange, info, Config1)),
|
||||
?assert(ping_log(rmq_1_exchange, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}, Config1)),
|
||||
?assert(ping_log(rmq_1_exchange, info,
|
||||
#{domain => ['3rd_party']}, Config1)),
|
||||
?assertNot(ping_log(rmq_1_exchange, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE}, Config1)),
|
||||
|
||||
?assert(ping_log(rmq_1_file_2, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE}, Config)),
|
||||
?assertNot(ping_log(rmq_1_file_2, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL}, Config)),
|
||||
|
||||
amqp_channel:call(Chan, #'queue.delete'{queue = QName}),
|
||||
rabbit_ct_client_helpers:close_connection_and_channel(Conn, Chan),
|
||||
ok.
|
||||
|
||||
setting_log_levels_in_env_works(Config) ->
|
||||
GlobalLevel = warning,
|
||||
PrelaunchLevel = error,
|
||||
MinLevel = rabbit_prelaunch_logging:get_less_severe_level(
|
||||
GlobalLevel, PrelaunchLevel),
|
||||
#{var_origins := Origins0} = Context0 = default_context(Config),
|
||||
Context = Context0#{log_levels => #{global => GlobalLevel,
|
||||
"prelaunch" => PrelaunchLevel},
|
||||
var_origins => Origins0#{log_levels => environment}},
|
||||
rabbit_prelaunch_logging:clear_config_run_number(),
|
||||
rabbit_prelaunch_logging:setup(Context),
|
||||
|
||||
Handlers = logger:get_handler_config(),
|
||||
|
||||
MainFileHandler = get_handler_by_id(Handlers, rmq_1_file_1),
|
||||
MainFile = main_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, MainFileHandler),
|
||||
?assertMatch(
|
||||
#{level := MinLevel,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := GlobalLevel,
|
||||
prelaunch := PrelaunchLevel,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := MainFile}},
|
||||
MainFileHandler),
|
||||
|
||||
UpgradeFileHandler = get_handler_by_id(Handlers, rmq_1_file_2),
|
||||
UpgradeFile = upgrade_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, UpgradeFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := stop,
|
||||
filters := [{rmqlog_filter, {_, #{upgrade := info}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := UpgradeFile}},
|
||||
UpgradeFileHandler),
|
||||
|
||||
?assertNot(ping_log(rmq_1_file_1, info)),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assertNot(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ['3rd_party']})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel)),
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
?assert(ping_log(rmq_1_file_1, PrelaunchLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ['3rd_party']})),
|
||||
?assertNot(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
|
||||
?assert(ping_log(rmq_1_file_2, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
?assertNot(ping_log(rmq_1_file_2, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
ok.
|
||||
|
||||
setting_log_levels_in_config_works(Config) ->
|
||||
GlobalLevel = warning,
|
||||
PrelaunchLevel = error,
|
||||
MinLevel = rabbit_prelaunch_logging:get_less_severe_level(
|
||||
GlobalLevel, PrelaunchLevel),
|
||||
Context = default_context(Config),
|
||||
ok = application:set_env(
|
||||
rabbit, log,
|
||||
[{file, [{level, GlobalLevel}]},
|
||||
{categories, [{prelaunch, [{level, PrelaunchLevel}]}]}],
|
||||
[{persistent, true}]),
|
||||
rabbit_prelaunch_logging:clear_config_run_number(),
|
||||
rabbit_prelaunch_logging:setup(Context),
|
||||
|
||||
Handlers = logger:get_handler_config(),
|
||||
|
||||
MainFileHandler = get_handler_by_id(Handlers, rmq_1_file_1),
|
||||
MainFile = main_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, MainFileHandler),
|
||||
?assertMatch(
|
||||
#{level := MinLevel,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := GlobalLevel,
|
||||
prelaunch := PrelaunchLevel,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := MainFile}},
|
||||
MainFileHandler),
|
||||
|
||||
UpgradeFileHandler = get_handler_by_id(Handlers, rmq_1_file_2),
|
||||
UpgradeFile = upgrade_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, UpgradeFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := stop,
|
||||
filters := [{rmqlog_filter, {_, #{upgrade := info}}}],
|
||||
formatter := {rabbit_logger_text_fmt, _},
|
||||
config := #{type := file,
|
||||
file := UpgradeFile}},
|
||||
UpgradeFileHandler),
|
||||
|
||||
?assertNot(ping_log(rmq_1_file_1, info)),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assertNot(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ['3rd_party']})),
|
||||
?assertNot(ping_log(rmq_1_file_1, info,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel)),
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
?assert(ping_log(rmq_1_file_1, PrelaunchLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_PRELAUNCH})),
|
||||
?assert(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ['3rd_party']})),
|
||||
?assertNot(ping_log(rmq_1_file_1, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
|
||||
?assert(ping_log(rmq_1_file_2, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_UPGRADE})),
|
||||
?assertNot(ping_log(rmq_1_file_2, GlobalLevel,
|
||||
#{domain => ?RMQLOG_DOMAIN_GLOBAL})),
|
||||
ok.
|
||||
|
||||
format_messages_as_json_works(Config) ->
|
||||
#{var_origins := Origins0} = Context0 = default_context(Config),
|
||||
Context = Context0#{log_levels => #{json => true},
|
||||
var_origins => Origins0#{log_levels => environment}},
|
||||
rabbit_prelaunch_logging:clear_config_run_number(),
|
||||
rabbit_prelaunch_logging:setup(Context),
|
||||
|
||||
Handlers = logger:get_handler_config(),
|
||||
|
||||
MainFileHandler = get_handler_by_id(Handlers, rmq_1_file_1),
|
||||
MainFile = main_log_file_in_context(Context),
|
||||
?assertNotEqual(undefined, MainFileHandler),
|
||||
?assertMatch(
|
||||
#{level := info,
|
||||
module := rabbit_logger_std_h,
|
||||
filter_default := log,
|
||||
filters := [{progress_reports, {_, stop}},
|
||||
{rmqlog_filter, {_, #{global := info,
|
||||
upgrade := none}}}],
|
||||
formatter := {rabbit_logger_json_fmt, _},
|
||||
config := #{type := file,
|
||||
file := MainFile}},
|
||||
MainFileHandler),
|
||||
|
||||
?assertNot(ping_log(rmq_1_file_1, info)),
|
||||
|
||||
RandomMsg = get_random_string(
|
||||
32,
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
|
||||
Metadata = #{atom => rabbit,
|
||||
integer => 1,
|
||||
float => 1.42,
|
||||
string => "string",
|
||||
list => ["s", a, 3],
|
||||
map => #{key => "value"},
|
||||
function => fun get_random_string/2,
|
||||
pid => self(),
|
||||
port => hd(erlang:ports()),
|
||||
ref => erlang:make_ref()},
|
||||
?LOG_INFO(RandomMsg, Metadata),
|
||||
|
||||
rabbit_logger_std_h:filesync(rmq_1_file_1),
|
||||
{ok, Content} = file:read_file(MainFile),
|
||||
ReOpts = [{capture, first, binary}, multiline],
|
||||
{match, [Line]} = re:run(
|
||||
Content,
|
||||
"^.+\"" ++ RandomMsg ++ "\".+$",
|
||||
ReOpts),
|
||||
Term = jsx:decode(Line, [return_maps, {labels, attempt_atom}]),
|
||||
|
||||
RandomMsgBin = list_to_binary(RandomMsg),
|
||||
?assertMatch(#{time := _}, Term),
|
||||
?assertMatch(#{level := <<"info">>}, Term),
|
||||
?assertMatch(#{msg := RandomMsgBin}, Term),
|
||||
|
||||
Meta = maps:get(meta, Term),
|
||||
FunBin = list_to_binary(erlang:fun_to_list(maps:get(function, Metadata))),
|
||||
PidBin = list_to_binary(erlang:pid_to_list(maps:get(pid, Metadata))),
|
||||
PortBin = list_to_binary(erlang:port_to_list(maps:get(port, Metadata))),
|
||||
RefBin = list_to_binary(erlang:ref_to_list(maps:get(ref, Metadata))),
|
||||
?assertMatch(#{atom := <<"rabbit">>}, Meta),
|
||||
?assertMatch(#{integer := 1}, Meta),
|
||||
?assertMatch(#{float := 1.42}, Meta),
|
||||
?assertMatch(#{string := <<"string">>}, Meta),
|
||||
?assertMatch(#{list := [<<"s">>, <<"a">>, 3]}, Meta),
|
||||
?assertMatch(#{map := #{key := <<"value">>}}, Meta),
|
||||
?assertMatch(#{function := FunBin}, Meta),
|
||||
?assertMatch(#{pid := PidBin}, Meta),
|
||||
?assertMatch(#{port := PortBin}, Meta),
|
||||
?assertMatch(#{ref := RefBin}, Meta).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Internal functions.
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
default_context(Config) ->
|
||||
LogBaseDir = ?config(log_base_dir, Config),
|
||||
MainFile = "rabbit.log",
|
||||
UpgradeFile = "rabbit_upgrade.log",
|
||||
#{log_base_dir => LogBaseDir,
|
||||
main_log_file => MainFile,
|
||||
upgrade_log_file => UpgradeFile,
|
||||
log_levels => undefined,
|
||||
var_origins => #{log_base_dir => default,
|
||||
main_log_file => default,
|
||||
upgrade_log_file => default,
|
||||
log_levels => default}}.
|
||||
|
||||
main_log_file_in_context(#{log_base_dir := LogBaseDir,
|
||||
main_log_file := MainLogFile}) ->
|
||||
filename:join(LogBaseDir, MainLogFile).
|
||||
|
||||
upgrade_log_file_in_context(#{log_base_dir := LogBaseDir,
|
||||
upgrade_log_file := UpgradeLogFile}) ->
|
||||
filename:join(LogBaseDir, UpgradeLogFile).
|
||||
|
||||
get_handler_by_id([#{id := Id} = Handler | _], Id) ->
|
||||
Handler;
|
||||
get_handler_by_id([_ | Rest], Id) ->
|
||||
get_handler_by_id(Rest, Id);
|
||||
get_handler_by_id([], _) ->
|
||||
undefined.
|
||||
|
||||
ping_log(Id, Level) ->
|
||||
ping_log(Id, Level, #{}, []).
|
||||
|
||||
ping_log(Id, Level, Metadata) when is_map(Metadata) ->
|
||||
ping_log(Id, Level, Metadata, []);
|
||||
ping_log(Id, Level, Config) when is_list(Config) ->
|
||||
ping_log(Id, Level, #{}, Config).
|
||||
|
||||
ping_log(Id, Level, Metadata, Config) ->
|
||||
RandomMsg = get_random_string(
|
||||
32,
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
|
||||
ct:log("Logging \"~ts\" at level ~ts (~p)", [RandomMsg, Level, Metadata]),
|
||||
case need_rpc(Config) of
|
||||
false -> logger:log(Level, RandomMsg, Metadata);
|
||||
true -> rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
logger, log, [Level, RandomMsg, Metadata])
|
||||
end,
|
||||
check_log(Id, RandomMsg, Config).
|
||||
|
||||
need_rpc(Config) ->
|
||||
rabbit_ct_helpers:get_config(
|
||||
Config, rmq_nodes_count) =/= undefined.
|
||||
|
||||
check_log(Id, RandomMsg, Config) ->
|
||||
{ok, Handler} = case need_rpc(Config) of
|
||||
false -> logger:get_handler_config(Id);
|
||||
true -> rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
logger, get_handler_config, [Id])
|
||||
end,
|
||||
check_log1(Handler, RandomMsg, Config).
|
||||
|
||||
check_log1(#{id := Id,
|
||||
module := rabbit_logger_std_h,
|
||||
config := #{type := file,
|
||||
file := Filename}},
|
||||
RandomMsg,
|
||||
Config) ->
|
||||
ok = case need_rpc(Config) of
|
||||
false -> rabbit_logger_std_h:filesync(Id);
|
||||
true -> rabbit_ct_broker_helpers:rpc(
|
||||
Config, 0,
|
||||
rabbit_logger_std_h, filesync, [Id])
|
||||
end,
|
||||
{ok, Content} = file:read_file(Filename),
|
||||
ReOpts = [{capture, none}, multiline],
|
||||
match =:= re:run(Content, RandomMsg ++ "$", ReOpts);
|
||||
check_log1(#{module := Mod,
|
||||
config := #{type := Stddev}},
|
||||
RandomMsg,
|
||||
Config)
|
||||
when ?IS_STD_H_COMPAT(Mod) andalso ?IS_STDDEV(Stddev) ->
|
||||
Filename = html_report_filename(Config),
|
||||
ReOpts = [{capture, none}, multiline],
|
||||
lists:any(
|
||||
fun(_) ->
|
||||
{ok, Content} = file:read_file(Filename),
|
||||
case re:run(Content, RandomMsg ++ "$", ReOpts) of
|
||||
match -> true;
|
||||
_ -> timer:sleep(500),
|
||||
false
|
||||
end
|
||||
end, lists:seq(1, 10));
|
||||
check_log1(#{module := rabbit_logger_exchange_h},
|
||||
RandomMsg,
|
||||
Config) ->
|
||||
{Chan, QName} = ?config(test_channel_and_queue, Config),
|
||||
ReOpts = [{capture, none}, multiline],
|
||||
lists:any(
|
||||
fun(_) ->
|
||||
Ret = amqp_channel:call(
|
||||
Chan, #'basic.get'{queue = QName, no_ack = false}),
|
||||
case Ret of
|
||||
{#'basic.get_ok'{}, #amqp_msg{payload = Content}} ->
|
||||
case re:run(Content, RandomMsg ++ "$", ReOpts) of
|
||||
match -> true;
|
||||
_ -> timer:sleep(500),
|
||||
false
|
||||
end;
|
||||
#'basic.get_empty'{} ->
|
||||
timer:sleep(500),
|
||||
false;
|
||||
Other ->
|
||||
io:format(standard_error, "OTHER -> ~p~n", [Other]),
|
||||
timer:sleep(500),
|
||||
false
|
||||
end
|
||||
end, lists:seq(1, 10)).
|
||||
|
||||
get_random_string(Length, AllowedChars) ->
|
||||
lists:foldl(fun(_, Acc) ->
|
||||
[lists:nth(rand:uniform(length(AllowedChars)),
|
||||
AllowedChars)]
|
||||
++ Acc
|
||||
end, [], lists:seq(1, Length)).
|
||||
|
||||
html_report_filename(Config) ->
|
||||
?config(tc_logfile, Config).
|
||||
|
|
@ -1,838 +0,0 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2016-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(unit_log_config_SUITE).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
all() ->
|
||||
[
|
||||
default,
|
||||
env_var_tty,
|
||||
config_file_handler,
|
||||
config_file_handler_level,
|
||||
config_file_handler_rotation,
|
||||
config_console_handler,
|
||||
config_exchange_handler,
|
||||
config_syslog_handler,
|
||||
config_syslog_handler_options,
|
||||
config_multiple_handlers,
|
||||
|
||||
env_var_overrides_config,
|
||||
env_var_disable_log,
|
||||
|
||||
config_sinks_level,
|
||||
config_sink_file,
|
||||
config_sink_file_override_config_handler_file,
|
||||
|
||||
config_handlers_merged_with_lager_handlers,
|
||||
sink_handlers_merged_with_lager_extra_sinks_handlers,
|
||||
sink_file_rewrites_file_backends
|
||||
].
|
||||
|
||||
init_per_testcase(_, Config) ->
|
||||
application:load(rabbit),
|
||||
application:load(lager),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(rabbit, lager_log_root),
|
||||
application:unset_env(rabbit, lager_default_file),
|
||||
application:unset_env(rabbit, lager_upgrade_file),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, rabbit_handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
unset_logs_var_origin(),
|
||||
Config.
|
||||
|
||||
end_per_testcase(_, Config) ->
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(rabbit, lager_log_root),
|
||||
application:unset_env(rabbit, lager_default_file),
|
||||
application:unset_env(rabbit, lager_upgrade_file),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, rabbit_handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
unset_logs_var_origin(),
|
||||
application:unload(rabbit),
|
||||
application:unload(lager),
|
||||
Config.
|
||||
|
||||
sink_file_rewrites_file_backends(_) ->
|
||||
application:set_env(rabbit, log, [
|
||||
%% Disable rabbit file handler
|
||||
{file, [{file, false}]},
|
||||
{categories, [{federation, [{file, "federation.log"}, {level, warning}]}]}
|
||||
]),
|
||||
|
||||
LagerHandlers = [
|
||||
{lager_file_backend, [{file, "lager_file.log"}, {level, error}]},
|
||||
{lager_file_backend, [{file, "lager_file_1.log"}, {level, error}]},
|
||||
{lager_console_backend, [{level, info}]},
|
||||
{lager_exchange_backend, [{level, info}]}
|
||||
],
|
||||
application:set_env(lager, handlers, LagerHandlers),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedSinks = sort_sinks(sink_rewrite_sinks()),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
sink_rewrite_sinks() ->
|
||||
[{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "federation.log"},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, warning},
|
||||
{size, 0}]},
|
||||
{lager_console_backend, [{level, warning}]},
|
||||
{lager_exchange_backend, [{level, warning}]}
|
||||
]},
|
||||
{rabbit_handlers,[
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "federation.log"},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, warning},
|
||||
{size, 0}]},
|
||||
{lager_console_backend, [{level, warning}]},
|
||||
{lager_exchange_backend, [{level, warning}]}
|
||||
]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]}
|
||||
].
|
||||
|
||||
sink_handlers_merged_with_lager_extra_sinks_handlers(_) ->
|
||||
DefaultLevel = debug,
|
||||
application:set_env(rabbit, log, [
|
||||
{file, [{file, "rabbit_file.log"}, {level, DefaultLevel}]},
|
||||
{console, [{enabled, true}, {level, error}]},
|
||||
{exchange, [{enabled, true}, {level, error}]},
|
||||
{categories, [
|
||||
{connection, [{level, debug}]},
|
||||
{channel, [{level, warning}, {file, "channel_log.log"}]}
|
||||
]}
|
||||
]),
|
||||
|
||||
LagerSinks = [
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,
|
||||
[{lager_file_backend,
|
||||
[{file, "connection_lager.log"},
|
||||
{level, info}]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,
|
||||
[{lager_console_backend, [{level, debug}]},
|
||||
{lager_exchange_backend, [{level, debug}]},
|
||||
{lager_file_backend, [{level, error},
|
||||
{file, "channel_lager.log"}]}]}]}],
|
||||
|
||||
application:set_env(lager, extra_sinks, LagerSinks),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedSinks = sort_sinks([
|
||||
{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[
|
||||
{lager_console_backend, [{level, error},
|
||||
{formatter_config, formatter_config(console)}]},
|
||||
{lager_exchange_backend, [{level, error},
|
||||
{formatter_config, formatter_config(exchange)}]},
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "channel_log.log"},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, warning},
|
||||
{size, 0}]},
|
||||
{lager_console_backend, [{level, debug}]},
|
||||
{lager_exchange_backend, [{level, debug}]},
|
||||
{lager_file_backend, [{level, error},
|
||||
{file, "channel_lager.log"}]}
|
||||
]},
|
||||
{rabbit_handlers,[
|
||||
{lager_console_backend, [{level, error},
|
||||
{formatter_config, formatter_config(console)}]},
|
||||
{lager_exchange_backend, [{level, error},
|
||||
{formatter_config, formatter_config(exchange)}]},
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "channel_log.log"},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, warning},
|
||||
{size, 0}]}]}
|
||||
]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,debug]},
|
||||
{lager_file_backend, [{file, "connection_lager.log"}, {level, info}]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,debug]}]}]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]}]),
|
||||
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
config_handlers_merged_with_lager_handlers(_) ->
|
||||
application:set_env(rabbit, log, [
|
||||
{file, [{file, "rabbit_file.log"}, {level, debug}]},
|
||||
{console, [{enabled, true}, {level, error}]},
|
||||
{exchange, [{enabled, true}, {level, error}]},
|
||||
{syslog, [{enabled, true}]}
|
||||
]),
|
||||
|
||||
LagerHandlers = [
|
||||
{lager_file_backend, [{file, "lager_file.log"}, {level, info}]},
|
||||
{lager_console_backend, [{level, info}]},
|
||||
{lager_exchange_backend, [{level, info}]},
|
||||
{lager_exchange_backend, [{level, info}]}
|
||||
],
|
||||
application:set_env(lager, handlers, LagerHandlers),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
FileHandlers = default_expected_handlers("rabbit_file.log", debug),
|
||||
ConsoleHandlers = expected_console_handler(error),
|
||||
RabbitHandlers = expected_rabbit_handler(error),
|
||||
SyslogHandlers = expected_syslog_handler(),
|
||||
|
||||
ExpectedRabbitHandlers = sort_handlers(FileHandlers ++ ConsoleHandlers ++ RabbitHandlers ++ SyslogHandlers),
|
||||
ExpectedHandlers = sort_handlers(ExpectedRabbitHandlers ++ LagerHandlers),
|
||||
|
||||
?assertEqual(ExpectedRabbitHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))).
|
||||
|
||||
config_sinks_level(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
application:set_env(rabbit, log, [
|
||||
{categories, [
|
||||
{connection, [{level, warning}]},
|
||||
{channel, [{level, debug}]},
|
||||
{mirroring, [{level, error}]}
|
||||
]}
|
||||
]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedSinks = sort_sinks(level_sinks()),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
level_sinks() ->
|
||||
[{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,debug]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,debug]}]}]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,warning]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,warning]}]}]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,error]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,error]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,
|
||||
[lager_event,info]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]}
|
||||
].
|
||||
|
||||
config_sink_file(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
DefaultLevel = error,
|
||||
application:set_env(rabbit, log, [
|
||||
{console, [{enabled, true}]},
|
||||
{exchange, [{enabled, true}]},
|
||||
{file, [{level, DefaultLevel}]},
|
||||
{categories, [
|
||||
{connection, [{file, "connection.log"}, {level, warning}]}
|
||||
]}
|
||||
]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedSinks = sort_sinks(file_sinks(DefaultLevel)),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
config_sink_file_override_config_handler_file(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
NonDefaultLogFile = "rabbit_not_default.log",
|
||||
|
||||
DefaultLevel = error,
|
||||
application:set_env(rabbit, log, [
|
||||
{file, [{file, NonDefaultLogFile}, {level, DefaultLevel}]},
|
||||
{console, [{enabled, true}]},
|
||||
{exchange, [{enabled, true}]},
|
||||
{categories, [
|
||||
{connection, [{file, "connection.log"}, {level, warning}]}
|
||||
]}
|
||||
]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedSinks = sort_sinks(file_sinks(DefaultLevel)),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
file_sinks() ->
|
||||
file_sinks(info).
|
||||
|
||||
file_sinks(DefaultLevel) ->
|
||||
[{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[
|
||||
{lager_console_backend, [{level, warning},
|
||||
{formatter_config, formatter_config(console)}]},
|
||||
{lager_exchange_backend, [{level, warning},
|
||||
{formatter_config, formatter_config(exchange)}]},
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "connection.log"},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, error},
|
||||
{size, 0}]}]},
|
||||
{rabbit_handlers,[
|
||||
{lager_console_backend, [{level, warning},
|
||||
{formatter_config, formatter_config(console)}]},
|
||||
{lager_exchange_backend, [{level, warning},
|
||||
{formatter_config, formatter_config(exchange)}]},
|
||||
{lager_file_backend,
|
||||
[{date, ""},
|
||||
{file, "connection.log"},
|
||||
{formatter_config, formatter_config(backend)},
|
||||
{level, error},
|
||||
{size, 0}]}]}
|
||||
]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,DefaultLevel]}]}]}
|
||||
].
|
||||
|
||||
config_multiple_handlers(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
application:set_env(rabbit, log, [
|
||||
%% Disable file output
|
||||
{file, [{file, false}]},
|
||||
%% Enable console output
|
||||
{console, [{enabled, true}]},
|
||||
%% Enable exchange output
|
||||
{exchange, [{enabled, true}]},
|
||||
%% Enable a syslog output
|
||||
{syslog, [{enabled, true}, {level, error}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ConsoleHandlers = expected_console_handler(),
|
||||
RabbitHandlers = expected_rabbit_handler(),
|
||||
SyslogHandlers = expected_syslog_handler(error),
|
||||
|
||||
ExpectedHandlers = sort_handlers(SyslogHandlers ++ ConsoleHandlers ++ RabbitHandlers),
|
||||
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_console_handler(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
application:set_env(rabbit, log, [{console, [{enabled, true}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
FileHandlers = default_expected_handlers(DefaultLogFile),
|
||||
ConsoleHandlers = expected_console_handler(),
|
||||
|
||||
ExpectedHandlers = sort_handlers(FileHandlers ++ ConsoleHandlers),
|
||||
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_exchange_handler(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
application:set_env(rabbit, log, [{exchange, [{enabled, true}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
FileHandlers = default_expected_handlers(DefaultLogFile),
|
||||
ExchangeHandlers = expected_rabbit_handler(),
|
||||
|
||||
ExpectedHandlers = sort_handlers(FileHandlers ++ ExchangeHandlers),
|
||||
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
expected_console_handler() ->
|
||||
expected_console_handler(debug).
|
||||
|
||||
expected_console_handler(Level) ->
|
||||
[{lager_console_backend, [{level, Level},
|
||||
{formatter_config, formatter_config(console)}]}].
|
||||
|
||||
expected_rabbit_handler() ->
|
||||
expected_rabbit_handler(debug).
|
||||
|
||||
expected_rabbit_handler(Level) ->
|
||||
[{lager_exchange_backend, [{level, Level},
|
||||
{formatter_config, formatter_config(exchange)}]}].
|
||||
|
||||
config_syslog_handler(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
application:set_env(rabbit, log, [{syslog, [{enabled, true}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
FileHandlers = default_expected_handlers(DefaultLogFile),
|
||||
SyslogHandlers = expected_syslog_handler(),
|
||||
|
||||
ExpectedHandlers = sort_handlers(FileHandlers ++ SyslogHandlers),
|
||||
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_syslog_handler_options(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
application:set_env(rabbit, log, [{syslog, [{enabled, true},
|
||||
{level, warning}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
FileHandlers = default_expected_handlers(DefaultLogFile),
|
||||
SyslogHandlers = expected_syslog_handler(warning),
|
||||
|
||||
ExpectedHandlers = sort_handlers(FileHandlers ++ SyslogHandlers),
|
||||
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
expected_syslog_handler() ->
|
||||
expected_syslog_handler(debug).
|
||||
|
||||
expected_syslog_handler(Level) ->
|
||||
[{syslog_lager_backend, [Level,
|
||||
{},
|
||||
{lager_default_formatter, syslog_formatter_config()}]}].
|
||||
|
||||
env_var_overrides_config(_) ->
|
||||
EnvLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, EnvLogFile),
|
||||
|
||||
ConfigLogFile = "rabbit_not_default.log",
|
||||
application:set_env(rabbit, log, [{file, [{file, ConfigLogFile}]}]),
|
||||
|
||||
set_logs_var_origin(environment),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = default_expected_handlers(EnvLogFile),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
env_var_disable_log(_) ->
|
||||
application:set_env(rabbit, lager_default_file, false),
|
||||
|
||||
ConfigLogFile = "rabbit_not_default.log",
|
||||
application:set_env(rabbit, log, [{file, [{file, ConfigLogFile}]}]),
|
||||
|
||||
set_logs_var_origin(environment),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = [],
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_file_handler(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
NonDefaultLogFile = "rabbit_not_default.log",
|
||||
application:set_env(rabbit, log, [{file, [{file, NonDefaultLogFile}]}]),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = default_expected_handlers(NonDefaultLogFile),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_file_handler_level(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
application:set_env(rabbit, log, [{file, [{level, warning}]}]),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = default_expected_handlers(DefaultLogFile, warning),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
config_file_handler_rotation(_) ->
|
||||
DefaultLogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, DefaultLogFile),
|
||||
|
||||
application:set_env(rabbit, log, [{file, [{date, "$D0"}, {size, 5000}, {count, 10}]}]),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = sort_handlers(default_expected_handlers(DefaultLogFile, debug, 5000, "$D0", [{count, 10}])),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))).
|
||||
|
||||
default(_) ->
|
||||
LogRoot = "/tmp/log_base",
|
||||
application:set_env(rabbit, lager_log_root, LogRoot),
|
||||
LogFile = "rabbit_default.log",
|
||||
application:set_env(rabbit, lager_default_file, LogFile),
|
||||
LogUpgradeFile = "rabbit_default_upgrade.log",
|
||||
application:set_env(rabbit, lager_upgrade_file, LogUpgradeFile),
|
||||
|
||||
?assertEqual(LogRoot, application:get_env(rabbit, lager_log_root, undefined)),
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = default_expected_handlers(LogFile),
|
||||
?assertEqual(LogRoot, application:get_env(lager, log_root, undefined)),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))),
|
||||
|
||||
ExpectedSinks = default_expected_sinks(LogUpgradeFile),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
default_expected_handlers(File) ->
|
||||
default_expected_handlers(File, debug, 0, "").
|
||||
default_expected_handlers(File, Level) ->
|
||||
default_expected_handlers(File, Level, 0, "").
|
||||
default_expected_handlers(File, Level, RotSize, RotDate) ->
|
||||
default_expected_handlers(File, Level, RotSize, RotDate, []).
|
||||
default_expected_handlers(File, Level, RotSize, RotDate, Extra) ->
|
||||
[{lager_file_backend,
|
||||
[{date, RotDate},
|
||||
{file, File},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level, Level},
|
||||
{size, RotSize}] ++ Extra}].
|
||||
|
||||
default_expected_sinks(UpgradeFile) ->
|
||||
[{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,
|
||||
[{lager_file_backend,
|
||||
[{date,[]},
|
||||
{file, UpgradeFile},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level,info},
|
||||
{size,0}]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_file_backend,
|
||||
[{date,[]},
|
||||
{file, UpgradeFile},
|
||||
{formatter_config, formatter_config(file)},
|
||||
{level,info},
|
||||
{size,0}]}]}]}].
|
||||
|
||||
env_var_tty(_) ->
|
||||
application:set_env(rabbit, lager_log_root, "/tmp/log_base"),
|
||||
application:set_env(rabbit, lager_default_file, tty),
|
||||
application:set_env(rabbit, lager_upgrade_file, tty),
|
||||
%% tty can only be set explicitly
|
||||
set_logs_var_origin(environment),
|
||||
|
||||
rabbit_lager:configure_lager(),
|
||||
|
||||
ExpectedHandlers = tty_expected_handlers(),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, handlers, undefined))),
|
||||
?assertEqual(ExpectedHandlers, sort_handlers(application:get_env(lager, rabbit_handlers, undefined))),
|
||||
|
||||
%% Upgrade sink will be different.
|
||||
ExpectedSinks = tty_expected_sinks(),
|
||||
?assertEqual(ExpectedSinks, sort_sinks(application:get_env(lager, extra_sinks, undefined))).
|
||||
|
||||
set_logs_var_origin(Origin) ->
|
||||
Context = #{var_origins => #{main_log_file => Origin}},
|
||||
rabbit_prelaunch:store_context(Context),
|
||||
ok.
|
||||
|
||||
unset_logs_var_origin() ->
|
||||
rabbit_prelaunch:clear_context_cache(),
|
||||
ok.
|
||||
|
||||
tty_expected_handlers() ->
|
||||
[{lager_console_backend,
|
||||
[{formatter_config, formatter_config(console)},
|
||||
{level, debug}]}].
|
||||
|
||||
tty_expected_sinks() ->
|
||||
[{error_logger_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_channel_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_connection_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_feature_flags_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_federation_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers, [{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ldap_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_mirroring_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_osiris_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_prelaunch_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_queue_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_ra_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_shovel_lager_event,
|
||||
[{handlers, [{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,
|
||||
[{lager_forwarder_backend,[lager_event,info]}]}]},
|
||||
{rabbit_log_upgrade_lager_event,
|
||||
[{handlers,[{lager_forwarder_backend,[lager_event,info]}]},
|
||||
{rabbit_handlers,[{lager_forwarder_backend,[lager_event,info]}]}]}].
|
||||
|
||||
sort_sinks(Sinks) ->
|
||||
lists:ukeysort(1,
|
||||
lists:map(
|
||||
fun({Name, Config}) ->
|
||||
Handlers = proplists:get_value(handlers, Config),
|
||||
RabbitHandlers = proplists:get_value(rabbit_handlers, Config),
|
||||
{Name, lists:ukeymerge(1,
|
||||
[{handlers, sort_handlers(Handlers)},
|
||||
{rabbit_handlers, sort_handlers(RabbitHandlers)}],
|
||||
lists:ukeysort(1, Config))}
|
||||
end,
|
||||
Sinks)).
|
||||
|
||||
sort_handlers(Handlers) ->
|
||||
lists:keysort(1,
|
||||
lists:map(
|
||||
fun
|
||||
({Name, [{Atom, _}|_] = Config}) when is_atom(Atom) ->
|
||||
{Name, lists:ukeysort(1, Config)};
|
||||
%% Non-proplist configuration. forwarder backend
|
||||
(Other) ->
|
||||
Other
|
||||
end,
|
||||
Handlers)).
|
||||
|
||||
formatter_config(console) ->
|
||||
[date," ",time," ",color,"[",severity, "] ", {pid,[]}, " ",message,"\r\n"];
|
||||
formatter_config(_) ->
|
||||
[date," ",time," ",color,"[",severity, "] ", {pid,[]}, " ",message,"\n"].
|
||||
|
||||
syslog_formatter_config() ->
|
||||
[color,"[",severity, "] ", {pid,[]}, " ",message,"\n"].
|
||||
|
|
@ -25,7 +25,6 @@ all() ->
|
|||
groups() ->
|
||||
[
|
||||
{non_parallel_tests, [], [
|
||||
log_management,
|
||||
log_file_initialised_during_startup,
|
||||
log_file_fails_to_initialise_during_startup,
|
||||
externally_rotated_logs_are_automatically_reopened
|
||||
|
|
@ -113,94 +112,6 @@ wait_for_application(Application, Time) ->
|
|||
%% Log management.
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
log_management(Config) ->
|
||||
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||
?MODULE, log_management1, [Config]).
|
||||
|
||||
log_management1(_Config) ->
|
||||
[LogFile|_] = rabbit:log_locations(),
|
||||
Suffix = ".0",
|
||||
|
||||
ok = test_logs_working([LogFile]),
|
||||
|
||||
%% prepare basic logs
|
||||
file:delete(LogFile ++ Suffix),
|
||||
ok = test_logs_working([LogFile]),
|
||||
|
||||
%% simple log rotation
|
||||
ok = rabbit:rotate_logs(),
|
||||
%% rabbit:rotate_logs/0 is asynchronous due to a limitation in
|
||||
%% Lager. Therefore, we have no choice but to wait an arbitrary
|
||||
%% amount of time.
|
||||
ok = rabbit_ct_helpers:await_condition(
|
||||
fun() ->
|
||||
[true, true] =:=
|
||||
non_empty_files([LogFile ++ Suffix, LogFile])
|
||||
end, 5000),
|
||||
ok = test_logs_working([LogFile]),
|
||||
|
||||
%% log rotation on empty files
|
||||
ok = clean_logs([LogFile], Suffix),
|
||||
ok = rabbit:rotate_logs(),
|
||||
ok = rabbit_ct_helpers:await_condition(
|
||||
fun() ->
|
||||
[true, true] =:=
|
||||
non_empty_files([LogFile ++ Suffix, LogFile])
|
||||
end, 5000),
|
||||
|
||||
%% logs with suffix are not writable
|
||||
ok = rabbit:rotate_logs(),
|
||||
ok = rabbit_ct_helpers:await_condition(
|
||||
fun() ->
|
||||
ok =:= make_files_non_writable([LogFile ++ Suffix])
|
||||
end, 5000),
|
||||
ok = rabbit:rotate_logs(),
|
||||
ok = rabbit_ct_helpers:await_condition(
|
||||
fun() ->
|
||||
ok =:= test_logs_working([LogFile])
|
||||
end, 5000),
|
||||
|
||||
%% rotate when original log files are not writable
|
||||
ok = make_files_non_writable([LogFile]),
|
||||
ok = rabbit:rotate_logs(),
|
||||
timer:sleep(2000),
|
||||
|
||||
%% logging directed to tty (first, remove handlers)
|
||||
ok = rabbit:stop(),
|
||||
ok = make_files_writable([LogFile ++ Suffix]),
|
||||
ok = clean_logs([LogFile], Suffix),
|
||||
ok = application:set_env(rabbit, lager_default_file, tty),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = rabbit:start(),
|
||||
timer:sleep(200),
|
||||
rabbit_log:info("test info"),
|
||||
|
||||
%% rotate logs when logging is turned off
|
||||
ok = rabbit:stop(),
|
||||
ok = clean_logs([LogFile], Suffix),
|
||||
ok = application:set_env(rabbit, lager_default_file, false),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = rabbit:start(),
|
||||
timer:sleep(200),
|
||||
rabbit_log:error("test error"),
|
||||
timer:sleep(200),
|
||||
?assertEqual([{error,enoent}], empty_files([LogFile])),
|
||||
|
||||
%% cleanup
|
||||
ok = rabbit:stop(),
|
||||
ok = clean_logs([LogFile], Suffix),
|
||||
ok = application:set_env(rabbit, lager_default_file, LogFile),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = rabbit:start(),
|
||||
ok = test_logs_working([LogFile]),
|
||||
passed.
|
||||
|
||||
log_file_initialised_during_startup(Config) ->
|
||||
passed = rabbit_ct_broker_helpers:rpc(Config, 0,
|
||||
?MODULE, log_file_initialised_during_startup1, [Config]).
|
||||
|
|
@ -212,10 +123,8 @@ log_file_initialised_during_startup1(_Config) ->
|
|||
%% start application with simple tty logging
|
||||
ok = rabbit:stop(),
|
||||
ok = clean_logs([LogFile], Suffix),
|
||||
ok = application:set_env(rabbit, lager_default_file, tty),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, false}]}]),
|
||||
ok = rabbit:start(),
|
||||
|
||||
%% start application with logging to non-existing directory
|
||||
|
|
@ -224,18 +133,14 @@ log_file_initialised_during_startup1(_Config) ->
|
|||
delete_file(NonExistent),
|
||||
delete_file(filename:dirname(NonExistent)),
|
||||
ok = rabbit:stop(),
|
||||
ct:pal("Setting lager_default_file to \"~s\"", [NonExistent]),
|
||||
ok = application:set_env(rabbit, lager_default_file, NonExistent),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
io:format("Setting log file to \"~s\"~n", [NonExistent]),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, NonExistent}]}]),
|
||||
ok = rabbit:start(),
|
||||
|
||||
%% clean up
|
||||
ok = application:set_env(rabbit, lager_default_file, LogFile),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, LogFile}]}]),
|
||||
ok = rabbit:start(),
|
||||
passed.
|
||||
|
||||
|
|
@ -277,13 +182,12 @@ log_file_fails_to_initialise_during_startup1(_Config, NonWritableDir) ->
|
|||
delete_file(filename:dirname(NoPermission1)),
|
||||
|
||||
ok = rabbit:stop(),
|
||||
ct:pal("Setting lager_default_file to \"~s\"", [NoPermission1]),
|
||||
ok = application:set_env(rabbit, lager_default_file, NoPermission1),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
io:format("Setting log file to \"~s\"~n", [NoPermission1]),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, NoPermission1}]}]),
|
||||
|
||||
ct:pal("`rabbit` application env.: ~p", [application:get_all_env(rabbit)]),
|
||||
io:format("rabbit application env.: ~p~n",
|
||||
[application:get_all_env(rabbit)]),
|
||||
?assertThrow(
|
||||
{error, {rabbit, {{cannot_log_to_file, _, _}, _}}},
|
||||
rabbit:start()),
|
||||
|
|
@ -296,22 +200,19 @@ log_file_fails_to_initialise_during_startup1(_Config, NonWritableDir) ->
|
|||
delete_file(NoPermission2),
|
||||
delete_file(filename:dirname(NoPermission2)),
|
||||
|
||||
ct:pal("Setting lager_default_file to \"~s\"", [NoPermission2]),
|
||||
ok = application:set_env(rabbit, lager_default_file, NoPermission2),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
io:format("Setting log file to \"~s\"~n", [NoPermission2]),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, NoPermission2}]}]),
|
||||
|
||||
ct:pal("`rabbit` application env.: ~p", [application:get_all_env(rabbit)]),
|
||||
io:format("rabbit application env.: ~p~n",
|
||||
[application:get_all_env(rabbit)]),
|
||||
?assertThrow(
|
||||
{error, {rabbit, {{cannot_log_to_file, _, _}, _}}},
|
||||
rabbit:start()),
|
||||
|
||||
%% clean up
|
||||
ok = application:set_env(rabbit, lager_default_file, LogFile),
|
||||
application:unset_env(rabbit, log),
|
||||
application:unset_env(lager, handlers),
|
||||
application:unset_env(lager, extra_sinks),
|
||||
ok = application:set_env(rabbit, log, [{console, [{enabled, true}]},
|
||||
{file, [{file, LogFile}]}]),
|
||||
ok = rabbit:start(),
|
||||
passed.
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ define PROJECT_APP_EXTRA_KEYS
|
|||
endef
|
||||
|
||||
LOCAL_DEPS = compiler crypto public_key sasl ssl syntax_tools tools xmerl
|
||||
DEPS = lager jsx recon credentials_obfuscation
|
||||
DEPS = jsx recon credentials_obfuscation
|
||||
|
||||
dep_credentials_obfuscation = git https://github.com/rabbitmq/credentials-obfuscation.git master
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
-define(RMQLOG_SUPER_DOMAIN_NAME, rabbitmq).
|
||||
-define(RMQLOG_DOMAIN_GLOBAL, [?RMQLOG_SUPER_DOMAIN_NAME]).
|
||||
-define(DEFINE_RMQLOG_DOMAIN(Domain), [?RMQLOG_SUPER_DOMAIN_NAME, Domain]).
|
||||
|
||||
-define(RMQLOG_DOMAIN_CHAN, ?DEFINE_RMQLOG_DOMAIN(channel)).
|
||||
-define(RMQLOG_DOMAIN_CONN, ?DEFINE_RMQLOG_DOMAIN(connection)).
|
||||
-define(RMQLOG_DOMAIN_FEAT_FLAGS, ?DEFINE_RMQLOG_DOMAIN(feature_flags)).
|
||||
-define(RMQLOG_DOMAIN_MIRRORING, ?DEFINE_RMQLOG_DOMAIN(mirroring)).
|
||||
-define(RMQLOG_DOMAIN_PRELAUNCH, ?DEFINE_RMQLOG_DOMAIN(prelaunch)).
|
||||
-define(RMQLOG_DOMAIN_QUEUE, ?DEFINE_RMQLOG_DOMAIN(queue)).
|
||||
-define(RMQLOG_DOMAIN_UPGRADE, ?DEFINE_RMQLOG_DOMAIN(upgrade)).
|
||||
|
||||
-define(DEFAULT_LOG_LEVEL, info).
|
||||
-define(FILTER_NAME, rmqlog_filter).
|
||||
|
||||
-define(IS_STD_H_COMPAT(Mod),
|
||||
Mod =:= logger_std_h orelse Mod =:= rabbit_logger_std_h).
|
||||
-define(IS_STDDEV(DevName),
|
||||
DevName =:= standard_io orelse DevName =:= standard_error).
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2017-2020 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-define(LAGER_SINK, rabbit_log_lager_event).
|
||||
|
|
@ -18,25 +18,6 @@ ifneq ($(filter-out rabbit_common amqp_client,$(PROJECT)),)
|
|||
RMQ_ERLC_OPTS += -pa $(DEPS_DIR)/rabbitmq_cli/_build/dev/lib/rabbitmqctl/ebin
|
||||
endif
|
||||
|
||||
# Add Lager parse_transform module and our default Lager extra sinks.
|
||||
LAGER_EXTRA_SINKS += rabbit_log \
|
||||
rabbit_log_channel \
|
||||
rabbit_log_connection \
|
||||
rabbit_log_feature_flags \
|
||||
rabbit_log_federation \
|
||||
rabbit_log_ldap \
|
||||
rabbit_log_mirroring \
|
||||
rabbit_log_osiris \
|
||||
rabbit_log_prelaunch \
|
||||
rabbit_log_queue \
|
||||
rabbit_log_ra \
|
||||
rabbit_log_shovel \
|
||||
rabbit_log_upgrade
|
||||
lager_extra_sinks = $(subst $(space),$(comma),$(LAGER_EXTRA_SINKS))
|
||||
|
||||
RMQ_ERLC_OPTS += +'{parse_transform,lager_transform}' \
|
||||
+'{lager_extra_sinks,[$(lager_extra_sinks)]}'
|
||||
|
||||
# Push our compilation options to both the normal and test ERLC_OPTS.
|
||||
ERLC_OPTS += $(RMQ_ERLC_OPTS)
|
||||
TEST_ERLC_OPTS += $(RMQ_ERLC_OPTS)
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ dep_accept = hex 0.3.5
|
|||
dep_cowboy = hex 2.8.0
|
||||
dep_cowlib = hex 2.9.1
|
||||
dep_jsx = hex 2.11.0
|
||||
dep_lager = hex 3.9.1
|
||||
dep_prometheus = git https://github.com/deadtrickster/prometheus.erl.git master
|
||||
dep_ra = git https://github.com/rabbitmq/ra.git master
|
||||
dep_ranch = hex 2.0.0
|
||||
|
|
|
|||
|
|
@ -164,9 +164,7 @@ define test_rabbitmq_config
|
|||
[
|
||||
{rabbit, [
|
||||
$(if $(RABBITMQ_NODE_PORT), {tcp_listeners$(comma) [$(RABBITMQ_NODE_PORT)]}$(comma),)
|
||||
{loopback_users, []},
|
||||
{log, [{file, [{level, debug}]},
|
||||
{console, [{level, debug}]}]}
|
||||
{loopback_users, []}
|
||||
]},
|
||||
{rabbitmq_management, [
|
||||
$(if $(RABBITMQ_NODE_PORT), {listener$(comma) [{port$(comma) $(shell echo "$$(($(RABBITMQ_NODE_PORT) + 10000))")}]},)
|
||||
|
|
@ -184,19 +182,6 @@ $(if $(RABBITMQ_NODE_PORT), {tcp_listeners$(comma) [$(shell echo "$$((5551
|
|||
{data_dir, "$(RABBITMQ_QUORUM_DIR)"},
|
||||
{wal_sync_method, sync}
|
||||
]},
|
||||
{lager, [
|
||||
{colors, [
|
||||
%% https://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||
{debug, "\\\e[0;34m" },
|
||||
{info, "\\\e[1;37m" },
|
||||
{notice, "\\\e[1;36m" },
|
||||
{warning, "\\\e[1;33m" },
|
||||
{error, "\\\e[1;31m" },
|
||||
{critical, "\\\e[1;35m" },
|
||||
{alert, "\\\e[1;44m" },
|
||||
{emergency, "\\\e[1;41m" }
|
||||
]}
|
||||
]},
|
||||
{osiris, [
|
||||
{data_dir, "$(RABBITMQ_STREAM_DIR)"}
|
||||
]}
|
||||
|
|
@ -209,8 +194,6 @@ define test_rabbitmq_config_with_tls
|
|||
[
|
||||
{rabbit, [
|
||||
{loopback_users, []},
|
||||
{log, [{file, [{level, debug}]},
|
||||
{console, [{level, debug}]}]},
|
||||
{ssl_listeners, [5671]},
|
||||
{ssl_options, [
|
||||
{cacertfile, "$(TEST_TLS_CERTS_DIR_in_config)/testca/cacert.pem"},
|
||||
|
|
@ -237,19 +220,6 @@ define test_rabbitmq_config_with_tls
|
|||
{data_dir, "$(RABBITMQ_QUORUM_DIR)"},
|
||||
{wal_sync_method, sync}
|
||||
]},
|
||||
{lager, [
|
||||
{colors, [
|
||||
%% https://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||
{debug, "\\\e[0;34m" },
|
||||
{info, "\\\e[1;37m" },
|
||||
{notice, "\\\e[1;36m" },
|
||||
{warning, "\\\e[1;33m" },
|
||||
{error, "\\\e[1;31m" },
|
||||
{critical, "\\\e[1;35m" },
|
||||
{alert, "\\\e[1;44m" },
|
||||
{emergency, "\\\e[1;41m" }
|
||||
]}
|
||||
]},
|
||||
{osiris, [
|
||||
{data_dir, "$(RABBITMQ_STREAM_DIR)"}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -1083,8 +1083,8 @@ init([AlarmSet, AlarmClear]) ->
|
|||
end
|
||||
end,
|
||||
ObtainLimit = obtain_limit(Limit),
|
||||
error_logger:info_msg("Limiting to approx ~p file handles (~p sockets)~n",
|
||||
[Limit, ObtainLimit]),
|
||||
logger:info("Limiting to approx ~p file handles (~p sockets)",
|
||||
[Limit, ObtainLimit]),
|
||||
Clients = ets:new(?CLIENT_ETS_TABLE, [set, private, {keypos, #cstate.pid}]),
|
||||
Elders = ets:new(?ELDERS_ETS_TABLE, [set, private]),
|
||||
{ok, #fhc_state { elders = Elders,
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
%% This Source Code Form is subject to the terms of the Mozilla Public
|
||||
%% License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
%%
|
||||
%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(lager_forwarder_backend).
|
||||
|
||||
-behaviour(gen_event).
|
||||
|
||||
-export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2,
|
||||
code_change/3]).
|
||||
|
||||
-record(state, {
|
||||
next_sink :: atom(),
|
||||
level :: {'mask', integer()} | inherit
|
||||
}).
|
||||
|
||||
%% @private
|
||||
init(Sink) when is_atom(Sink) ->
|
||||
init([Sink]);
|
||||
init([Sink]) when is_atom(Sink) ->
|
||||
init([Sink, inherit]);
|
||||
init([Sink, inherit]) when is_atom(Sink) ->
|
||||
{ok, #state{
|
||||
next_sink = Sink,
|
||||
level = inherit
|
||||
}};
|
||||
init([Sink, Level]) when is_atom(Sink) ->
|
||||
try
|
||||
Mask = lager_util:config_to_mask(Level),
|
||||
{ok, #state{
|
||||
next_sink = Sink,
|
||||
level = Mask
|
||||
}}
|
||||
catch
|
||||
_:_ ->
|
||||
{error, {fatal, bad_log_level}}
|
||||
end;
|
||||
init(_) ->
|
||||
{error, {fatal, bad_config}}.
|
||||
|
||||
%% @private
|
||||
handle_call(get_loglevel, #state{next_sink = Sink, level = inherit} = State) ->
|
||||
SinkPid = whereis(Sink),
|
||||
Mask = case self() of
|
||||
SinkPid ->
|
||||
%% Avoid direct loops, defaults to 'info'.
|
||||
127;
|
||||
_ ->
|
||||
try
|
||||
Levels = [gen_event:call(SinkPid, Handler, get_loglevel,
|
||||
infinity)
|
||||
|| Handler <- gen_event:which_handlers(SinkPid)],
|
||||
lists:foldl(fun
|
||||
({mask, Mask}, Acc) ->
|
||||
Mask bor Acc;
|
||||
(Level, Acc) when is_integer(Level) ->
|
||||
{mask, Mask} = lager_util:config_to_mask(
|
||||
lager_util:num_to_level(Level)),
|
||||
Mask bor Acc;
|
||||
(_, Acc) ->
|
||||
Acc
|
||||
end, 0, Levels)
|
||||
catch
|
||||
exit:noproc ->
|
||||
127
|
||||
end
|
||||
end,
|
||||
{ok, {mask, Mask}, State};
|
||||
handle_call(get_loglevel, #state{level = Mask} = State) ->
|
||||
{ok, Mask, State};
|
||||
handle_call({set_loglevel, inherit}, State) ->
|
||||
{ok, ok, State#state{level = inherit}};
|
||||
handle_call({set_loglevel, Level}, State) ->
|
||||
try lager_util:config_to_mask(Level) of
|
||||
Mask ->
|
||||
{ok, ok, State#state{level = Mask}}
|
||||
catch
|
||||
_:_ ->
|
||||
{ok, {error, bad_log_level}, State}
|
||||
end;
|
||||
handle_call(_Request, State) ->
|
||||
{ok, ok, State}.
|
||||
|
||||
%% @private
|
||||
handle_event({log, LagerMsg}, #state{next_sink = Sink, level = Mask} = State) ->
|
||||
SinkPid = whereis(Sink),
|
||||
case self() of
|
||||
SinkPid ->
|
||||
%% Avoid direct loops.
|
||||
ok;
|
||||
_ ->
|
||||
case Mask =:= inherit orelse
|
||||
lager_util:is_loggable(LagerMsg, Mask, ?MODULE) of
|
||||
true ->
|
||||
case lager_config:get({Sink, async}, false) of
|
||||
true -> gen_event:notify(SinkPid, {log, LagerMsg});
|
||||
false -> gen_event:sync_notify(SinkPid, {log, LagerMsg})
|
||||
end;
|
||||
false ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
{ok, State};
|
||||
handle_event(_Event, State) ->
|
||||
{ok, State}.
|
||||
|
||||
%% @private
|
||||
handle_info(_Info, State) ->
|
||||
{ok, State}.
|
||||
|
||||
%% @private
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
%% @private
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
|
@ -14,11 +14,11 @@ amqp_params(ConnPid, Timeout) ->
|
|||
P = try
|
||||
gen_server:call(ConnPid, {info, [amqp_params]}, Timeout)
|
||||
catch exit:{noproc, Error} ->
|
||||
rabbit_log:debug("file ~p, line ~p - connection process ~p not alive: ~p~n",
|
||||
rabbit_log:debug("file ~p, line ~p - connection process ~p not alive: ~p",
|
||||
[?FILE, ?LINE, ConnPid, Error]),
|
||||
[];
|
||||
_:Error ->
|
||||
rabbit_log:debug("file ~p, line ~p - failed to get amqp_params from connection process ~p: ~p~n",
|
||||
rabbit_log:debug("file ~p, line ~p - failed to get amqp_params from connection process ~p: ~p",
|
||||
[?FILE, ?LINE, ConnPid, Error]),
|
||||
[]
|
||||
end,
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ lookup_amqp_exception(#amqp_error{name = Name,
|
|||
ExplBin = amqp_exception_explanation(Text, Expl),
|
||||
{ShouldClose, Code, ExplBin, Method};
|
||||
lookup_amqp_exception(Other, Protocol) ->
|
||||
rabbit_log:warning("Non-AMQP exit reason '~p'~n", [Other]),
|
||||
rabbit_log:warning("Non-AMQP exit reason '~p'", [Other]),
|
||||
{ShouldClose, Code, Text} = Protocol:lookup_amqp_exception(internal_error),
|
||||
{ShouldClose, Code, Text, none}.
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue