1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_TRACE_EVENT_TRACE_CONFIG_H_
6#define BASE_TRACE_EVENT_TRACE_CONFIG_H_
7
8#include <stdint.h>
9
10#include <set>
11#include <string>
12#include <vector>
13
14#include "base/base_export.h"
15#include "base/gtest_prod_util.h"
16#include "base/strings/string_piece.h"
17#include "base/trace_event/memory_dump_request_args.h"
18#include "base/values.h"
19
20namespace base {
21namespace trace_event {
22
23class ConvertableToTraceFormat;
24
25// Options determines how the trace buffer stores data.
26enum TraceRecordMode {
27  // Record until the trace buffer is full.
28  RECORD_UNTIL_FULL,
29
30  // Record until the user ends the trace. The trace buffer is a fixed size
31  // and we use it as a ring buffer during recording.
32  RECORD_CONTINUOUSLY,
33
34  // Record until the trace buffer is full, but with a huge buffer size.
35  RECORD_AS_MUCH_AS_POSSIBLE,
36
37  // Echo to console. Events are discarded.
38  ECHO_TO_CONSOLE,
39};
40
41class BASE_EXPORT TraceConfig {
42 public:
43  using StringList = std::vector<std::string>;
44
45  // Specifies the memory dump config for tracing.
46  // Used only when "memory-infra" category is enabled.
47  struct BASE_EXPORT MemoryDumpConfig {
48    MemoryDumpConfig();
49    MemoryDumpConfig(const MemoryDumpConfig& other);
50    ~MemoryDumpConfig();
51
52    // Specifies the triggers in the memory dump config.
53    struct Trigger {
54      uint32_t periodic_interval_ms;
55      MemoryDumpLevelOfDetail level_of_detail;
56    };
57
58    // Specifies the configuration options for the heap profiler.
59    struct HeapProfiler {
60      // Default value for |breakdown_threshold_bytes|.
61      enum { kDefaultBreakdownThresholdBytes = 1024 };
62
63      HeapProfiler();
64
65      // Reset the options to default.
66      void Clear();
67
68      uint32_t breakdown_threshold_bytes;
69    };
70
71    // Reset the values in the config.
72    void Clear();
73
74    // Set of memory dump modes allowed for the tracing session. The explicitly
75    // triggered dumps will be successful only if the dump mode is allowed in
76    // the config.
77    std::set<MemoryDumpLevelOfDetail> allowed_dump_modes;
78
79    std::vector<Trigger> triggers;
80    HeapProfiler heap_profiler_options;
81  };
82
83  TraceConfig();
84
85  // Create TraceConfig object from category filter and trace options strings.
86  //
87  // |category_filter_string| is a comma-delimited list of category wildcards.
88  // A category can have an optional '-' prefix to make it an excluded category.
89  // All the same rules apply above, so for example, having both included and
90  // excluded categories in the same list would not be supported.
91  //
92  // Category filters can also be used to configure synthetic delays.
93  //
94  // |trace_options_string| is a comma-delimited list of trace options.
95  // Possible options are: "record-until-full", "record-continuously",
96  // "record-as-much-as-possible", "trace-to-console", "enable-sampling",
97  // "enable-systrace" and "enable-argument-filter".
98  // The first 4 options are trace recoding modes and hence
99  // mutually exclusive. If more than one trace recording modes appear in the
100  // options_string, the last one takes precedence. If none of the trace
101  // recording mode is specified, recording mode is RECORD_UNTIL_FULL.
102  //
103  // The trace option will first be reset to the default option
104  // (record_mode set to RECORD_UNTIL_FULL, enable_sampling, enable_systrace,
105  // and enable_argument_filter set to false) before options parsed from
106  // |trace_options_string| are applied on it. If |trace_options_string| is
107  // invalid, the final state of trace options is undefined.
108  //
109  // Example: TraceConfig("test_MyTest*", "record-until-full");
110  // Example: TraceConfig("test_MyTest*,test_OtherStuff",
111  //                      "record-continuously, enable-sampling");
112  // Example: TraceConfig("-excluded_category1,-excluded_category2",
113  //                      "record-until-full, trace-to-console");
114  //          would set ECHO_TO_CONSOLE as the recording mode.
115  // Example: TraceConfig("-*,webkit", "");
116  //          would disable everything but webkit; and use default options.
117  // Example: TraceConfig("-webkit", "");
118  //          would enable everything but webkit; and use default options.
119  // Example: TraceConfig("DELAY(gpu.PresentingFrame;16)", "");
120  //          would make swap buffers always take at least 16 ms; and use
121  //          default options.
122  // Example: TraceConfig("DELAY(gpu.PresentingFrame;16;oneshot)", "");
123  //          would make swap buffers take at least 16 ms the first time it is
124  //          called; and use default options.
125  // Example: TraceConfig("DELAY(gpu.PresentingFrame;16;alternating)", "");
126  //          would make swap buffers take at least 16 ms every other time it
127  //          is called; and use default options.
128  TraceConfig(StringPiece category_filter_string,
129              StringPiece trace_options_string);
130
131  TraceConfig(StringPiece category_filter_string, TraceRecordMode record_mode);
132
133  // Create TraceConfig object from the trace config string.
134  //
135  // |config_string| is a dictionary formatted as a JSON string, containing both
136  // category filters and trace options.
137  //
138  // Example:
139  //   {
140  //     "record_mode": "record-continuously",
141  //     "enable_sampling": true,
142  //     "enable_systrace": true,
143  //     "enable_argument_filter": true,
144  //     "included_categories": ["included",
145  //                             "inc_pattern*",
146  //                             "disabled-by-default-memory-infra"],
147  //     "excluded_categories": ["excluded", "exc_pattern*"],
148  //     "synthetic_delays": ["test.Delay1;16", "test.Delay2;32"],
149  //     "memory_dump_config": {
150  //       "triggers": [
151  //         {
152  //           "mode": "detailed",
153  //           "periodic_interval_ms": 2000
154  //         }
155  //       ]
156  //     }
157  //   }
158  //
159  // Note: memory_dump_config can be specified only if
160  // disabled-by-default-memory-infra category is enabled.
161  explicit TraceConfig(StringPiece config_string);
162
163  // Functionally identical to the above, but takes a parsed dictionary as input
164  // instead of its JSON serialization.
165  explicit TraceConfig(const DictionaryValue& config);
166
167  TraceConfig(const TraceConfig& tc);
168
169  ~TraceConfig();
170
171  TraceConfig& operator=(const TraceConfig& rhs);
172
173  // Return a list of the synthetic delays specified in this category filter.
174  const StringList& GetSyntheticDelayValues() const;
175
176  TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
177  bool IsSamplingEnabled() const { return enable_sampling_; }
178  bool IsSystraceEnabled() const { return enable_systrace_; }
179  bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
180
181  void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
182  void EnableSampling() { enable_sampling_ = true; }
183  void EnableSystrace() { enable_systrace_ = true; }
184  void EnableArgumentFilter() { enable_argument_filter_ = true; }
185
186  // Writes the string representation of the TraceConfig. The string is JSON
187  // formatted.
188  std::string ToString() const;
189
190  // Returns a copy of the TraceConfig wrapped in a ConvertableToTraceFormat
191  std::unique_ptr<ConvertableToTraceFormat> AsConvertableToTraceFormat() const;
192
193  // Write the string representation of the CategoryFilter part.
194  std::string ToCategoryFilterString() const;
195
196  // Returns true if at least one category in the list is enabled by this
197  // trace config. This is used to determine if the category filters are
198  // enabled in the TRACE_* macros.
199  bool IsCategoryGroupEnabled(const char* category_group) const;
200
201  // Merges config with the current TraceConfig
202  void Merge(const TraceConfig& config);
203
204  void Clear();
205
206  // Clears and resets the memory dump config.
207  void ResetMemoryDumpConfig(const MemoryDumpConfig& memory_dump_config);
208
209  const MemoryDumpConfig& memory_dump_config() const {
210    return memory_dump_config_;
211  }
212
213 private:
214  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidLegacyFormat);
215  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
216                           TraceConfigFromInvalidLegacyStrings);
217  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidString);
218  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromInvalidString);
219  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
220                           IsEmptyOrContainsLeadingOrTrailingWhitespace);
221  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromMemoryConfigString);
222  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, LegacyStringToMemoryDumpConfig);
223  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, EmptyMemoryDumpConfigTest);
224  FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
225                           EmptyAndAsteriskCategoryFilterString);
226
227  // The default trace config, used when none is provided.
228  // Allows all non-disabled-by-default categories through, except if they end
229  // in the suffix 'Debug' or 'Test'.
230  void InitializeDefault();
231
232  // Initialize from a config dictionary.
233  void InitializeFromConfigDict(const DictionaryValue& dict);
234
235  // Initialize from a config string.
236  void InitializeFromConfigString(StringPiece config_string);
237
238  // Initialize from category filter and trace options strings
239  void InitializeFromStrings(StringPiece category_filter_string,
240                             StringPiece trace_options_string);
241
242  void SetCategoriesFromIncludedList(const ListValue& included_list);
243  void SetCategoriesFromExcludedList(const ListValue& excluded_list);
244  void SetSyntheticDelaysFromList(const ListValue& list);
245  void AddCategoryToDict(DictionaryValue* dict,
246                         const char* param,
247                         const StringList& categories) const;
248
249  void SetMemoryDumpConfigFromConfigDict(
250      const DictionaryValue& memory_dump_config);
251  void SetDefaultMemoryDumpConfig();
252
253  std::unique_ptr<DictionaryValue> ToDict() const;
254
255  std::string ToTraceOptionsString() const;
256
257  void WriteCategoryFilterString(const StringList& values,
258                                 std::string* out,
259                                 bool included) const;
260  void WriteCategoryFilterString(const StringList& delays,
261                                 std::string* out) const;
262
263  // Returns true if the category is enabled according to this trace config.
264  // This tells whether a category is enabled from the TraceConfig's
265  // perspective. Please refer to IsCategoryGroupEnabled() to determine if a
266  // category is enabled from the tracing runtime's perspective.
267  bool IsCategoryEnabled(const char* category_name) const;
268
269  static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(StringPiece str);
270
271  bool HasIncludedPatterns() const;
272
273  TraceRecordMode record_mode_;
274  bool enable_sampling_ : 1;
275  bool enable_systrace_ : 1;
276  bool enable_argument_filter_ : 1;
277
278  MemoryDumpConfig memory_dump_config_;
279
280  StringList included_categories_;
281  StringList disabled_categories_;
282  StringList excluded_categories_;
283  StringList synthetic_delays_;
284};
285
286}  // namespace trace_event
287}  // namespace base
288
289#endif  // BASE_TRACE_EVENT_TRACE_CONFIG_H_
290