summaryrefslogtreecommitdiff
path: root/chromium/services/tracing/public/cpp/perfetto/trace_event_data_source.h
blob: 4550cb0283c6177abb1c0f88139439539593c83c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_EVENT_DATA_SOURCE_H_
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_EVENT_DATA_SOURCE_H_

#include <atomic>
#include <memory>
#include <string>
#include <vector>

#include "base/component_export.h"
#include "base/macros.h"
#include "base/metrics/histogram_base.h"
#include "base/threading/thread_local.h"
#include "base/time/time.h"
#include "base/trace_event/trace_config.h"
#include "services/tracing/public/cpp/perfetto/producer_client.h"

namespace perfetto {
class StartupTraceWriter;
class StartupTraceWriterRegistry;
class TraceWriter;
}

namespace tracing {

class ThreadLocalEventSink;

// This class is a data source that clients can use to provide
// global metadata in dictionary form, by registering callbacks.
class COMPONENT_EXPORT(TRACING_CPP) TraceEventMetadataSource
    : public ProducerClient::DataSourceBase {
 public:
  TraceEventMetadataSource();
  ~TraceEventMetadataSource() override;

  using MetadataGeneratorFunction =
      base::RepeatingCallback<std::unique_ptr<base::DictionaryValue>()>;
  // Any callbacks passed here will be called when tracing starts.
  void AddGeneratorFunction(MetadataGeneratorFunction generator);

  // ProducerClient::DataSourceBase implementation, called by
  // ProducerClent.
  void StartTracing(
      ProducerClient* producer_client,
      const perfetto::DataSourceConfig& data_source_config) override;
  void StopTracing(base::OnceClosure stop_complete_callback) override;
  void Flush(base::RepeatingClosure flush_complete_callback) override;

 private:
  void GenerateMetadata(std::unique_ptr<perfetto::TraceWriter> trace_writer);
  std::unique_ptr<base::DictionaryValue> GenerateTraceConfigMetadataDict();

  std::vector<MetadataGeneratorFunction> generator_functions_;
  scoped_refptr<base::SequencedTaskRunner> origin_task_runner_;
  std::unique_ptr<perfetto::TraceWriter> trace_writer_;
  bool privacy_filtering_enabled_ = false;
  std::string chrome_config_;

  DISALLOW_COPY_AND_ASSIGN(TraceEventMetadataSource);
};

// This class acts as a bridge between the TraceLog and
// the Perfetto ProducerClient. It converts incoming
// trace events to ChromeTraceEvent protos and writes
// them into the Perfetto shared memory.
class COMPONENT_EXPORT(TRACING_CPP) TraceEventDataSource
    : public ProducerClient::DataSourceBase {
 public:
  static TraceEventDataSource* GetInstance();

  // Destroys and recreates the global instance for testing.
  static void ResetForTesting();

  // Flushes and deletes the TraceWriter for the current thread, if any.
  static void FlushCurrentThread();

  // Installs TraceLog overrides for tracing during Chrome startup. Trace data
  // is locally buffered until connection to the perfetto service is
  // established. Expects a later call to StartTracing() to bind to the perfetto
  // service. Should only be called once.
  void SetupStartupTracing();

  // The ProducerClient is responsible for calling StopTracing
  // which will clear the stored pointer to it, before it
  // gets destroyed. ProducerClient::CreateTraceWriter can be
  // called by the TraceEventDataSource on any thread.
  void StartTracing(
      ProducerClient* producer_client,
      const perfetto::DataSourceConfig& data_source_config) override;

  // Called from the ProducerClient.
  void StopTracing(base::OnceClosure stop_complete_callback) override;
  void Flush(base::RepeatingClosure flush_complete_callback) override;

  // Resets emitted incremental state on the current thread and causes
  // incremental data (e.g. interning index entries and a ThreadDescriptor) to
  // be emitted again.
  void ResetIncrementalStateForTesting();

  // Deletes TraceWriter safely on behalf of a ThreadLocalEventSink.
  void ReturnTraceWriter(
      std::unique_ptr<perfetto::StartupTraceWriter> trace_writer);

 private:
  friend class base::NoDestructor<TraceEventDataSource>;

  TraceEventDataSource();
  ~TraceEventDataSource() override;

  void RegisterWithTraceLog();
  void UnregisterFromTraceLog();

  ThreadLocalEventSink* CreateThreadLocalEventSink(bool thread_will_flush);

  // Callback from TraceLog, can be called from any thread.
  static void OnAddTraceEvent(base::trace_event::TraceEvent* trace_event,
                              bool thread_will_flush,
                              base::trace_event::TraceEventHandle* handle);
  static void OnUpdateDuration(base::trace_event::TraceEventHandle handle,
                               const base::TimeTicks& now,
                               const base::ThreadTicks& thread_now);

  // Extracts UMA histogram names that should be logged in traces and logs their
  // starting values.
  void ResetHistograms(const base::trace_event::TraceConfig& trace_config);
  // Logs selected UMA histogram.
  void LogHistograms();
  // Logs a given histogram in traces.
  void LogHistogram(base::HistogramBase* histogram);

  bool disable_interning_ = false;
  bool privacy_filtering_enabled_ = false;
  base::OnceClosure stop_complete_callback_;

  // Incremented and accessed atomically but without memory order guarantees.
  // This ID is incremented whenever a new tracing session is started.
  static constexpr uint32_t kInvalidSessionID = 0;
  static constexpr uint32_t kFirstSessionID = 1;
  std::atomic<uint32_t> session_id_{kInvalidSessionID};

  base::Lock lock_;  // Protects subsequent members.
  uint32_t target_buffer_ = 0;
  ProducerClient* producer_client_ = nullptr;
  // We own the registry during startup, but transfer its ownership to the
  // ProducerClient once the perfetto service is available. Only set if
  // SetupStartupTracing() is called.
  std::unique_ptr<perfetto::StartupTraceWriterRegistry>
      startup_writer_registry_;
  // Unbound writers created by the current |startup_writer_registry_|. We track
  // these writers to ensure that we only return the correct ones back to the
  // registry.
  std::set<perfetto::StartupTraceWriter*> trace_writers_from_registry_;
  std::vector<std::string> histograms_;

  DISALLOW_COPY_AND_ASSIGN(TraceEventDataSource);
};

}  // namespace tracing

#endif  // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_EVENT_DATA_SOURCE_H_