1%% This Source Code Form is subject to the terms of the Mozilla Public
2%% License, v. 2.0. If a copy of the MPL was not distributed with this
3%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4%%
5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates.  All rights reserved.
6%%
7
8-module(rabbit_looking_glass).
9
10-ignore_xref([
11    {lg, trace, 4},
12    {lg_callgrind, profile_many, 3}
13]).
14-ignore_xref([{maps, from_list, 1}]).
15
16-export([boot/0]).
17-export([trace/1, profile/0, profile/1]).
18-export([connections/0]).
19
20boot() ->
21    case os:getenv("RABBITMQ_TRACER") of
22        false ->
23            ok;
24        On when On =:= "1" orelse On =:= "true" ->
25            rabbit_log:info("Loading Looking Glass profiler for interactive use"),
26            case application:ensure_all_started(looking_glass) of
27                {ok, _} -> ok;
28                {error, Error} ->
29                    rabbit_log:error("Failed to start Looking Glass, reason: ~p", [Error])
30            end;
31        Value ->
32            Input = parse_value(Value),
33            rabbit_log:info(
34                "Enabling Looking Glass profiler, input value: ~p",
35                [Input]
36            ),
37            {ok, _} = application:ensure_all_started(looking_glass),
38            lg:trace(
39                Input,
40                lg_file_tracer,
41                "traces.lz4",
42                maps:from_list([
43                    {mode, profile},
44                    {process_dump, true},
45                    {running, true},
46                    {send, true}]
47                )
48             )
49    end.
50
51trace(Input) ->
52    lg:trace(Input,
53             lg_file_tracer,
54             "traces.lz4",
55             maps:from_list([
56                 {mode, profile},
57                 {process_dump, true},
58                 {running, true},
59                 {send, true}]
60            )).
61
62profile() ->
63    profile("callgrind.out").
64
65profile(Filename) ->
66    lg_callgrind:profile_many("traces.lz4.*", Filename, #{running => true}).
67
68%%
69%% Implementation
70%%
71
72parse_value(Value) ->
73    [begin
74        [Mod, Fun] = string:tokens(C, ":"),
75        {callback, list_to_atom(Mod), list_to_atom(Fun)}
76    end || C <- string:tokens(Value, ",")].
77
78connections() ->
79    Pids = [Pid || {{conns_sup, _}, Pid} <- ets:tab2list(ranch_server)],
80    ['_', {scope, Pids}].
81