Home | History | Annotate | Download | only in base
      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 
     20 namespace base {
     21 class DictionaryValue;
     22 class Value;
     23 }
     24 
     25 namespace 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
     42 class 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     // Log all events, but do not include the actual transferred bytes and
     82     // remove cookies and HTTP credentials.
     83     LOG_STRIP_PRIVATE_DATA,
     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   struct NET_EXPORT EntryData {
    124     EntryData(EventType type,
    125               Source source,
    126               EventPhase phase,
    127               base::TimeTicks time,
    128               const ParametersCallback* parameters_callback);
    129     ~EntryData();
    130 
    131     const EventType type;
    132     const Source source;
    133     const EventPhase phase;
    134     const base::TimeTicks time;
    135     const ParametersCallback* const parameters_callback;
    136   };
    137 
    138   // An Entry pre-binds EntryData to a LogLevel, so observers will observe the
    139   // output of ToValue() and ParametersToValue() at their log level rather than
    140   // current maximum.
    141   class NET_EXPORT Entry {
    142    public:
    143     Entry(const EntryData* data, LogLevel log_level);
    144     ~Entry();
    145 
    146     EventType type() const { return data_->type; }
    147     Source source() const { return data_->source; }
    148     EventPhase phase() const { return data_->phase; }
    149 
    150     // Serializes the specified event to a Value.  The Value also includes the
    151     // current time.  Caller takes ownership of returned Value.  Takes in a time
    152     // to allow back-dating entries.
    153     base::Value* ToValue() const;
    154 
    155     // Returns the parameters as a Value.  Returns NULL if there are no
    156     // parameters.  Caller takes ownership of returned Value.
    157     base::Value* ParametersToValue() const;
    158 
    159    private:
    160     const EntryData* const data_;
    161 
    162     // Log level when the event occurred.
    163     const LogLevel log_level_;
    164 
    165     // It is not safe to copy this class, since |parameters_callback_| may
    166     // include pointers that become stale immediately after the event is added,
    167     // even if the code were modified to keep its own copy of the callback.
    168     DISALLOW_COPY_AND_ASSIGN(Entry);
    169   };
    170 
    171   // An observer, that must ensure its own thread safety, for events
    172   // being added to a NetLog.
    173   class NET_EXPORT ThreadSafeObserver {
    174    public:
    175     // Constructs an observer that wants to see network events, with
    176     // the specified minimum event granularity.  A ThreadSafeObserver can only
    177     // observe a single NetLog at a time.
    178     //
    179     // Observers will be called on the same thread an entry is added on,
    180     // and are responsible for ensuring their own thread safety.
    181     //
    182     // Observers must stop watching a NetLog before either the Observer or the
    183     // NetLog is destroyed.
    184     ThreadSafeObserver();
    185 
    186     // Returns the minimum log level for events this observer wants to
    187     // receive.  Must not be called when not watching a NetLog.
    188     LogLevel log_level() const;
    189 
    190     // Returns the NetLog we are currently watching, if any.  Returns NULL
    191     // otherwise.
    192     NetLog* net_log() const;
    193 
    194     // This method will be called on the thread that the event occurs on.  It
    195     // is the responsibility of the observer to handle it in a thread safe
    196     // manner.
    197     //
    198     // It is illegal for an Observer to call any NetLog or
    199     // NetLog::Observer functions in response to a call to OnAddEntry.
    200     virtual void OnAddEntry(const Entry& entry) = 0;
    201 
    202    protected:
    203     virtual ~ThreadSafeObserver();
    204 
    205    private:
    206     friend class NetLog;
    207 
    208     void OnAddEntryData(const EntryData& entry_data);
    209 
    210     // Both of these values are only modified by the NetLog.
    211     LogLevel log_level_;
    212     NetLog* net_log_;
    213 
    214     DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
    215   };
    216 
    217   NetLog();
    218   virtual ~NetLog();
    219 
    220   // Emits a global event to the log stream, with its own unique source ID.
    221   void AddGlobalEntry(EventType type);
    222   void AddGlobalEntry(EventType type,
    223                       const NetLog::ParametersCallback& parameters_callback);
    224 
    225   // Returns a unique ID which can be used as a source ID.  All returned IDs
    226   // will be unique and greater than 0.
    227   uint32 NextID();
    228 
    229   // Returns the logging level for this NetLog. This is used to avoid computing
    230   // and saving expensive log entries.
    231   LogLevel GetLogLevel() const;
    232 
    233   // Adds an observer and sets its log level.  The observer must not be
    234   // watching any NetLog, including this one, when this is called.
    235   //
    236   // NetLog implementations must call NetLog::OnAddObserver to update the
    237   // observer's internal state.
    238   void AddThreadSafeObserver(ThreadSafeObserver* observer, LogLevel log_level);
    239 
    240   // Sets the log level of |observer| to |log_level|.  |observer| must be
    241   // watching |this|.  NetLog implementations must call
    242   // NetLog::OnSetObserverLogLevel to update the observer's internal state.
    243   void SetObserverLogLevel(ThreadSafeObserver* observer, LogLevel log_level);
    244 
    245   // Removes an observer.  NetLog implementations must call
    246   // NetLog::OnAddObserver to update the observer's internal state.
    247   //
    248   // For thread safety reasons, it is recommended that this not be called in
    249   // an object's destructor.
    250   void RemoveThreadSafeObserver(ThreadSafeObserver* observer);
    251 
    252   // Converts a time to the string format that the NetLog uses to represent
    253   // times.  Strings are used since integers may overflow.
    254   static std::string TickCountToString(const base::TimeTicks& time);
    255 
    256   // Returns a C-String symbolic name for |event_type|.
    257   static const char* EventTypeToString(EventType event_type);
    258 
    259   // Returns a dictionary that maps event type symbolic names to their enum
    260   // values.  Caller takes ownership of the returned Value.
    261   static base::Value* GetEventTypesAsValue();
    262 
    263   // Returns a C-String symbolic name for |source_type|.
    264   static const char* SourceTypeToString(SourceType source_type);
    265 
    266   // Returns a dictionary that maps source type symbolic names to their enum
    267   // values.  Caller takes ownership of the returned Value.
    268   static base::Value* GetSourceTypesAsValue();
    269 
    270   // Returns a C-String symbolic name for |event_phase|.
    271   static const char* EventPhaseToString(EventPhase event_phase);
    272 
    273   // Returns true if |log_level| indicates the actual bytes transferred should
    274   // be logged.  This is only the case when |log_level| is LOG_ALL.
    275   static bool IsLoggingBytes(LogLevel log_level);
    276 
    277   // Returns true if |log_level| indicates that events should be logged. This is
    278   // the case when |log_level| is anything other than LOG_NONE.
    279   static bool IsLogging(LogLevel log_level);
    280 
    281   // Creates a ParametersCallback that encapsulates a single integer.
    282   // Warning: |name| must remain valid for the life of the callback.
    283   // TODO(mmenke):  Rename this to be consistent with Int64Callback.
    284   static ParametersCallback IntegerCallback(const char* name, int value);
    285 
    286   // Creates a ParametersCallback that encapsulates a single int64.  The
    287   // callback will return the value as a StringValue, since IntegerValues
    288   // only support 32-bit values.
    289   // Warning: |name| must remain valid for the life of the callback.
    290   static ParametersCallback Int64Callback(const char* name, int64 value);
    291 
    292   // Creates a ParametersCallback that encapsulates a single UTF8 string.  Takes
    293   // |value| as a pointer to avoid copying, and emphasize it must be valid for
    294   // the life of the callback.  |value| may not be NULL.
    295   // Warning: |name| and |value| must remain valid for the life of the callback.
    296   static ParametersCallback StringCallback(const char* name,
    297                                            const std::string* value);
    298 
    299   // Same as above, but takes in a UTF16 string.
    300   static ParametersCallback StringCallback(const char* name,
    301                                            const base::string16* value);
    302 
    303  protected:
    304   // Set the lowest allowed log level, regardless of any Observers.
    305   void SetBaseLogLevel(LogLevel log_level);
    306 
    307  private:
    308   friend class BoundNetLog;
    309 
    310   void AddEntry(EventType type,
    311                 const Source& source,
    312                 EventPhase phase,
    313                 const NetLog::ParametersCallback* parameters_callback);
    314 
    315   // Called whenever an observer is added or removed, or has its log level
    316   // changed.  Must have acquired |lock_| prior to calling.
    317   void UpdateLogLevel();
    318 
    319   // |lock_| protects access to |observers_|.
    320   base::Lock lock_;
    321 
    322   // Last assigned source ID.  Incremented to get the next one.
    323   base::subtle::Atomic32 last_id_;
    324 
    325   // The lowest allowed log level, regardless of any Observers.
    326   // Normally defaults to LOG_NONE, but can be changed with SetBaseLogLevel
    327   LogLevel base_log_level_;
    328 
    329   // The current log level.
    330   base::subtle::Atomic32 effective_log_level_;
    331 
    332   // |lock_| must be acquired whenever reading or writing to this.
    333   ObserverList<ThreadSafeObserver, true> observers_;
    334 
    335   DISALLOW_COPY_AND_ASSIGN(NetLog);
    336 };
    337 
    338 // Helper that binds a Source to a NetLog, and exposes convenience methods to
    339 // output log messages without needing to pass in the source.
    340 class NET_EXPORT BoundNetLog {
    341  public:
    342   BoundNetLog() : net_log_(NULL) {}
    343 
    344   // Add a log entry to the NetLog for the bound source.
    345   void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const;
    346   void AddEntry(NetLog::EventType type,
    347                 NetLog::EventPhase phase,
    348                 const NetLog::ParametersCallback& get_parameters) const;
    349 
    350   // Convenience methods that call AddEntry with a fixed "capture phase"
    351   // (begin, end, or none).
    352   void BeginEvent(NetLog::EventType type) const;
    353   void BeginEvent(NetLog::EventType type,
    354                   const NetLog::ParametersCallback& get_parameters) const;
    355 
    356   void EndEvent(NetLog::EventType type) const;
    357   void EndEvent(NetLog::EventType type,
    358                 const NetLog::ParametersCallback& get_parameters) const;
    359 
    360   void AddEvent(NetLog::EventType type) const;
    361   void AddEvent(NetLog::EventType type,
    362                 const NetLog::ParametersCallback& get_parameters) const;
    363 
    364   // Just like AddEvent, except |net_error| is a net error code.  A parameter
    365   // called "net_error" with the indicated value will be recorded for the event.
    366   // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
    367   // error.
    368   void AddEventWithNetErrorCode(NetLog::EventType event_type,
    369                                 int net_error) const;
    370 
    371   // Just like EndEvent, except |net_error| is a net error code.  If it's
    372   // negative, a parameter called "net_error" with a value of |net_error| is
    373   // associated with the event.  Otherwise, the end event has no parameters.
    374   // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
    375   void EndEventWithNetErrorCode(NetLog::EventType event_type,
    376                                 int net_error) const;
    377 
    378   // Logs a byte transfer event to the NetLog.  Determines whether to log the
    379   // received bytes or not based on the current logging level.
    380   void AddByteTransferEvent(NetLog::EventType event_type,
    381                             int byte_count, const char* bytes) const;
    382 
    383   NetLog::LogLevel GetLogLevel() const;
    384 
    385   // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()).
    386   bool IsLoggingBytes() const;
    387 
    388   // Shortcut for NetLog::IsLogging(this->GetLogLevel()).
    389   bool IsLogging() const;
    390 
    391   // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
    392   // of creating a unique source ID, and handles the case of NULL net_log.
    393   static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);
    394 
    395   const NetLog::Source& source() const { return source_; }
    396   NetLog* net_log() const { return net_log_; }
    397 
    398  private:
    399   BoundNetLog(const NetLog::Source& source, NetLog* net_log)
    400       : source_(source), net_log_(net_log) {
    401   }
    402 
    403   NetLog::Source source_;
    404   NetLog* net_log_;
    405 };
    406 
    407 }  // namespace net
    408 
    409 #endif  // NET_BASE_NET_LOG_H_
    410