metric_data_collector.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright 2021 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. #include "components/reporting/metrics/metric_data_collector.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/logging.h"
  8. #include "base/task/bind_post_task.h"
  9. #include "base/threading/sequenced_task_runner_handle.h"
  10. #include "components/reporting/metrics/metric_rate_controller.h"
  11. #include "components/reporting/metrics/metric_report_queue.h"
  12. #include "components/reporting/metrics/metric_reporting_controller.h"
  13. #include "components/reporting/util/status.h"
  14. namespace reporting {
  15. CollectorBase::CollectorBase(Sampler* sampler,
  16. MetricReportQueue* metric_report_queue)
  17. : sampler_(sampler), metric_report_queue_(metric_report_queue) {}
  18. CollectorBase::~CollectorBase() {
  19. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  20. }
  21. void CollectorBase::Collect() {
  22. CHECK(base::SequencedTaskRunnerHandle::IsSet());
  23. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  24. auto on_collected_cb = base::BindOnce(&CollectorBase::OnMetricDataCollected,
  25. weak_ptr_factory_.GetWeakPtr());
  26. sampler_->MaybeCollect(base::BindPostTask(
  27. base::SequencedTaskRunnerHandle::Get(), std::move(on_collected_cb)));
  28. }
  29. void CollectorBase::ReportMetricData(MetricData metric_data,
  30. base::OnceClosure on_data_reported) {
  31. auto enqueue_cb = base::BindOnce(
  32. [](base::OnceClosure on_data_reported, Status status) {
  33. if (!status.ok()) {
  34. DVLOG(1) << "Could not enqueue event to reporting queue because of: "
  35. << status;
  36. }
  37. std::move(on_data_reported).Run();
  38. },
  39. std::move(on_data_reported));
  40. metric_report_queue_->Enqueue(
  41. std::make_unique<MetricData>(std::move(metric_data)),
  42. std::move(enqueue_cb));
  43. }
  44. OneShotCollector::OneShotCollector(Sampler* sampler,
  45. MetricReportQueue* metric_report_queue,
  46. ReportingSettings* reporting_settings,
  47. const std::string& setting_path,
  48. bool setting_enabled_default_value,
  49. base::OnceClosure on_data_reported)
  50. : CollectorBase(sampler, metric_report_queue),
  51. on_data_reported_(std::move(on_data_reported)) {
  52. reporting_controller_ = std::make_unique<MetricReportingController>(
  53. reporting_settings, setting_path, setting_enabled_default_value,
  54. base::BindRepeating(&OneShotCollector::Collect, base::Unretained(this)));
  55. }
  56. OneShotCollector::~OneShotCollector() = default;
  57. void OneShotCollector::Collect() {
  58. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  59. if (data_collected_) {
  60. return;
  61. }
  62. data_collected_ = true;
  63. reporting_controller_.reset();
  64. CollectorBase::Collect();
  65. }
  66. void OneShotCollector::OnMetricDataCollected(
  67. absl::optional<MetricData> metric_data) {
  68. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  69. DCHECK(on_data_reported_);
  70. if (!metric_data.has_value()) {
  71. return;
  72. }
  73. metric_data->set_timestamp_ms(base::Time::Now().ToJavaTime());
  74. ReportMetricData(std::move(metric_data.value()),
  75. std::move(on_data_reported_));
  76. }
  77. PeriodicCollector::PeriodicCollector(Sampler* sampler,
  78. MetricReportQueue* metric_report_queue,
  79. ReportingSettings* reporting_settings,
  80. const std::string& enable_setting_path,
  81. bool setting_enabled_default_value,
  82. const std::string& rate_setting_path,
  83. base::TimeDelta default_rate,
  84. int rate_unit_to_ms)
  85. : CollectorBase(sampler, metric_report_queue),
  86. rate_controller_(std::make_unique<MetricRateController>(
  87. base::BindRepeating(&PeriodicCollector::Collect,
  88. base::Unretained(this)),
  89. reporting_settings,
  90. rate_setting_path,
  91. default_rate,
  92. rate_unit_to_ms)),
  93. reporting_controller_(std::make_unique<MetricReportingController>(
  94. reporting_settings,
  95. enable_setting_path,
  96. setting_enabled_default_value,
  97. base::BindRepeating(&PeriodicEventCollector::StartPeriodicCollection,
  98. base::Unretained(this)),
  99. base::BindRepeating(&PeriodicEventCollector::StopPeriodicCollection,
  100. base::Unretained(this)))) {}
  101. PeriodicCollector::~PeriodicCollector() = default;
  102. void PeriodicCollector::OnMetricDataCollected(
  103. absl::optional<MetricData> metric_data) {
  104. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  105. if (!metric_data.has_value()) {
  106. return;
  107. }
  108. metric_data->set_timestamp_ms(base::Time::Now().ToJavaTime());
  109. ReportMetricData(std::move(metric_data.value()));
  110. }
  111. void PeriodicCollector::StartPeriodicCollection() {
  112. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  113. // Do initial collection at startup.
  114. Collect();
  115. rate_controller_->Start();
  116. }
  117. void PeriodicCollector::StopPeriodicCollection() {
  118. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  119. rate_controller_->Stop();
  120. }
  121. AdditionalSamplersCollector::AdditionalSamplersCollector(
  122. std::vector<Sampler*> samplers)
  123. : samplers_(std::move(samplers)) {
  124. DETACH_FROM_SEQUENCE(sequence_checker_);
  125. }
  126. AdditionalSamplersCollector::~AdditionalSamplersCollector() {
  127. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  128. }
  129. void AdditionalSamplersCollector::CollectAll(
  130. OptionalMetricCallback on_all_collected_cb,
  131. MetricData metric_data) const {
  132. CollectAdditionalMetricData(
  133. /*sampler_index=*/0, std::move(on_all_collected_cb),
  134. std::move(metric_data), /*new_metric_data=*/absl::nullopt);
  135. }
  136. void AdditionalSamplersCollector::CollectAdditionalMetricData(
  137. uint64_t sampler_index,
  138. OptionalMetricCallback on_all_collected_cb,
  139. MetricData metric_data,
  140. absl::optional<MetricData> new_metric_data) const {
  141. CHECK(base::SequencedTaskRunnerHandle::IsSet());
  142. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  143. if (new_metric_data.has_value()) {
  144. metric_data.CheckTypeAndMergeFrom(new_metric_data.value());
  145. }
  146. if (sampler_index == samplers_.size()) {
  147. std::move(on_all_collected_cb).Run(std::move(metric_data));
  148. return;
  149. }
  150. auto on_collected_cb =
  151. base::BindOnce(&AdditionalSamplersCollector::CollectAdditionalMetricData,
  152. weak_ptr_factory_.GetWeakPtr(), sampler_index + 1,
  153. std::move(on_all_collected_cb), std::move(metric_data));
  154. samplers_[sampler_index]->MaybeCollect(base::BindPostTask(
  155. base::SequencedTaskRunnerHandle::Get(), std::move(on_collected_cb)));
  156. }
  157. PeriodicEventCollector::PeriodicEventCollector(
  158. Sampler* sampler,
  159. std::unique_ptr<EventDetector> event_detector,
  160. std::vector<Sampler*> additional_samplers,
  161. MetricReportQueue* metric_report_queue,
  162. ReportingSettings* reporting_settings,
  163. const std::string& enable_setting_path,
  164. bool setting_enabled_default_value,
  165. const std::string& rate_setting_path,
  166. base::TimeDelta default_rate,
  167. int rate_unit_to_ms)
  168. : PeriodicCollector(sampler,
  169. metric_report_queue,
  170. reporting_settings,
  171. enable_setting_path,
  172. setting_enabled_default_value,
  173. rate_setting_path,
  174. default_rate,
  175. rate_unit_to_ms),
  176. event_detector_(std::move(event_detector)),
  177. additional_samplers_collector_(
  178. std::make_unique<AdditionalSamplersCollector>(
  179. std::move(additional_samplers))) {}
  180. PeriodicEventCollector::~PeriodicEventCollector() = default;
  181. void PeriodicEventCollector::OnMetricDataCollected(
  182. absl::optional<MetricData> metric_data) {
  183. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  184. if (!metric_data.has_value()) {
  185. return;
  186. }
  187. metric_data->set_timestamp_ms(base::Time::Now().ToJavaTime());
  188. absl::optional<MetricEventType> event =
  189. event_detector_->DetectEvent(last_collected_data_, metric_data.value());
  190. last_collected_data_ = std::move(metric_data.value());
  191. if (!event.has_value()) {
  192. return;
  193. }
  194. last_collected_data_.mutable_event_data()->set_type(event.value());
  195. additional_samplers_collector_->CollectAll(
  196. base::BindOnce(&PeriodicEventCollector::OnAdditionalMetricDataCollected,
  197. base::Unretained(this)),
  198. /*metric_data=*/last_collected_data_);
  199. }
  200. void PeriodicEventCollector::OnAdditionalMetricDataCollected(
  201. absl::optional<MetricData> metric_data) {
  202. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  203. if (!metric_data.has_value()) {
  204. NOTREACHED() << "Metric data is unexpectedly empty after additional metric "
  205. << "collection.";
  206. return;
  207. }
  208. ReportMetricData(std::move(metric_data.value()));
  209. }
  210. } // namespace reporting