Skip to content

Commit 821c56e

Browse files
author
Andy Till
authored
Merge pull request #1251 from basho/at-rt-redbug
redbug tracing in riak test
2 parents adb4caa + 6aeaa86 commit 821c56e

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,30 @@ you add them via one of the methods listed previously.
356356

357357
{load_intercepts, false}
358358

359+
### Adding Tracing to Nodes Under Test
360+
361+
Erlang Tracing can be added to test suites to trace function calls on
362+
nodes under test. By default, trace calls will not execute without the
363+
`riak_test` tracing command line argument
364+
365+
```shell
366+
--trace
367+
```
368+
369+
To add tracing to target nodes, make a call to the `rt_redbug:trace/2`
370+
function. `Nodes` is a single node name or a list of node names that the
371+
trace should be applied to. The second argument is a string or list of
372+
string traces using the redbug syntax. An arity three function is also
373+
exported that takes options as defined in the redbug docs.
374+
375+
```erlang
376+
rt_redbug:trace(Nodes, ["module:function"])
377+
```
378+
379+
Tracing is output to the terminal and `test.log` file. More documentation on
380+
redbug can be found
381+
[here](https://github.com/massemanet/eper/blob/master/doc/redbug.txt).
382+
359383
#### Config
360384

361385
Here is how you would add the `dropped_put` intercept via the config.

src/riak_test_escript.erl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ cli_options() ->
4444
{upgrade_version, $u, "upgrade", atom, "which version to upgrade from [ previous | legacy ]"},
4545
{keep, undefined, "keep", boolean, "do not teardown cluster"},
4646
{report, $r, "report", string, "you're reporting an official test run, provide platform info (e.g. ubuntu-1204-64)\nUse 'config' if you want to pull from ~/.riak_test.config"},
47-
{file, $F, "file", string, "use the specified file instead of ~/.riak_test.config"}
47+
{file, $F, "file", string, "use the specified file instead of ~/.riak_test.config"},
48+
{apply_traces,undefined, "trace", undefined, "Apply traces to the target node, defined in the SUITEs"}
4849
].
4950

5051
print_help() ->
@@ -210,6 +211,11 @@ parse_command_line_tests(ParsedArgs) ->
210211
[] -> [undefined];
211212
UpgradeList -> UpgradeList
212213
end,
214+
%% this is a little ugly, the process that creates the ets table to store
215+
%% the tracing state cannot shutdown or the table will be gc'ed, so create
216+
%% a dummy proc that doens't die
217+
rt_redbug:new(),
218+
rt_redbug:set_tracing_applied(proplists:is_defined(apply_traces, ParsedArgs)),
213219
%% Parse Command Line Tests
214220
{CodePaths, SpecificTests} =
215221
lists:foldl(fun extract_test_names/2,

src/rt_redbug.erl

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
%% -------------------------------------------------------------------
2+
%%
3+
%% Copyright (c) 2016 Basho Technologies, Inc.
4+
%%
5+
%% This file is provided to you under the Apache License,
6+
%% Version 2.0 (the "License"); you may not use this file
7+
%% except in compliance with the License. You may obtain
8+
%% a copy of the License at
9+
%%
10+
%% http://www.apache.org/licenses/LICENSE-2.0
11+
%%
12+
%% Unless required by applicable law or agreed to in writing,
13+
%% software distributed under the License is distributed on an
14+
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
%% KIND, either express or implied. See the License for the
16+
%% specific language governing permissions and limitations
17+
%% under the License.
18+
%%
19+
%% Enable and disable tracing from the riak_test command line,
20+
%% add `--tracing` to the test run to execute any calls to
21+
%% `rt_redbug:trace/2` that are in the test suites. The traces
22+
%% are printed to the test.log
23+
%%
24+
%% -------------------------------------------------------------------
25+
26+
-module(rt_redbug).
27+
28+
-export([is_tracing_applied/0]).
29+
-export([new/0]).
30+
-export([set_tracing_applied/1]).
31+
-export([stop/1]).
32+
-export([trace/2, trace/3]).
33+
34+
%% Create a new ets to store globally whether we're tracing or not.
35+
new() ->
36+
ok.
37+
38+
set_tracing_applied(TracingApplied) when is_boolean(TracingApplied) ->
39+
lager:info("Setting apply tracing to ~p", [TracingApplied]),
40+
rt_config:set(apply_traces, TracingApplied).
41+
42+
is_tracing_applied() ->
43+
rt_config:get(apply_traces).
44+
45+
%% Apply traces to one or more nodes using redbug tracing and syntax.
46+
%%
47+
%% eper documentation for the redbug trace string and options is here:
48+
%%
49+
%% https://github.com/massemanet/eper/blob/master/doc/redbug.txt
50+
%%
51+
%% docs on profiling using redbug (for test timeouts) is here:
52+
%%
53+
%% http://roberto-aloi.com/erlang/profiling-erlang-applications-using-redbug
54+
%%
55+
%% Set a trace on a function
56+
%% rt_redbug:trace(Node, "riak_kv_qry_compiler:compile").
57+
%% rt_redbug:trace(Node, ["riak_kv_qry_compiler:compile", "riak_ql_parser:parse"]).
58+
%%
59+
%% Multiple traces can be set in one call. Calling the `rt_redbug:trace`
60+
%% function a second time stops the traces started by the first call.
61+
%%
62+
%% Traces can be stopped by calling `rt_redbug:stop(Nodes)` with the nodes in
63+
%% the test cluster. This is important if there are multiple tests in the same
64+
%% suite, but not if the cluster is torn down at the end of the suite.
65+
trace(Nodes, TraceStrings) ->
66+
trace(Nodes, TraceStrings, []).
67+
68+
trace(Nodes, TraceStrings, Options1) when (is_atom(Nodes) orelse is_list(Nodes)) ->
69+
case is_tracing_applied() of
70+
true ->
71+
Options2 = apply_options_to_defaults(Options1),
72+
[apply_trace(N, TraceStrings, Options2) || N <- ensure_list(Nodes)],
73+
ok;
74+
false ->
75+
ok
76+
end.
77+
78+
%%
79+
apply_trace(Node, TraceString, Options) ->
80+
rpc:call(Node, redbug, start, [TraceString, Options]).
81+
82+
%%
83+
apply_options_to_defaults(Options) ->
84+
lists:foldl(
85+
fun({K,_} = E,Acc) ->
86+
lists:keystore(K, 1, Acc, E)
87+
end, default_trace_options(), Options).
88+
89+
%%
90+
default_trace_options() ->
91+
[
92+
%% default ct timeout of 30 minutes
93+
%% http://erlang.org/doc/apps/common_test/write_test_chapter.html#id77922
94+
{time,(30*60*1000)},
95+
%% raise the threshold for the number of traces that can be received by
96+
%% redbug before tracing is suspended
97+
{msgs, 1000},
98+
%% print milliseconds
99+
{print_msec, true}
100+
].
101+
102+
%% Stop redbug tracing on a node or list of nodes
103+
stop(Nodes) ->
104+
case is_tracing_applied() of
105+
true ->
106+
[rpc:call(N, redbug, stop, []) || N <- ensure_list(Nodes)],
107+
ok;
108+
false ->
109+
ok
110+
end.
111+
112+
%% Doesn't work on lists of strings!
113+
ensure_list(V) ->
114+
lists:flatten([V]).
115+

0 commit comments

Comments
 (0)