xref: /aosp_15_r20/external/cronet/net/log/net_log.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_LOG_NET_LOG_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_LOG_NET_LOG_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <vector>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/atomicops.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/types/pass_key.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
21*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_capture_mode.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_entry.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source_type.h"
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker namespace net {
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker class NetLogWithSource;
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker // NetLog is the destination for log messages generated by the network stack.
34*6777b538SAndroid Build Coastguard Worker // Each log message has a "source" field which identifies the specific entity
35*6777b538SAndroid Build Coastguard Worker // that generated the message (for example, which URLRequest or which
36*6777b538SAndroid Build Coastguard Worker // SpdySession).
37*6777b538SAndroid Build Coastguard Worker //
38*6777b538SAndroid Build Coastguard Worker // To avoid needing to pass in the "source ID" to the logging functions, NetLog
39*6777b538SAndroid Build Coastguard Worker // is usually accessed through a NetLogWithSource, which will always pass in a
40*6777b538SAndroid Build Coastguard Worker // specific source ID.
41*6777b538SAndroid Build Coastguard Worker //
42*6777b538SAndroid Build Coastguard Worker // All methods on NetLog are thread safe, with the exception that no NetLog or
43*6777b538SAndroid Build Coastguard Worker // NetLog::ThreadSafeObserver functions may be called by an observer's
44*6777b538SAndroid Build Coastguard Worker // OnAddEntry() method, as doing so will result in a deadlock.
45*6777b538SAndroid Build Coastguard Worker //
46*6777b538SAndroid Build Coastguard Worker // For a broader introduction see the design document:
47*6777b538SAndroid Build Coastguard Worker // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
48*6777b538SAndroid Build Coastguard Worker //
49*6777b538SAndroid Build Coastguard Worker // ==================================
50*6777b538SAndroid Build Coastguard Worker // Materializing parameters
51*6777b538SAndroid Build Coastguard Worker // ==================================
52*6777b538SAndroid Build Coastguard Worker //
53*6777b538SAndroid Build Coastguard Worker // Events can contain a JSON serializable base::Value [1] referred to as its
54*6777b538SAndroid Build Coastguard Worker // "parameters".
55*6777b538SAndroid Build Coastguard Worker //
56*6777b538SAndroid Build Coastguard Worker // Functions for emitting events have overloads that take a |get_params|
57*6777b538SAndroid Build Coastguard Worker // argument for this purpose.
58*6777b538SAndroid Build Coastguard Worker //
59*6777b538SAndroid Build Coastguard Worker // |get_params| is essentially a block of code to conditionally execute when
60*6777b538SAndroid Build Coastguard Worker // the parameters need to be materialized. It is most easily specified as a C++
61*6777b538SAndroid Build Coastguard Worker // lambda.
62*6777b538SAndroid Build Coastguard Worker //
63*6777b538SAndroid Build Coastguard Worker // This idiom for specifying parameters avoids spending time building the
64*6777b538SAndroid Build Coastguard Worker // base::Value when capturing is off. For instance when specified as a lambda
65*6777b538SAndroid Build Coastguard Worker // that takes 0 arguments, the inlined code from template expansion roughly
66*6777b538SAndroid Build Coastguard Worker // does:
67*6777b538SAndroid Build Coastguard Worker //
68*6777b538SAndroid Build Coastguard Worker //   if (net_log->IsCapturing()) {
69*6777b538SAndroid Build Coastguard Worker //     base::Value params = get_params();
70*6777b538SAndroid Build Coastguard Worker //     net_log->EmitEventToAllObsevers(type, source, phase, std::move(params));
71*6777b538SAndroid Build Coastguard Worker //   }
72*6777b538SAndroid Build Coastguard Worker //
73*6777b538SAndroid Build Coastguard Worker // Alternately, the |get_params| argument could be an invocable that takes a
74*6777b538SAndroid Build Coastguard Worker // NetLogCaptureMode parameter:
75*6777b538SAndroid Build Coastguard Worker //
76*6777b538SAndroid Build Coastguard Worker //   base::Value params = get_params(capture_mode);
77*6777b538SAndroid Build Coastguard Worker //
78*6777b538SAndroid Build Coastguard Worker // In this case, |get_params| depends on the logging granularity and would be
79*6777b538SAndroid Build Coastguard Worker // called once per observed NetLogCaptureMode.
80*6777b538SAndroid Build Coastguard Worker //
81*6777b538SAndroid Build Coastguard Worker // [1] Being "JSON serializable" means you cannot use
82*6777b538SAndroid Build Coastguard Worker //     base::Value::Type::BINARY. Instead use NetLogBinaryValue() to repackage
83*6777b538SAndroid Build Coastguard Worker //     it as a base::Value::Type::STRING.
84*6777b538SAndroid Build Coastguard Worker class NET_EXPORT NetLog {
85*6777b538SAndroid Build Coastguard Worker  public:
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker   // An observer that is notified of entries added to the NetLog. The
88*6777b538SAndroid Build Coastguard Worker   // "ThreadSafe" prefix of the name emphasizes that this observer may be
89*6777b538SAndroid Build Coastguard Worker   // called from different threads then the one which added it as an observer.
90*6777b538SAndroid Build Coastguard Worker   class NET_EXPORT ThreadSafeObserver {
91*6777b538SAndroid Build Coastguard Worker    public:
92*6777b538SAndroid Build Coastguard Worker     // Constructs an observer that wants to see network events, with
93*6777b538SAndroid Build Coastguard Worker     // the specified minimum event granularity.  A ThreadSafeObserver can only
94*6777b538SAndroid Build Coastguard Worker     // observe a single NetLog at a time.
95*6777b538SAndroid Build Coastguard Worker     //
96*6777b538SAndroid Build Coastguard Worker     // Observers will be called on the same thread an entry is added on,
97*6777b538SAndroid Build Coastguard Worker     // and are responsible for ensuring their own thread safety.
98*6777b538SAndroid Build Coastguard Worker     //
99*6777b538SAndroid Build Coastguard Worker     // Observers must stop watching a NetLog before either the observer or the
100*6777b538SAndroid Build Coastguard Worker     // NetLog is destroyed.
101*6777b538SAndroid Build Coastguard Worker     ThreadSafeObserver();
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker     ThreadSafeObserver(const ThreadSafeObserver&) = delete;
104*6777b538SAndroid Build Coastguard Worker     ThreadSafeObserver& operator=(const ThreadSafeObserver&) = delete;
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker     // Returns the capture mode for events this observer wants to
107*6777b538SAndroid Build Coastguard Worker     // receive. It is only valid to call this while observing a NetLog.
108*6777b538SAndroid Build Coastguard Worker     NetLogCaptureMode capture_mode() const;
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker     // Returns the NetLog being watched, or nullptr if there is none.
111*6777b538SAndroid Build Coastguard Worker     NetLog* net_log() const;
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker     // This method is called whenever an entry (event) was added to the NetLog
114*6777b538SAndroid Build Coastguard Worker     // being watched.
115*6777b538SAndroid Build Coastguard Worker     //
116*6777b538SAndroid Build Coastguard Worker     // OnAddEntry() is invoked on the thread which generated the NetLog entry,
117*6777b538SAndroid Build Coastguard Worker     // which may be different from the thread that added this observer.
118*6777b538SAndroid Build Coastguard Worker     //
119*6777b538SAndroid Build Coastguard Worker     // Whenever OnAddEntry() is invoked, the NetLog's mutex is held. The
120*6777b538SAndroid Build Coastguard Worker     // consequences of this are:
121*6777b538SAndroid Build Coastguard Worker     //
122*6777b538SAndroid Build Coastguard Worker     //   * OnAddEntry() will never be called concurrently -- implementations
123*6777b538SAndroid Build Coastguard Worker     //     can rely on this to avoid needing their own synchronization.
124*6777b538SAndroid Build Coastguard Worker     //
125*6777b538SAndroid Build Coastguard Worker     //   * It is illegal for an observer to call back into the NetLog, or the
126*6777b538SAndroid Build Coastguard Worker     //     observer itself, as this can result in deadlock or violating
127*6777b538SAndroid Build Coastguard Worker     //     expectations of non re-entrancy into ThreadSafeObserver.
128*6777b538SAndroid Build Coastguard Worker     virtual void OnAddEntry(const NetLogEntry& entry) = 0;
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker    protected:
131*6777b538SAndroid Build Coastguard Worker     virtual ~ThreadSafeObserver();
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker    private:
134*6777b538SAndroid Build Coastguard Worker     friend class NetLog;
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker     // Both of these values are only modified by the NetLog.
137*6777b538SAndroid Build Coastguard Worker     NetLogCaptureMode capture_mode_ = NetLogCaptureMode::kDefault;
138*6777b538SAndroid Build Coastguard Worker     raw_ptr<NetLog> net_log_ = nullptr;
139*6777b538SAndroid Build Coastguard Worker   };
140*6777b538SAndroid Build Coastguard Worker 
141*6777b538SAndroid Build Coastguard Worker   // An observer that is notified of changes in the capture mode set, and has
142*6777b538SAndroid Build Coastguard Worker   // the ability to add NetLog entries with materialized params.
143*6777b538SAndroid Build Coastguard Worker   class NET_EXPORT ThreadSafeCaptureModeObserver {
144*6777b538SAndroid Build Coastguard Worker    public:
145*6777b538SAndroid Build Coastguard Worker     ThreadSafeCaptureModeObserver();
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker     ThreadSafeCaptureModeObserver(const ThreadSafeCaptureModeObserver&) =
148*6777b538SAndroid Build Coastguard Worker         delete;
149*6777b538SAndroid Build Coastguard Worker     ThreadSafeCaptureModeObserver& operator=(
150*6777b538SAndroid Build Coastguard Worker         const ThreadSafeCaptureModeObserver&) = delete;
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker     virtual void OnCaptureModeUpdated(NetLogCaptureModeSet modes) = 0;
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker    protected:
155*6777b538SAndroid Build Coastguard Worker     virtual ~ThreadSafeCaptureModeObserver();
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker     NetLogCaptureModeSet GetObserverCaptureModes() const;
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker     // Add event to the observed NetLog. Must only be called while observing is
160*6777b538SAndroid Build Coastguard Worker     // active, and the caller is responsible for ensuring the materialized
161*6777b538SAndroid Build Coastguard Worker     // params are suitable for the current capture mode.
162*6777b538SAndroid Build Coastguard Worker     void AddEntryAtTimeWithMaterializedParams(NetLogEventType type,
163*6777b538SAndroid Build Coastguard Worker                                               const NetLogSource& source,
164*6777b538SAndroid Build Coastguard Worker                                               NetLogEventPhase phase,
165*6777b538SAndroid Build Coastguard Worker                                               base::TimeTicks time,
166*6777b538SAndroid Build Coastguard Worker                                               base::Value::Dict params);
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker    private:
169*6777b538SAndroid Build Coastguard Worker     // Friend NetLog so that AddCaptureModeObserver/RemoveCaptureModeObserver
170*6777b538SAndroid Build Coastguard Worker     // can update the |net_log_| member.
171*6777b538SAndroid Build Coastguard Worker     friend class NetLog;
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker     // This value is only modified by the NetLog.
174*6777b538SAndroid Build Coastguard Worker     raw_ptr<NetLog> net_log_ = nullptr;
175*6777b538SAndroid Build Coastguard Worker   };
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker   // Returns the singleton NetLog object, which is never destructed and which
178*6777b538SAndroid Build Coastguard Worker   // may be used on any thread.
179*6777b538SAndroid Build Coastguard Worker   static NetLog* Get();
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker   // NetLog should only be used through the singleton returned by Get(), the
182*6777b538SAndroid Build Coastguard Worker   // constructor takes a PassKey to ensure that additional NetLog objects
183*6777b538SAndroid Build Coastguard Worker   // cannot be created.
184*6777b538SAndroid Build Coastguard Worker   explicit NetLog(base::PassKey<NetLog>);
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   // NetLogWithSource creates a dummy NetLog as an internal optimization.
187*6777b538SAndroid Build Coastguard Worker   explicit NetLog(base::PassKey<NetLogWithSource>);
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   NetLog(const NetLog&) = delete;
190*6777b538SAndroid Build Coastguard Worker   NetLog& operator=(const NetLog&) = delete;
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   ~NetLog() = delete;
193*6777b538SAndroid Build Coastguard Worker 
194*6777b538SAndroid Build Coastguard Worker   // Configure the source IDs returned by NextID() to use a different starting
195*6777b538SAndroid Build Coastguard Worker   // position, so that NetLog events generated by this process will not conflict
196*6777b538SAndroid Build Coastguard Worker   // with those generated by another NetLog in a different process. This
197*6777b538SAndroid Build Coastguard Worker   // should only be called once, before any NetLogSource could be created in
198*6777b538SAndroid Build Coastguard Worker   // the current process.
199*6777b538SAndroid Build Coastguard Worker   //
200*6777b538SAndroid Build Coastguard Worker   // Currently only a single additional source id partition is supported.
201*6777b538SAndroid Build Coastguard Worker   void InitializeSourceIdPartition();
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker   void AddEntry(NetLogEventType type,
204*6777b538SAndroid Build Coastguard Worker                 const NetLogSource& source,
205*6777b538SAndroid Build Coastguard Worker                 NetLogEventPhase phase);
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   // NetLog parameter generators (lambdas) come in two flavors -- those that
208*6777b538SAndroid Build Coastguard Worker   // take no arguments, and those that take a single NetLogCaptureMode. This
209*6777b538SAndroid Build Coastguard Worker   // code allows differentiating between the two.
210*6777b538SAndroid Build Coastguard Worker   template <typename T, typename = void>
211*6777b538SAndroid Build Coastguard Worker   struct ExpectsCaptureMode : std::false_type {};
212*6777b538SAndroid Build Coastguard Worker   template <typename T>
213*6777b538SAndroid Build Coastguard Worker   struct ExpectsCaptureMode<T,
214*6777b538SAndroid Build Coastguard Worker                             decltype(void(std::declval<T>()(
215*6777b538SAndroid Build Coastguard Worker                                 NetLogCaptureMode::kDefault)))>
216*6777b538SAndroid Build Coastguard Worker       : std::true_type {};
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   // Adds an entry for the given source, phase, and type, whose parameters are
219*6777b538SAndroid Build Coastguard Worker   // obtained by invoking |get_params()| with no arguments.
220*6777b538SAndroid Build Coastguard Worker   //
221*6777b538SAndroid Build Coastguard Worker   // See "Materializing parameters" for details.
222*6777b538SAndroid Build Coastguard Worker   template <typename ParametersCallback>
223*6777b538SAndroid Build Coastguard Worker   inline typename std::enable_if<!ExpectsCaptureMode<ParametersCallback>::value,
224*6777b538SAndroid Build Coastguard Worker                                  void>::type
225*6777b538SAndroid Build Coastguard Worker   AddEntry(NetLogEventType type,
226*6777b538SAndroid Build Coastguard Worker            const NetLogSource& source,
227*6777b538SAndroid Build Coastguard Worker            NetLogEventPhase phase,
228*6777b538SAndroid Build Coastguard Worker            const ParametersCallback& get_params) {
229*6777b538SAndroid Build Coastguard Worker     if (LIKELY(!IsCapturing()))
230*6777b538SAndroid Build Coastguard Worker       return;
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker     AddEntryWithMaterializedParams(type, source, phase, get_params());
233*6777b538SAndroid Build Coastguard Worker   }
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   // Adds an entry for the given source, phase, and type, whose parameters are
236*6777b538SAndroid Build Coastguard Worker   // obtained by invoking |get_params(capture_mode)| with a NetLogCaptureMode.
237*6777b538SAndroid Build Coastguard Worker   //
238*6777b538SAndroid Build Coastguard Worker   // See "Materializing parameters" for details.
239*6777b538SAndroid Build Coastguard Worker   template <typename ParametersCallback>
240*6777b538SAndroid Build Coastguard Worker   inline typename std::enable_if<ExpectsCaptureMode<ParametersCallback>::value,
241*6777b538SAndroid Build Coastguard Worker                                  void>::type
242*6777b538SAndroid Build Coastguard Worker   AddEntry(NetLogEventType type,
243*6777b538SAndroid Build Coastguard Worker            const NetLogSource& source,
244*6777b538SAndroid Build Coastguard Worker            NetLogEventPhase phase,
245*6777b538SAndroid Build Coastguard Worker            const ParametersCallback& get_params) {
246*6777b538SAndroid Build Coastguard Worker     if (LIKELY(!IsCapturing()))
247*6777b538SAndroid Build Coastguard Worker       return;
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker     // Indirect through virtual dispatch to reduce code bloat, as this is
250*6777b538SAndroid Build Coastguard Worker     // inlined in a number of places.
251*6777b538SAndroid Build Coastguard Worker     class GetParamsImpl : public GetParamsInterface {
252*6777b538SAndroid Build Coastguard Worker      public:
253*6777b538SAndroid Build Coastguard Worker       explicit GetParamsImpl(const ParametersCallback& get_params)
254*6777b538SAndroid Build Coastguard Worker           : get_params_(get_params) {}
255*6777b538SAndroid Build Coastguard Worker       base::Value::Dict GetParams(NetLogCaptureMode mode) const override {
256*6777b538SAndroid Build Coastguard Worker         return (*get_params_)(mode);
257*6777b538SAndroid Build Coastguard Worker       }
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker      private:
260*6777b538SAndroid Build Coastguard Worker       const raw_ref<const ParametersCallback> get_params_;
261*6777b538SAndroid Build Coastguard Worker     };
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker     GetParamsImpl wrapper(get_params);
264*6777b538SAndroid Build Coastguard Worker     AddEntryInternal(type, source, phase, &wrapper);
265*6777b538SAndroid Build Coastguard Worker   }
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker   // Emits a global event to the log stream, with its own unique source ID.
268*6777b538SAndroid Build Coastguard Worker   void AddGlobalEntry(NetLogEventType type);
269*6777b538SAndroid Build Coastguard Worker 
270*6777b538SAndroid Build Coastguard Worker   // Overload of AddGlobalEntry() that includes parameters.
271*6777b538SAndroid Build Coastguard Worker   //
272*6777b538SAndroid Build Coastguard Worker   // See "Materializing parameters" for details on |get_params|.
273*6777b538SAndroid Build Coastguard Worker   template <typename ParametersCallback>
274*6777b538SAndroid Build Coastguard Worker   void AddGlobalEntry(NetLogEventType type,
275*6777b538SAndroid Build Coastguard Worker                       const ParametersCallback& get_params) {
276*6777b538SAndroid Build Coastguard Worker     AddEntry(type, NetLogSource(NetLogSourceType::NONE, NextID()),
277*6777b538SAndroid Build Coastguard Worker              NetLogEventPhase::NONE, get_params);
278*6777b538SAndroid Build Coastguard Worker   }
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker   void AddGlobalEntryWithStringParams(NetLogEventType type,
281*6777b538SAndroid Build Coastguard Worker                                       std::string_view name,
282*6777b538SAndroid Build Coastguard Worker                                       std::string_view value);
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker   // Returns a unique ID which can be used as a source ID.  All returned IDs
285*6777b538SAndroid Build Coastguard Worker   // will be unique and not equal to 0.
286*6777b538SAndroid Build Coastguard Worker   uint32_t NextID();
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker   // Returns true if there are any observers attached to the NetLog.
289*6777b538SAndroid Build Coastguard Worker   //
290*6777b538SAndroid Build Coastguard Worker   // TODO(eroman): Survey current callsites; most are probably not necessary,
291*6777b538SAndroid Build Coastguard Worker   // and may even be harmful.
292*6777b538SAndroid Build Coastguard Worker   bool IsCapturing() const {
293*6777b538SAndroid Build Coastguard Worker     return GetObserverCaptureModes() != 0;
294*6777b538SAndroid Build Coastguard Worker   }
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker   // Adds an observer and sets its log capture mode.  The observer must not be
297*6777b538SAndroid Build Coastguard Worker   // watching any NetLog, including this one, when this is called.
298*6777b538SAndroid Build Coastguard Worker   //
299*6777b538SAndroid Build Coastguard Worker   // CAUTION: Think carefully before introducing a dependency on the
300*6777b538SAndroid Build Coastguard Worker   // NetLog. The order, format, and parameters in NetLog events are NOT
301*6777b538SAndroid Build Coastguard Worker   // guaranteed to be stable. As such, building a production feature that works
302*6777b538SAndroid Build Coastguard Worker   // by observing the NetLog is likely inappropriate. Just as you wouldn't build
303*6777b538SAndroid Build Coastguard Worker   // a feature by scraping the text output from LOG(INFO), you shouldn't do
304*6777b538SAndroid Build Coastguard Worker   // the same by scraping the logging data emitted to NetLog. Support for
305*6777b538SAndroid Build Coastguard Worker   // observers is an internal detail mainly used for testing and to write events
306*6777b538SAndroid Build Coastguard Worker   // to a file. Please consult a //net OWNER before using this outside of
307*6777b538SAndroid Build Coastguard Worker   // testing or serialization.
308*6777b538SAndroid Build Coastguard Worker   void AddObserver(ThreadSafeObserver* observer,
309*6777b538SAndroid Build Coastguard Worker                    NetLogCaptureMode capture_mode);
310*6777b538SAndroid Build Coastguard Worker 
311*6777b538SAndroid Build Coastguard Worker   // Removes an observer.
312*6777b538SAndroid Build Coastguard Worker   //
313*6777b538SAndroid Build Coastguard Worker   // For thread safety reasons, it is recommended that this not be called in
314*6777b538SAndroid Build Coastguard Worker   // an object's destructor.
315*6777b538SAndroid Build Coastguard Worker   void RemoveObserver(ThreadSafeObserver* observer);
316*6777b538SAndroid Build Coastguard Worker 
317*6777b538SAndroid Build Coastguard Worker   // Adds an observer that is notified of changes in the capture mode set.
318*6777b538SAndroid Build Coastguard Worker   void AddCaptureModeObserver(ThreadSafeCaptureModeObserver* observer);
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker   // Removes a capture mode observer.
321*6777b538SAndroid Build Coastguard Worker   void RemoveCaptureModeObserver(ThreadSafeCaptureModeObserver* observer);
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   // Converts a time to the string format that the NetLog uses to represent
324*6777b538SAndroid Build Coastguard Worker   // times.  Strings are used since integers may overflow.
325*6777b538SAndroid Build Coastguard Worker   // The resulting string contains the number of milliseconds since the origin
326*6777b538SAndroid Build Coastguard Worker   // or "zero" point of the TimeTicks class, which can vary each time the
327*6777b538SAndroid Build Coastguard Worker   // application is restarted. This number is related to an actual time via the
328*6777b538SAndroid Build Coastguard Worker   // timeTickOffset recorded in GetNetConstants().
329*6777b538SAndroid Build Coastguard Worker   static std::string TickCountToString(const base::TimeTicks& time);
330*6777b538SAndroid Build Coastguard Worker 
331*6777b538SAndroid Build Coastguard Worker   // Same as above but takes a base::Time. Should not be used if precise
332*6777b538SAndroid Build Coastguard Worker   // timestamps are desired, but is suitable for e.g. expiration times.
333*6777b538SAndroid Build Coastguard Worker   static std::string TimeToString(const base::Time& time);
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   // Returns a dictionary that maps event type symbolic names to their enum
336*6777b538SAndroid Build Coastguard Worker   // values.
337*6777b538SAndroid Build Coastguard Worker   static base::Value GetEventTypesAsValue();
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker   // Returns a C-String symbolic name for |source_type|.
340*6777b538SAndroid Build Coastguard Worker   static const char* SourceTypeToString(NetLogSourceType source_type);
341*6777b538SAndroid Build Coastguard Worker 
342*6777b538SAndroid Build Coastguard Worker   // Returns a dictionary that maps source type symbolic names to their enum
343*6777b538SAndroid Build Coastguard Worker   // values.
344*6777b538SAndroid Build Coastguard Worker   static base::Value GetSourceTypesAsValue();
345*6777b538SAndroid Build Coastguard Worker 
346*6777b538SAndroid Build Coastguard Worker   // Returns a C-String symbolic name for |event_phase|.
347*6777b538SAndroid Build Coastguard Worker   static const char* EventPhaseToString(NetLogEventPhase event_phase);
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker  private:
350*6777b538SAndroid Build Coastguard Worker   class GetParamsInterface {
351*6777b538SAndroid Build Coastguard Worker    public:
352*6777b538SAndroid Build Coastguard Worker     virtual base::Value::Dict GetParams(NetLogCaptureMode mode) const = 0;
353*6777b538SAndroid Build Coastguard Worker     virtual ~GetParamsInterface() = default;
354*6777b538SAndroid Build Coastguard Worker   };
355*6777b538SAndroid Build Coastguard Worker 
356*6777b538SAndroid Build Coastguard Worker   // Helper for implementing AddEntry() that indirects parameter getting through
357*6777b538SAndroid Build Coastguard Worker   // virtual dispatch.
358*6777b538SAndroid Build Coastguard Worker   void AddEntryInternal(NetLogEventType type,
359*6777b538SAndroid Build Coastguard Worker                         const NetLogSource& source,
360*6777b538SAndroid Build Coastguard Worker                         NetLogEventPhase phase,
361*6777b538SAndroid Build Coastguard Worker                         const GetParamsInterface* get_params);
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker   // Returns the set of all capture modes being observed.
364*6777b538SAndroid Build Coastguard Worker   NetLogCaptureModeSet GetObserverCaptureModes() const {
365*6777b538SAndroid Build Coastguard Worker     return base::subtle::NoBarrier_Load(&observer_capture_modes_);
366*6777b538SAndroid Build Coastguard Worker   }
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker   // Adds an entry using already materialized parameters, when it is already
369*6777b538SAndroid Build Coastguard Worker   // known that the log is capturing (goes straight to acquiring observer lock).
370*6777b538SAndroid Build Coastguard Worker   //
371*6777b538SAndroid Build Coastguard Worker   // TODO(eroman): Drop the rvalue-ref on |params| unless can show it improves
372*6777b538SAndroid Build Coastguard Worker   // the generated code (initial testing suggests it makes no difference in
373*6777b538SAndroid Build Coastguard Worker   // clang).
374*6777b538SAndroid Build Coastguard Worker   void AddEntryWithMaterializedParams(NetLogEventType type,
375*6777b538SAndroid Build Coastguard Worker                                       const NetLogSource& source,
376*6777b538SAndroid Build Coastguard Worker                                       NetLogEventPhase phase,
377*6777b538SAndroid Build Coastguard Worker                                       base::Value::Dict params);
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   // Adds an entry at a certain time, using already materialized parameters,
380*6777b538SAndroid Build Coastguard Worker   // when it is already known that the log is capturing (goes straight to
381*6777b538SAndroid Build Coastguard Worker   // acquiring observer lock).
382*6777b538SAndroid Build Coastguard Worker   void AddEntryAtTimeWithMaterializedParams(NetLogEventType type,
383*6777b538SAndroid Build Coastguard Worker                                             const NetLogSource& source,
384*6777b538SAndroid Build Coastguard Worker                                             NetLogEventPhase phase,
385*6777b538SAndroid Build Coastguard Worker                                             base::TimeTicks time,
386*6777b538SAndroid Build Coastguard Worker                                             base::Value::Dict params);
387*6777b538SAndroid Build Coastguard Worker 
388*6777b538SAndroid Build Coastguard Worker   // Called whenever an observer is added or removed, to update
389*6777b538SAndroid Build Coastguard Worker   // |observer_capture_modes_|. Must have acquired |lock_| prior to calling.
390*6777b538SAndroid Build Coastguard Worker   void UpdateObserverCaptureModes();
391*6777b538SAndroid Build Coastguard Worker 
392*6777b538SAndroid Build Coastguard Worker   // Returns true if |observer| is watching this NetLog. Must
393*6777b538SAndroid Build Coastguard Worker   // be called while |lock_| is already held.
394*6777b538SAndroid Build Coastguard Worker   bool HasObserver(ThreadSafeObserver* observer);
395*6777b538SAndroid Build Coastguard Worker   bool HasCaptureModeObserver(ThreadSafeCaptureModeObserver* observer);
396*6777b538SAndroid Build Coastguard Worker 
397*6777b538SAndroid Build Coastguard Worker   // |lock_| protects access to |observers_|.
398*6777b538SAndroid Build Coastguard Worker   base::Lock lock_;
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker   // Last assigned source ID.  Incremented to get the next one.
401*6777b538SAndroid Build Coastguard Worker   base::subtle::Atomic32 last_id_ = 0;
402*6777b538SAndroid Build Coastguard Worker 
403*6777b538SAndroid Build Coastguard Worker   // Holds the set of all capture modes that observers are watching the log at.
404*6777b538SAndroid Build Coastguard Worker   //
405*6777b538SAndroid Build Coastguard Worker   // Is 0 when there are no observers. Stored as an Atomic32 so it can be
406*6777b538SAndroid Build Coastguard Worker   // accessed and updated more efficiently.
407*6777b538SAndroid Build Coastguard Worker   base::subtle::Atomic32 observer_capture_modes_ = 0;
408*6777b538SAndroid Build Coastguard Worker 
409*6777b538SAndroid Build Coastguard Worker   // |observers_| is a list of observers, ordered by when they were added.
410*6777b538SAndroid Build Coastguard Worker   // Pointers contained in |observers_| are non-owned, and must
411*6777b538SAndroid Build Coastguard Worker   // remain valid.
412*6777b538SAndroid Build Coastguard Worker   //
413*6777b538SAndroid Build Coastguard Worker   // |lock_| must be acquired whenever reading or writing to this.
414*6777b538SAndroid Build Coastguard Worker   //
415*6777b538SAndroid Build Coastguard Worker   // In practice |observers_| will be very small (<5) so O(n)
416*6777b538SAndroid Build Coastguard Worker   // operations on it are fine.
417*6777b538SAndroid Build Coastguard Worker   std::vector<raw_ptr<ThreadSafeObserver, VectorExperimental>> observers_;
418*6777b538SAndroid Build Coastguard Worker 
419*6777b538SAndroid Build Coastguard Worker   std::vector<raw_ptr<ThreadSafeCaptureModeObserver, VectorExperimental>>
420*6777b538SAndroid Build Coastguard Worker       capture_mode_observers_;
421*6777b538SAndroid Build Coastguard Worker };
422*6777b538SAndroid Build Coastguard Worker 
423*6777b538SAndroid Build Coastguard Worker }  // namespace net
424*6777b538SAndroid Build Coastguard Worker 
425*6777b538SAndroid Build Coastguard Worker #endif  // NET_LOG_NET_LOG_H_
426