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 type()146 EventType type() const { return data_->type; } source()147 Source source() const { return data_->source; } phase()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: BoundNetLog()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 source()395 const NetLog::Source& source() const { return source_; } net_log()396 NetLog* net_log() const { return net_log_; } 397 398 private: BoundNetLog(const NetLog::Source & source,NetLog * net_log)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