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_BUFFER_H_
6 #define BASE_TRACE_EVENT_TRACE_BUFFER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "base/base_export.h"
12 #include "base/trace_event/trace_event.h"
13 #include "base/trace_event/trace_event_impl.h"
14 
15 namespace base {
16 
17 namespace trace_event {
18 
19 // TraceBufferChunk is the basic unit of TraceBuffer.
20 class BASE_EXPORT TraceBufferChunk {
21  public:
22   explicit TraceBufferChunk(uint32_t seq);
23   ~TraceBufferChunk();
24 
25   void Reset(uint32_t new_seq);
26   TraceEvent* AddTraceEvent(size_t* event_index);
IsFull()27   bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
28 
seq()29   uint32_t seq() const { return seq_; }
capacity()30   size_t capacity() const { return kTraceBufferChunkSize; }
size()31   size_t size() const { return next_free_; }
32 
GetEventAt(size_t index)33   TraceEvent* GetEventAt(size_t index) {
34     DCHECK(index < size());
35     return &chunk_[index];
36   }
GetEventAt(size_t index)37   const TraceEvent* GetEventAt(size_t index) const {
38     DCHECK(index < size());
39     return &chunk_[index];
40   }
41 
42   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
43 
44   // These values must be kept consistent with the numbers of bits of
45   // chunk_index and event_index fields in TraceEventHandle
46   // (in trace_event_impl.h).
47   static const size_t kMaxChunkIndex = (1u << 26) - 1;
48   static const size_t kTraceBufferChunkSize = 64;
49 
50  private:
51   size_t next_free_;
52   std::unique_ptr<TraceEventMemoryOverhead> cached_overhead_estimate_;
53   TraceEvent chunk_[kTraceBufferChunkSize];
54   uint32_t seq_;
55 };
56 
57 // TraceBuffer holds the events as they are collected.
58 class BASE_EXPORT TraceBuffer {
59  public:
60   virtual ~TraceBuffer() = default;
61 
62   virtual std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) = 0;
63   virtual void ReturnChunk(size_t index,
64                            std::unique_ptr<TraceBufferChunk> chunk) = 0;
65 
66   virtual bool IsFull() const = 0;
67   virtual size_t Size() const = 0;
68   virtual size_t Capacity() const = 0;
69   virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
70 
71   // For iteration. Each TraceBuffer can only be iterated once.
72   virtual const TraceBufferChunk* NextChunk() = 0;
73 
74 
75   // Computes an estimate of the size of the buffer, including all the retained
76   // objects.
77   virtual void EstimateTraceMemoryOverhead(
78       TraceEventMemoryOverhead* overhead) = 0;
79 
80   static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks);
81   static TraceBuffer* CreateTraceBufferVectorOfSize(size_t max_chunks);
82 };
83 
84 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
85 // to JSON output.
86 class BASE_EXPORT TraceResultBuffer {
87  public:
88   using OutputCallback = base::RepeatingCallback<void(const std::string&)>;
89 
90   // If you don't need to stream JSON chunks out efficiently, and just want to
91   // get a complete JSON string after calling Finish, use this struct to collect
92   // JSON trace output.
93   struct BASE_EXPORT SimpleOutput {
94     OutputCallback GetCallback();
95     void Append(const std::string& json_string);
96 
97     // Do what you want with the json_output_ string after calling
98     // TraceResultBuffer::Finish.
99     std::string json_output;
100   };
101 
102   TraceResultBuffer();
103   ~TraceResultBuffer();
104 
105   // Set callback. The callback will be called during Start with the initial
106   // JSON output and during AddFragment and Finish with following JSON output
107   // chunks. The callback target must live past the last calls to
108   // TraceResultBuffer::Start/AddFragment/Finish.
109   void SetOutputCallback(OutputCallback json_chunk_callback);
110 
111   // Start JSON output. This resets all internal state, so you can reuse
112   // the TraceResultBuffer by calling Start.
113   void Start();
114 
115   // Call AddFragment 0 or more times to add trace fragments from TraceLog.
116   void AddFragment(const std::string& trace_fragment);
117 
118   // When all fragments have been added, call Finish to complete the JSON
119   // formatted output.
120   void Finish();
121 
122  private:
123   OutputCallback output_callback_;
124   bool append_comma_;
125 };
126 
127 }  // namespace trace_event
128 }  // namespace base
129 
130 #endif  // BASE_TRACE_EVENT_TRACE_BUFFER_H_
131