126 lines
3.9 KiB
Erlang
126 lines
3.9 KiB
Erlang
%% The contents of this file are subject to the Mozilla Public License
|
|
%% Version 1.1 (the "License"); you may not use this file except in
|
|
%% compliance with the License. You may obtain a copy of the License
|
|
%% at https://www.mozilla.org/MPL/
|
|
%%
|
|
%% Software distributed under the License is distributed on an "AS IS"
|
|
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
%% the License for the specific language governing rights and
|
|
%% limitations under the License.
|
|
%%
|
|
%% The Original Code is RabbitMQ.
|
|
%%
|
|
%% The Initial Developer of the Original Code is GoPivotal, Inc.
|
|
%% Copyright (c) 2007-2020 Pivotal Software, Inc. All rights reserved.
|
|
%%
|
|
|
|
-module(rabbit_tracing_traces).
|
|
|
|
-behaviour(gen_server).
|
|
|
|
-import(rabbit_misc, [pget/2]).
|
|
|
|
-export([list/0, lookup/2, create/3, stop/2, announce/3]).
|
|
|
|
-export([start_link/0]).
|
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
|
|
code_change/3]).
|
|
|
|
-define(SERVER, ?MODULE).
|
|
|
|
-record(state, { table }).
|
|
|
|
%%--------------------------------------------------------------------
|
|
|
|
start_link() ->
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
|
|
|
list() ->
|
|
gen_server:call(?MODULE, list, infinity).
|
|
|
|
lookup(VHost, Name) ->
|
|
gen_server:call(?MODULE, {lookup, VHost, Name}, infinity).
|
|
|
|
create(VHost, Name, Trace) ->
|
|
gen_server:call(?MODULE, {create, VHost, Name, Trace}, infinity).
|
|
|
|
stop(VHost, Name) ->
|
|
gen_server:call(?MODULE, {stop, VHost, Name}, infinity).
|
|
|
|
announce(VHost, Name, Pid) ->
|
|
gen_server:cast(?MODULE, {announce, {VHost, Name}, Pid}).
|
|
|
|
%%--------------------------------------------------------------------
|
|
|
|
init([]) ->
|
|
{ok, #state{table = ets:new(anon, [private])}}.
|
|
|
|
handle_call(list, _From, State = #state{table = Table}) ->
|
|
{reply, [augment(Trace) || {_K, Trace} <- ets:tab2list(Table)], State};
|
|
|
|
handle_call({lookup, VHost, Name}, _From, State = #state{table = Table}) ->
|
|
{reply, case ets:lookup(Table, {VHost, Name}) of
|
|
[] -> not_found;
|
|
[{_K, Trace}] -> augment(Trace)
|
|
end, State};
|
|
|
|
handle_call({create, VHost, Name, Trace0}, _From,
|
|
State = #state{table = Table}) ->
|
|
Already = vhost_tracing(VHost, Table),
|
|
Trace = pset(vhost, VHost, pset(name, Name, Trace0)),
|
|
true = ets:insert(Table, {{VHost, Name}, Trace}),
|
|
case Already of
|
|
true -> ok;
|
|
false -> rabbit_trace:start(VHost)
|
|
end,
|
|
{reply, rabbit_tracing_sup:start_child({VHost, Name}, Trace), State};
|
|
|
|
handle_call({stop, VHost, Name}, _From, State = #state{table = Table}) ->
|
|
true = ets:delete(Table, {VHost, Name}),
|
|
case vhost_tracing(VHost, Table) of
|
|
true -> ok;
|
|
false -> rabbit_trace:stop(VHost)
|
|
end,
|
|
rabbit_tracing_sup:stop_child({VHost, Name}),
|
|
{reply, ok, State};
|
|
|
|
handle_call(_Req, _From, State) ->
|
|
{reply, unknown_request, State}.
|
|
|
|
handle_cast({announce, Key, Pid}, State = #state{table = Table}) ->
|
|
case ets:lookup(Table, Key) of
|
|
[] -> ok;
|
|
[{_, Trace}] -> ets:insert(Table, {Key, pset(pid, Pid, Trace)})
|
|
end,
|
|
{noreply, State};
|
|
|
|
handle_cast(_C, State) ->
|
|
{noreply, State}.
|
|
|
|
handle_info(_I, State) ->
|
|
{noreply, State}.
|
|
|
|
terminate(_, _) -> ok.
|
|
|
|
code_change(_, State, _) -> {ok, State}.
|
|
|
|
%%--------------------------------------------------------------------
|
|
|
|
pset(Key, Value, List) -> [{Key, Value} | proplists:delete(Key, List)].
|
|
|
|
vhost_tracing(VHost, Table) ->
|
|
case [true || {{V, _}, _} <- ets:tab2list(Table), V =:= VHost] of
|
|
[] -> false;
|
|
_ -> true
|
|
end.
|
|
|
|
augment(Trace) ->
|
|
Pid = pget(pid, Trace),
|
|
Trace1 = lists:keydelete(tracer_connection_password, 1,
|
|
lists:keydelete(<<"tracer_connection_password">>, 1,
|
|
lists:keydelete(pid, 1, Trace))),
|
|
case Pid of
|
|
undefined -> Trace1;
|
|
_ -> rabbit_tracing_consumer:info_all(Pid) ++ Trace1
|
|
end.
|