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
5#ifndef NET_BASE_NET_LOG_H_
6#define NET_BASE_NET_LOG_H_
7
8#include <string>
9
10#include "base/atomicops.h"
11#include "base/basictypes.h"
12#include "base/callback_forward.h"
13#include "base/compiler_specific.h"
14#include "base/observer_list.h"
15#include "base/strings/string16.h"
16#include "base/synchronization/lock.h"
17#include "base/time/time.h"
18#include "net/base/net_export.h"
19
20namespace base {
21class DictionaryValue;
22class Value;
23}
24
25namespace net {
26
27// NetLog is the destination for log messages generated by the network stack.
28// Each log message has a "source" field which identifies the specific entity
29// that generated the message (for example, which URLRequest or which
30// SocketStream).
31//
32// To avoid needing to pass in the "source ID" to the logging functions, NetLog
33// is usually accessed through a BoundNetLog, which will always pass in a
34// specific source ID.
35//
36// All methods are thread safe, with the exception that no NetLog or
37// NetLog::ThreadSafeObserver functions may be called by an observer's
38// OnAddEntry() method.  Doing so will result in a deadlock.
39//
40// For a broader introduction see the design document:
41// https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog
42class NET_EXPORT NetLog {
43 public:
44  enum EventType {
45#define EVENT_TYPE(label) TYPE_ ## label,
46#include "net/base/net_log_event_type_list.h"
47#undef EVENT_TYPE
48    EVENT_COUNT
49  };
50
51  // The 'phase' of an event trace (whether it marks the beginning or end
52  // of an event.).
53  enum EventPhase {
54    PHASE_NONE,
55    PHASE_BEGIN,
56    PHASE_END,
57  };
58
59  // The "source" identifies the entity that generated the log message.
60  enum SourceType {
61#define SOURCE_TYPE(label) SOURCE_ ## label,
62#include "net/base/net_log_source_type_list.h"
63#undef SOURCE_TYPE
64    SOURCE_COUNT
65  };
66
67  // Specifies the granularity of events that should be emitted to the log.
68  //
69  // Since the LogLevel may be read and set on any thread without locking, it
70  // may be possible for an Observer to receive an event or parameters that
71  // normally wouldn't be logged at the currently active log level.
72  enum LogLevel {
73    // Log everything possible, even if it is slow and memory expensive.
74    // Includes logging of transferred bytes.
75    LOG_ALL,
76
77    // Log all events, but do not include the actual transferred bytes as
78    // parameters for bytes sent/received events.
79    LOG_ALL_BUT_BYTES,
80
81    // Only log events which are cheap, and don't consume much memory.  This is
82    // the default value for observers.
83    LOG_BASIC,
84
85    // Don't log any events.
86    LOG_NONE,
87  };
88
89  // A callback function that return a Value representation of the parameters
90  // associated with an event.  If called, it will be called synchonously,
91  // so it need not have owning references.  May be called more than once, or
92  // not at all.  May return NULL.
93  typedef base::Callback<base::Value*(LogLevel)> ParametersCallback;
94
95  // Identifies the entity that generated this log. The |id| field should
96  // uniquely identify the source, and is used by log observers to infer
97  // message groupings. Can use NetLog::NextID() to create unique IDs.
98  struct NET_EXPORT Source {
99    static const uint32 kInvalidId;
100
101    Source();
102    Source(SourceType type, uint32 id);
103    bool IsValid() const;
104
105    // Adds the source to a DictionaryValue containing event parameters,
106    // using the name "source_dependency".
107    void AddToEventParameters(base::DictionaryValue* event_params) const;
108
109    // Returns a callback that returns a dictionary with a single entry
110    // named "source_dependecy" that describes |this|.
111    ParametersCallback ToEventParametersCallback() const;
112
113    // Attempts to extract a Source from a set of event parameters.  Returns
114    // true and writes the result to |source| on success.  Returns false and
115    // makes |source| an invalid source on failure.
116    // TODO(mmenke):  Long term, we want to remove this.
117    static bool FromEventParameters(base::Value* event_params, Source* source);
118
119    SourceType type;
120    uint32 id;
121  };
122
123  class NET_EXPORT Entry {
124   public:
125    Entry(EventType type,
126          Source source,
127          EventPhase phase,
128          base::TimeTicks time,
129          const ParametersCallback* parameters_callback,
130          LogLevel log_level);
131    ~Entry();
132
133    EventType type() const { return type_; }
134    Source source() const { return source_; }
135    EventPhase phase() const { return phase_; }
136
137    // Serializes the specified event to a Value.  The Value also includes the
138    // current time.  Caller takes ownership of returned Value.  Takes in a time
139    // to allow back-dating entries.
140    base::Value* ToValue() const;
141
142    // Returns the parameters as a Value.  Returns NULL if there are no
143    // parameters.  Caller takes ownership of returned Value.
144    base::Value* ParametersToValue() const;
145
146   private:
147    const EventType type_;
148    const Source source_;
149    const EventPhase phase_;
150    const base::TimeTicks time_;
151    const ParametersCallback* parameters_callback_;
152
153    // Log level when the event occurred.
154    const LogLevel log_level_;
155
156    // It is not safe to copy this class, since |parameters_callback_| may
157    // include pointers that become stale immediately after the event is added,
158    // even if the code were modified to keep its own copy of the callback.
159    DISALLOW_COPY_AND_ASSIGN(Entry);
160  };
161
162  // An observer, that must ensure its own thread safety, for events
163  // being added to a NetLog.
164  class NET_EXPORT ThreadSafeObserver {
165   public:
166    // Constructs an observer that wants to see network events, with
167    // the specified minimum event granularity.  A ThreadSafeObserver can only
168    // observe a single NetLog at a time.
169    //
170    // Observers will be called on the same thread an entry is added on,
171    // and are responsible for ensuring their own thread safety.
172    //
173    // Observers must stop watching a NetLog before either the Observer or the
174    // NetLog is destroyed.
175    ThreadSafeObserver();
176
177    // Returns the minimum log level for events this observer wants to
178    // receive.  Must not be called when not watching a NetLog.
179    LogLevel log_level() const;
180
181    // Returns the NetLog we are currently watching, if any.  Returns NULL
182    // otherwise.
183    NetLog* net_log() const;
184
185    // This method will be called on the thread that the event occurs on.  It
186    // is the responsibility of the observer to handle it in a thread safe
187    // manner.
188    //
189    // It is illegal for an Observer to call any NetLog or
190    // NetLog::Observer functions in response to a call to OnAddEntry.
191    virtual void OnAddEntry(const Entry& entry) = 0;
192
193   protected:
194    virtual ~ThreadSafeObserver();
195
196   private:
197    friend class NetLog;
198
199    // Both of these values are only modified by the NetLog.
200    LogLevel log_level_;
201    NetLog* net_log_;
202
203    DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
204  };
205
206  NetLog();
207  virtual ~NetLog();
208
209  // Emits a global event to the log stream, with its own unique source ID.
210  void AddGlobalEntry(EventType type);
211  void AddGlobalEntry(EventType type,
212                      const NetLog::ParametersCallback& parameters_callback);
213
214  // Returns a unique ID which can be used as a source ID.  All returned IDs
215  // will be unique and greater than 0.
216  uint32 NextID();
217
218  // Returns the logging level for this NetLog. This is used to avoid computing
219  // and saving expensive log entries.
220  LogLevel GetLogLevel() const;
221
222  // Adds an observer and sets its log level.  The observer must not be
223  // watching any NetLog, including this one, when this is called.
224  //
225  // Typical observers should specify LOG_BASIC.
226  //
227  // Observers that need to see the full granularity of events can specify
228  // LOG_ALL_BUT_BYTES. However, doing so will have performance consequences.
229  //
230  // NetLog implementations must call NetLog::OnAddObserver to update the
231  // observer's internal state.
232  void AddThreadSafeObserver(ThreadSafeObserver* observer, LogLevel log_level);
233
234  // Sets the log level of |observer| to |log_level|.  |observer| must be
235  // watching |this|.  NetLog implementations must call
236  // NetLog::OnSetObserverLogLevel to update the observer's internal state.
237  void SetObserverLogLevel(ThreadSafeObserver* observer, LogLevel log_level);
238
239  // Removes an observer.  NetLog implementations must call
240  // NetLog::OnAddObserver to update the observer's internal state.
241  //
242  // For thread safety reasons, it is recommended that this not be called in
243  // an object's destructor.
244  void RemoveThreadSafeObserver(ThreadSafeObserver* observer);
245
246  // Converts a time to the string format that the NetLog uses to represent
247  // times.  Strings are used since integers may overflow.
248  static std::string TickCountToString(const base::TimeTicks& time);
249
250  // Returns a C-String symbolic name for |event_type|.
251  static const char* EventTypeToString(EventType event_type);
252
253  // Returns a dictionary that maps event type symbolic names to their enum
254  // values.  Caller takes ownership of the returned Value.
255  static base::Value* GetEventTypesAsValue();
256
257  // Returns a C-String symbolic name for |source_type|.
258  static const char* SourceTypeToString(SourceType source_type);
259
260  // Returns a dictionary that maps source type symbolic names to their enum
261  // values.  Caller takes ownership of the returned Value.
262  static base::Value* GetSourceTypesAsValue();
263
264  // Returns a C-String symbolic name for |event_phase|.
265  static const char* EventPhaseToString(EventPhase event_phase);
266
267  // Returns true if |log_level| indicates the actual bytes transferred should
268  // be logged.  This is only the case when |log_level| is LOG_ALL.
269  static bool IsLoggingBytes(LogLevel log_level);
270
271  // Returns true if |log_level| indicates that all events should be logged,
272  // including frequently occuring ones that may impact performances.
273  // This is the case when |log_level| is LOG_ALL or LOG_ALL_BUT_BYTES.
274  static bool IsLoggingAllEvents(LogLevel log_level);
275
276  // Creates a ParametersCallback that encapsulates a single integer.
277  // Warning: |name| must remain valid for the life of the callback.
278  // TODO(mmenke):  Rename this to be consistent with Int64Callback.
279  static ParametersCallback IntegerCallback(const char* name, int value);
280
281  // Creates a ParametersCallback that encapsulates a single int64.  The
282  // callback will return the value as a StringValue, since IntegerValues
283  // only support 32-bit values.
284  // Warning: |name| must remain valid for the life of the callback.
285  static ParametersCallback Int64Callback(const char* name, int64 value);
286
287  // Creates a ParametersCallback that encapsulates a single UTF8 string.  Takes
288  // |value| as a pointer to avoid copying, and emphasize it must be valid for
289  // the life of the callback.  |value| may not be NULL.
290  // Warning: |name| and |value| must remain valid for the life of the callback.
291  static ParametersCallback StringCallback(const char* name,
292                                           const std::string* value);
293
294  // Same as above, but takes in a UTF16 string.
295  static ParametersCallback StringCallback(const char* name,
296                                           const base::string16* value);
297
298 protected:
299  // Set the lowest allowed log level, regardless of any Observers.
300  void SetBaseLogLevel(LogLevel log_level);
301
302 private:
303  friend class BoundNetLog;
304
305  void AddEntry(EventType type,
306                const Source& source,
307                EventPhase phase,
308                const NetLog::ParametersCallback* parameters_callback);
309
310  // Called whenever an observer is added or removed, or has its log level
311  // changed.  Must have acquired |lock_| prior to calling.
312  void UpdateLogLevel();
313
314  // |lock_| protects access to |observers_|.
315  base::Lock lock_;
316
317  // Last assigned source ID.  Incremented to get the next one.
318  base::subtle::Atomic32 last_id_;
319
320  // The lowest allowed log level, regardless of any Observers.
321  // Normally defaults to LOG_NONE, but can be changed with SetBaseLogLevel
322  LogLevel base_log_level_;
323
324  // The current log level.
325  base::subtle::Atomic32 effective_log_level_;
326
327  // |lock_| must be acquired whenever reading or writing to this.
328  ObserverList<ThreadSafeObserver, true> observers_;
329
330  DISALLOW_COPY_AND_ASSIGN(NetLog);
331};
332
333// Helper that binds a Source to a NetLog, and exposes convenience methods to
334// output log messages without needing to pass in the source.
335class NET_EXPORT BoundNetLog {
336 public:
337  BoundNetLog() : net_log_(NULL) {}
338
339  // Add a log entry to the NetLog for the bound source.
340  void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const;
341  void AddEntry(NetLog::EventType type,
342                NetLog::EventPhase phase,
343                const NetLog::ParametersCallback& get_parameters) const;
344
345  // Convenience methods that call AddEntry with a fixed "capture phase"
346  // (begin, end, or none).
347  void BeginEvent(NetLog::EventType type) const;
348  void BeginEvent(NetLog::EventType type,
349                  const NetLog::ParametersCallback& get_parameters) const;
350
351  void EndEvent(NetLog::EventType type) const;
352  void EndEvent(NetLog::EventType type,
353                const NetLog::ParametersCallback& get_parameters) const;
354
355  void AddEvent(NetLog::EventType type) const;
356  void AddEvent(NetLog::EventType type,
357                const NetLog::ParametersCallback& get_parameters) const;
358
359  // Just like AddEvent, except |net_error| is a net error code.  A parameter
360  // called "net_error" with the indicated value will be recorded for the event.
361  // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
362  // error.
363  void AddEventWithNetErrorCode(NetLog::EventType event_type,
364                                int net_error) const;
365
366  // Just like EndEvent, except |net_error| is a net error code.  If it's
367  // negative, a parameter called "net_error" with a value of |net_error| is
368  // associated with the event.  Otherwise, the end event has no parameters.
369  // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
370  void EndEventWithNetErrorCode(NetLog::EventType event_type,
371                                int net_error) const;
372
373  // Logs a byte transfer event to the NetLog.  Determines whether to log the
374  // received bytes or not based on the current logging level.
375  void AddByteTransferEvent(NetLog::EventType event_type,
376                            int byte_count, const char* bytes) const;
377
378  NetLog::LogLevel GetLogLevel() const;
379
380  // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()).
381  bool IsLoggingBytes() const;
382
383  // Shortcut for NetLog::IsLoggingAllEvents(this->GetLogLevel()).
384  bool IsLoggingAllEvents() const;
385
386  // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
387  // of creating a unique source ID, and handles the case of NULL net_log.
388  static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);
389
390  const NetLog::Source& source() const { return source_; }
391  NetLog* net_log() const { return net_log_; }
392
393 private:
394  BoundNetLog(const NetLog::Source& source, NetLog* net_log)
395      : source_(source), net_log_(net_log) {
396  }
397
398  NetLog::Source source_;
399  NetLog* net_log_;
400};
401
402}  // namespace net
403
404#endif  // NET_BASE_NET_LOG_H_
405