net_log.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // Copyright (c) 2012 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 "net/log/net_log.h"
  5. #include "base/check_op.h"
  6. #include "base/containers/contains.h"
  7. #include "base/no_destructor.h"
  8. #include "base/notreached.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "base/values.h"
  11. #include "net/log/net_log_values.h"
  12. namespace net {
  13. NetLog::ThreadSafeObserver::ThreadSafeObserver() = default;
  14. NetLog::ThreadSafeObserver::~ThreadSafeObserver() {
  15. // Make sure we aren't watching a NetLog on destruction. Because the NetLog
  16. // may pass events to each observer on multiple threads, we cannot safely
  17. // stop watching a NetLog automatically from a parent class.
  18. DCHECK(!net_log_);
  19. }
  20. NetLogCaptureMode NetLog::ThreadSafeObserver::capture_mode() const {
  21. DCHECK(net_log_);
  22. return capture_mode_;
  23. }
  24. NetLog* NetLog::ThreadSafeObserver::net_log() const {
  25. return net_log_;
  26. }
  27. NetLog::ThreadSafeCaptureModeObserver::ThreadSafeCaptureModeObserver() =
  28. default;
  29. NetLog::ThreadSafeCaptureModeObserver::~ThreadSafeCaptureModeObserver() =
  30. default;
  31. NetLogCaptureModeSet
  32. NetLog::ThreadSafeCaptureModeObserver::GetObserverCaptureModes() const {
  33. DCHECK(net_log_);
  34. return net_log_->GetObserverCaptureModes();
  35. }
  36. void NetLog::ThreadSafeCaptureModeObserver::
  37. AddEntryAtTimeWithMaterializedParams(NetLogEventType type,
  38. const NetLogSource& source,
  39. NetLogEventPhase phase,
  40. base::TimeTicks time,
  41. base::Value&& params) {
  42. DCHECK(net_log_);
  43. net_log_->AddEntryAtTimeWithMaterializedParams(type, source, phase, time,
  44. std::move(params));
  45. }
  46. // static
  47. NetLog* NetLog::Get() {
  48. static base::NoDestructor<NetLog> instance{base::PassKey<NetLog>()};
  49. return instance.get();
  50. }
  51. NetLog::NetLog(base::PassKey<NetLog>) {}
  52. NetLog::NetLog(base::PassKey<NetLogWithSource>) {}
  53. void NetLog::AddEntry(NetLogEventType type,
  54. const NetLogSource& source,
  55. NetLogEventPhase phase) {
  56. AddEntry(type, source, phase, [] { return base::Value(); });
  57. }
  58. void NetLog::AddGlobalEntry(NetLogEventType type) {
  59. AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
  60. NetLogEventPhase::NONE);
  61. }
  62. void NetLog::AddGlobalEntryWithStringParams(NetLogEventType type,
  63. base::StringPiece name,
  64. base::StringPiece value) {
  65. AddGlobalEntry(type, [&] { return NetLogParamsWithString(name, value); });
  66. }
  67. uint32_t NetLog::NextID() {
  68. return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
  69. }
  70. void NetLog::AddObserver(NetLog::ThreadSafeObserver* observer,
  71. NetLogCaptureMode capture_mode) {
  72. base::AutoLock lock(lock_);
  73. DCHECK(!observer->net_log_);
  74. DCHECK(!HasObserver(observer));
  75. DCHECK_LT(observers_.size(), 20u); // Performance sanity check.
  76. observers_.push_back(observer);
  77. observer->net_log_ = this;
  78. observer->capture_mode_ = capture_mode;
  79. UpdateObserverCaptureModes();
  80. }
  81. void NetLog::RemoveObserver(NetLog::ThreadSafeObserver* observer) {
  82. base::AutoLock lock(lock_);
  83. DCHECK_EQ(this, observer->net_log_);
  84. auto it = std::find(observers_.begin(), observers_.end(), observer);
  85. DCHECK(it != observers_.end());
  86. observers_.erase(it);
  87. observer->net_log_ = nullptr;
  88. observer->capture_mode_ = NetLogCaptureMode::kDefault;
  89. UpdateObserverCaptureModes();
  90. }
  91. void NetLog::AddCaptureModeObserver(
  92. NetLog::ThreadSafeCaptureModeObserver* observer) {
  93. base::AutoLock lock(lock_);
  94. DCHECK(!observer->net_log_);
  95. DCHECK(!HasCaptureModeObserver(observer));
  96. DCHECK_LT(capture_mode_observers_.size(), 20u); // Performance sanity check.
  97. observer->net_log_ = this;
  98. capture_mode_observers_.push_back(observer);
  99. }
  100. void NetLog::RemoveCaptureModeObserver(
  101. NetLog::ThreadSafeCaptureModeObserver* observer) {
  102. base::AutoLock lock(lock_);
  103. DCHECK_EQ(this, observer->net_log_);
  104. DCHECK(HasCaptureModeObserver(observer));
  105. auto it = std::find(capture_mode_observers_.begin(),
  106. capture_mode_observers_.end(), observer);
  107. DCHECK(it != capture_mode_observers_.end());
  108. capture_mode_observers_.erase(it);
  109. observer->net_log_ = nullptr;
  110. }
  111. void NetLog::UpdateObserverCaptureModes() {
  112. lock_.AssertAcquired();
  113. NetLogCaptureModeSet capture_mode_set = 0;
  114. for (const auto* observer : observers_)
  115. NetLogCaptureModeSetAdd(observer->capture_mode_, &capture_mode_set);
  116. base::subtle::NoBarrier_Store(&observer_capture_modes_, capture_mode_set);
  117. // Notify any capture mode observers with the new |capture_mode_set|.
  118. for (auto* capture_mode_observer : capture_mode_observers_)
  119. capture_mode_observer->OnCaptureModeUpdated(capture_mode_set);
  120. }
  121. bool NetLog::HasObserver(ThreadSafeObserver* observer) {
  122. lock_.AssertAcquired();
  123. return base::Contains(observers_, observer);
  124. }
  125. bool NetLog::HasCaptureModeObserver(ThreadSafeCaptureModeObserver* observer) {
  126. lock_.AssertAcquired();
  127. return base::Contains(capture_mode_observers_, observer);
  128. }
  129. // static
  130. std::string NetLog::TickCountToString(const base::TimeTicks& time) {
  131. int64_t delta_time = time.since_origin().InMilliseconds();
  132. // TODO(https://crbug.com/915391): Use NetLogNumberValue().
  133. return base::NumberToString(delta_time);
  134. }
  135. // static
  136. std::string NetLog::TimeToString(const base::Time& time) {
  137. // Convert the base::Time to its (approximate) equivalent in base::TimeTicks.
  138. base::TimeTicks time_ticks =
  139. base::TimeTicks::UnixEpoch() + (time - base::Time::UnixEpoch());
  140. return TickCountToString(time_ticks);
  141. }
  142. // static
  143. base::Value NetLog::GetEventTypesAsValue() {
  144. base::Value::Dict dict;
  145. for (int i = 0; i < static_cast<int>(NetLogEventType::COUNT); ++i) {
  146. dict.Set(NetLogEventTypeToString(static_cast<NetLogEventType>(i)), i);
  147. }
  148. return base::Value(std::move(dict));
  149. }
  150. // static
  151. const char* NetLog::SourceTypeToString(NetLogSourceType source) {
  152. switch (source) {
  153. #define SOURCE_TYPE(label) \
  154. case NetLogSourceType::label: \
  155. return #label;
  156. #include "net/log/net_log_source_type_list.h"
  157. #undef SOURCE_TYPE
  158. default:
  159. NOTREACHED();
  160. return nullptr;
  161. }
  162. }
  163. // static
  164. base::Value NetLog::GetSourceTypesAsValue() {
  165. base::Value::Dict dict;
  166. for (int i = 0; i < static_cast<int>(NetLogSourceType::COUNT); ++i) {
  167. dict.Set(SourceTypeToString(static_cast<NetLogSourceType>(i)), i);
  168. }
  169. return base::Value(std::move(dict));
  170. }
  171. // static
  172. const char* NetLog::EventPhaseToString(NetLogEventPhase phase) {
  173. switch (phase) {
  174. case NetLogEventPhase::BEGIN:
  175. return "PHASE_BEGIN";
  176. case NetLogEventPhase::END:
  177. return "PHASE_END";
  178. case NetLogEventPhase::NONE:
  179. return "PHASE_NONE";
  180. }
  181. NOTREACHED();
  182. return nullptr;
  183. }
  184. void NetLog::InitializeSourceIdPartition() {
  185. int32_t old_value = base::subtle::NoBarrier_AtomicExchange(
  186. &last_id_, std::numeric_limits<base::subtle::Atomic32>::min());
  187. DCHECK_EQ(old_value, 0) << " NetLog::InitializeSourceIdPartition() called "
  188. "after NextID() or called multiple times";
  189. }
  190. void NetLog::AddEntryInternal(NetLogEventType type,
  191. const NetLogSource& source,
  192. NetLogEventPhase phase,
  193. const GetParamsInterface* get_params) {
  194. NetLogCaptureModeSet observer_capture_modes = GetObserverCaptureModes();
  195. for (int i = 0; i <= static_cast<int>(NetLogCaptureMode::kLast); ++i) {
  196. NetLogCaptureMode capture_mode = static_cast<NetLogCaptureMode>(i);
  197. if (!NetLogCaptureModeSetContains(capture_mode, observer_capture_modes))
  198. continue;
  199. NetLogEntry entry(type, source, phase, base::TimeTicks::Now(),
  200. get_params->GetParams(capture_mode));
  201. // Notify all of the log observers with |capture_mode|.
  202. base::AutoLock lock(lock_);
  203. for (auto* observer : observers_) {
  204. if (observer->capture_mode() == capture_mode)
  205. observer->OnAddEntry(entry);
  206. }
  207. }
  208. }
  209. void NetLog::AddEntryWithMaterializedParams(NetLogEventType type,
  210. const NetLogSource& source,
  211. NetLogEventPhase phase,
  212. base::Value&& params) {
  213. AddEntryAtTimeWithMaterializedParams(
  214. type, source, phase, base::TimeTicks::Now(), std::move(params));
  215. }
  216. void NetLog::AddEntryAtTimeWithMaterializedParams(NetLogEventType type,
  217. const NetLogSource& source,
  218. NetLogEventPhase phase,
  219. base::TimeTicks time,
  220. base::Value&& params) {
  221. NetLogEntry entry(type, source, phase, time, std::move(params));
  222. // Notify all of the log observers, regardless of capture mode.
  223. base::AutoLock lock(lock_);
  224. for (auto* observer : observers_) {
  225. observer->OnAddEntry(entry);
  226. }
  227. }
  228. } // namespace net