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 <memory>
11 #include <set>
12 #include <string>
13 #include <unordered_set>
14 #include <vector>
15 
16 #include "base/base_export.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/strings/string_piece.h"
19 #include "base/trace_event/memory_dump_request_args.h"
20 #include "base/trace_event/trace_config_category_filter.h"
21 #include "base/values.h"
22 
23 namespace base {
24 namespace trace_event {
25 
26 class ConvertableToTraceFormat;
27 
28 // Options determines how the trace buffer stores data.
29 // A Java counterpart will be generated for this enum.
30 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
31 enum TraceRecordMode {
32   // Record until the trace buffer is full.
33   RECORD_UNTIL_FULL,
34 
35   // Record until the user ends the trace. The trace buffer is a fixed size
36   // and we use it as a ring buffer during recording.
37   RECORD_CONTINUOUSLY,
38 
39   // Record until the trace buffer is full, but with a huge buffer size.
40   RECORD_AS_MUCH_AS_POSSIBLE,
41 
42   // Echo to console. Events are discarded.
43   ECHO_TO_CONSOLE,
44 };
45 
46 class BASE_EXPORT TraceConfig {
47  public:
48   using StringList = std::vector<std::string>;
49 
50   // Specifies the memory dump config for tracing.
51   // Used only when "memory-infra" category is enabled.
52   struct BASE_EXPORT MemoryDumpConfig {
53     MemoryDumpConfig();
54     MemoryDumpConfig(const MemoryDumpConfig& other);
55     ~MemoryDumpConfig();
56 
57     // Specifies the triggers in the memory dump config.
58     struct Trigger {
59       uint32_t min_time_between_dumps_ms;
60       MemoryDumpLevelOfDetail level_of_detail;
61       MemoryDumpType trigger_type;
62     };
63 
64     // Specifies the configuration options for the heap profiler.
65     struct HeapProfiler {
66       // Default value for |breakdown_threshold_bytes|.
67       enum { kDefaultBreakdownThresholdBytes = 1024 };
68 
69       HeapProfiler();
70 
71       // Reset the options to default.
72       void Clear();
73 
74       uint32_t breakdown_threshold_bytes;
75     };
76 
77     // Reset the values in the config.
78     void Clear();
79 
80     void Merge(const MemoryDumpConfig& config);
81 
82     // Set of memory dump modes allowed for the tracing session. The explicitly
83     // triggered dumps will be successful only if the dump mode is allowed in
84     // the config.
85     std::set<MemoryDumpLevelOfDetail> allowed_dump_modes;
86 
87     std::vector<Trigger> triggers;
88     HeapProfiler heap_profiler_options;
89   };
90 
91   class BASE_EXPORT ProcessFilterConfig {
92    public:
93     ProcessFilterConfig();
94     explicit ProcessFilterConfig(
95         const std::unordered_set<base::ProcessId>& included_process_ids);
96     ProcessFilterConfig(const ProcessFilterConfig&);
97     ~ProcessFilterConfig();
98 
empty()99     bool empty() const { return included_process_ids_.empty(); }
100 
101     void Clear();
102     void Merge(const ProcessFilterConfig&);
103 
104     void InitializeFromConfigDict(const Value&);
105     void ToDict(Value*) const;
106 
107     bool IsEnabled(base::ProcessId) const;
included_process_ids()108     const std::unordered_set<base::ProcessId>& included_process_ids() const {
109       return included_process_ids_;
110     }
111 
112     bool operator==(const ProcessFilterConfig& other) const {
113       return included_process_ids_ == other.included_process_ids_;
114     }
115 
116    private:
117     std::unordered_set<base::ProcessId> included_process_ids_;
118   };
119 
120   class BASE_EXPORT EventFilterConfig {
121    public:
122     explicit EventFilterConfig(const std::string& predicate_name);
123     EventFilterConfig(const EventFilterConfig& tc);
124 
125     ~EventFilterConfig();
126 
127     EventFilterConfig& operator=(const EventFilterConfig& rhs);
128 
129     void InitializeFromConfigDict(const Value& event_filter);
130 
131     void SetCategoryFilter(const TraceConfigCategoryFilter& category_filter);
132 
133     void ToDict(Value* filter_dict) const;
134 
135     bool GetArgAsSet(const char* key, std::unordered_set<std::string>*) const;
136 
137     bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;
138 
predicate_name()139     const std::string& predicate_name() const { return predicate_name_; }
filter_args()140     const Value& filter_args() const { return args_; }
category_filter()141     const TraceConfigCategoryFilter& category_filter() const {
142       return category_filter_;
143     }
144 
145    private:
146     std::string predicate_name_;
147     TraceConfigCategoryFilter category_filter_;
148     Value args_;
149   };
150   typedef std::vector<EventFilterConfig> EventFilters;
151 
152   static std::string TraceRecordModeToStr(TraceRecordMode record_mode);
153 
154   TraceConfig();
155 
156   // Create TraceConfig object from category filter and trace options strings.
157   //
158   // |category_filter_string| is a comma-delimited list of category wildcards.
159   // A category can have an optional '-' prefix to make it an excluded category.
160   // All the same rules apply above, so for example, having both included and
161   // excluded categories in the same list would not be supported.
162   //
163   // |trace_options_string| is a comma-delimited list of trace options.
164   // Possible options are: "record-until-full", "record-continuously",
165   // "record-as-much-as-possible", "trace-to-console", "enable-systrace" and
166   // "enable-argument-filter".
167   // The first 4 options are trace recoding modes and hence
168   // mutually exclusive. If more than one trace recording modes appear in the
169   // options_string, the last one takes precedence. If none of the trace
170   // recording mode is specified, recording mode is RECORD_UNTIL_FULL.
171   //
172   // The trace option will first be reset to the default option
173   // (record_mode set to RECORD_UNTIL_FULL, enable_systrace and
174   // enable_argument_filter set to false) before options parsed from
175   // |trace_options_string| are applied on it. If |trace_options_string| is
176   // invalid, the final state of trace options is undefined.
177   //
178   // Example: TraceConfig("test_MyTest*", "record-until-full");
179   // Example: TraceConfig("test_MyTest*,test_OtherStuff",
180   //                      "record-continuously");
181   // Example: TraceConfig("-excluded_category1,-excluded_category2",
182   //                      "record-until-full, trace-to-console");
183   //          would set ECHO_TO_CONSOLE as the recording mode.
184   // Example: TraceConfig("-*,webkit", "");
185   //          would disable everything but webkit; and use default options.
186   // Example: TraceConfig("-webkit", "");
187   //          would enable everything but webkit; and use default options.
188   TraceConfig(StringPiece category_filter_string,
189               StringPiece trace_options_string);
190 
191   TraceConfig(StringPiece category_filter_string, TraceRecordMode record_mode);
192 
193   // Create TraceConfig object from the trace config string.
194   //
195   // |config_string| is a dictionary formatted as a JSON string, containing both
196   // category filters and trace options.
197   //
198   // Example:
199   //   {
200   //     "record_mode": "record-continuously",
201   //     "enable_systrace": true,
202   //     "enable_argument_filter": true,
203   //     "included_categories": ["included",
204   //                             "inc_pattern*",
205   //                             "disabled-by-default-memory-infra"],
206   //     "excluded_categories": ["excluded", "exc_pattern*"],
207   //     "memory_dump_config": {
208   //       "triggers": [
209   //         {
210   //           "mode": "detailed",
211   //           "periodic_interval_ms": 2000
212   //         }
213   //       ]
214   //     }
215   //   }
216   //
217   // Note: memory_dump_config can be specified only if
218   // disabled-by-default-memory-infra category is enabled.
219   explicit TraceConfig(StringPiece config_string);
220 
221   // Functionally identical to the above, but takes a parsed dictionary as input
222   // instead of its JSON serialization.
223   explicit TraceConfig(const Value& config);
224 
225   TraceConfig(const TraceConfig& tc);
226 
227   ~TraceConfig();
228 
229   TraceConfig& operator=(const TraceConfig& rhs);
230 
GetTraceRecordMode()231   TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
GetTraceBufferSizeInEvents()232   size_t GetTraceBufferSizeInEvents() const {
233     return trace_buffer_size_in_events_;
234   }
GetTraceBufferSizeInKb()235   size_t GetTraceBufferSizeInKb() const { return trace_buffer_size_in_kb_; }
IsSystraceEnabled()236   bool IsSystraceEnabled() const { return enable_systrace_; }
IsArgumentFilterEnabled()237   bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
238 
SetTraceRecordMode(TraceRecordMode mode)239   void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
SetTraceBufferSizeInEvents(size_t size)240   void SetTraceBufferSizeInEvents(size_t size) {
241     trace_buffer_size_in_events_ = size;
242   }
SetTraceBufferSizeInKb(size_t size)243   void SetTraceBufferSizeInKb(size_t size) { trace_buffer_size_in_kb_ = size; }
EnableSystrace()244   void EnableSystrace() { enable_systrace_ = true; }
245   void EnableSystraceEvent(const std::string& systrace_event);
EnableArgumentFilter()246   void EnableArgumentFilter() { enable_argument_filter_ = true; }
247   void EnableHistogram(const std::string& histogram_name);
248 
249   // Writes the string representation of the TraceConfig. The string is JSON
250   // formatted.
251   std::string ToString() const;
252 
253   // Returns a copy of the TraceConfig wrapped in a ConvertableToTraceFormat
254   std::unique_ptr<ConvertableToTraceFormat> AsConvertableToTraceFormat() const;
255 
256   // Write the string representation of the CategoryFilter part.
257   std::string ToCategoryFilterString() const;
258 
259   // Write the string representation of the trace options part (record mode,
260   // systrace, argument filtering). Does not include category filters, event
261   // filters, or memory dump configs.
262   std::string ToTraceOptionsString() const;
263 
264   // Returns true if at least one category in the list is enabled by this
265   // trace config. This is used to determine if the category filters are
266   // enabled in the TRACE_* macros.
267   bool IsCategoryGroupEnabled(const StringPiece& category_group_name) const;
268 
269   // Merges config with the current TraceConfig
270   void Merge(const TraceConfig& config);
271 
272   void Clear();
273 
274   // Clears and resets the memory dump config.
275   void ResetMemoryDumpConfig(const MemoryDumpConfig& memory_dump_config);
276 
category_filter()277   const TraceConfigCategoryFilter& category_filter() const {
278     return category_filter_;
279   }
280 
memory_dump_config()281   const MemoryDumpConfig& memory_dump_config() const {
282     return memory_dump_config_;
283   }
284 
process_filter_config()285   const ProcessFilterConfig& process_filter_config() const {
286     return process_filter_config_;
287   }
288   void SetProcessFilterConfig(const ProcessFilterConfig&);
289 
event_filters()290   const EventFilters& event_filters() const { return event_filters_; }
SetEventFilters(const EventFilters & filter_configs)291   void SetEventFilters(const EventFilters& filter_configs) {
292     event_filters_ = filter_configs;
293   }
294 
systrace_events()295   const std::unordered_set<std::string>& systrace_events() const {
296     return systrace_events_;
297   }
298 
histogram_names()299   const std::unordered_set<std::string>& histogram_names() const {
300     return histogram_names_;
301   }
302 
303  private:
304   FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, TraceConfigFromValidLegacyFormat);
305   FRIEND_TEST_ALL_PREFIXES(TraceConfigTest,
306                            TraceConfigFromInvalidLegacyStrings);
307   FRIEND_TEST_ALL_PREFIXES(TraceConfigTest, SystraceEventsSerialization);
308 
309   // The default trace config, used when none is provided.
310   // Allows all non-disabled-by-default categories through, except if they end
311   // in the suffix 'Debug' or 'Test'.
312   void InitializeDefault();
313 
314   // Initialize from a config dictionary.
315   void InitializeFromConfigDict(const Value& dict);
316 
317   // Initialize from a config string.
318   void InitializeFromConfigString(StringPiece config_string);
319 
320   // Initialize from category filter and trace options strings
321   void InitializeFromStrings(StringPiece category_filter_string,
322                              StringPiece trace_options_string);
323 
324   void SetMemoryDumpConfigFromConfigDict(const Value& memory_dump_config);
325   void SetDefaultMemoryDumpConfig();
326 
327   void SetHistogramNamesFromConfigList(const Value& histogram_names);
328   void SetEventFiltersFromConfigList(const Value& event_filters);
329   Value ToValue() const;
330 
331   TraceRecordMode record_mode_;
332   size_t trace_buffer_size_in_events_ = 0;  // 0 specifies default size
333   size_t trace_buffer_size_in_kb_ = 0;      // 0 specifies default size
334   bool enable_systrace_ : 1;
335   bool enable_argument_filter_ : 1;
336 
337   TraceConfigCategoryFilter category_filter_;
338 
339   MemoryDumpConfig memory_dump_config_;
340   ProcessFilterConfig process_filter_config_;
341 
342   EventFilters event_filters_;
343   std::unordered_set<std::string> histogram_names_;
344   std::unordered_set<std::string> systrace_events_;
345 };
346 
347 }  // namespace trace_event
348 }  // namespace base
349 
350 #endif  // BASE_TRACE_EVENT_TRACE_CONFIG_H_
351