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