| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_BASE_NET_LOG_H_ |
| #define NET_BASE_NET_LOG_H_ |
| |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/callback_forward.h" |
| #include "base/compiler_specific.h" |
| #include "base/string16.h" |
| #include "base/time.h" |
| #include "net/base/net_export.h" |
| |
| namespace base { |
| class DictionaryValue; |
| class Value; |
| } |
| |
| namespace net { |
| |
| // NetLog is the destination for log messages generated by the network stack. |
| // Each log message has a "source" field which identifies the specific entity |
| // that generated the message (for example, which URLRequest or which |
| // SocketStream). |
| // |
| // To avoid needing to pass in the "source ID" to the logging functions, NetLog |
| // is usually accessed through a BoundNetLog, which will always pass in a |
| // specific source ID. |
| // |
| // All NetLog methods must be thread-safe. |
| // |
| // For a broader introduction see the design document: |
| // https://sites.google.com/a/chromium.org/dev/developers/design-documents/network-stack/netlog |
| class NET_EXPORT NetLog { |
| public: |
| enum EventType { |
| #define EVENT_TYPE(label) TYPE_ ## label, |
| #include "net/base/net_log_event_type_list.h" |
| #undef EVENT_TYPE |
| EVENT_COUNT |
| }; |
| |
| // The 'phase' of an event trace (whether it marks the beginning or end |
| // of an event.). |
| enum EventPhase { |
| PHASE_NONE, |
| PHASE_BEGIN, |
| PHASE_END, |
| }; |
| |
| // The "source" identifies the entity that generated the log message. |
| enum SourceType { |
| #define SOURCE_TYPE(label) SOURCE_ ## label, |
| #include "net/base/net_log_source_type_list.h" |
| #undef SOURCE_TYPE |
| SOURCE_COUNT |
| }; |
| |
| // Specifies the granularity of events that should be emitted to the log. |
| enum LogLevel { |
| // Log everything possible, even if it is slow and memory expensive. |
| // Includes logging of transferred bytes. |
| LOG_ALL, |
| |
| // Log all events, but do not include the actual transferred bytes as |
| // parameters for bytes sent/received events. |
| LOG_ALL_BUT_BYTES, |
| |
| // Only log events which are cheap, and don't consume much memory. |
| LOG_BASIC, |
| }; |
| |
| // A callback function that return a Value representation of the parameters |
| // associated with an event. If called, it will be called synchonously, |
| // so it need not have owning references. May be called more than once, or |
| // not at all. May return NULL. |
| typedef base::Callback<base::Value*(LogLevel)> ParametersCallback; |
| |
| // Identifies the entity that generated this log. The |id| field should |
| // uniquely identify the source, and is used by log observers to infer |
| // message groupings. Can use NetLog::NextID() to create unique IDs. |
| struct NET_EXPORT Source { |
| static const uint32 kInvalidId; |
| |
| Source(); |
| Source(SourceType type, uint32 id); |
| bool IsValid() const; |
| |
| // Adds the source to a DictionaryValue containing event parameters, |
| // using the name "source_dependency". |
| void AddToEventParameters(base::DictionaryValue* event_params) const; |
| |
| // Returns a callback that returns a dictionary with a single entry |
| // named "source_dependecy" that describes |this|. |
| ParametersCallback ToEventParametersCallback() const; |
| |
| // Attempts to extract a Source from a set of event parameters. Returns |
| // true and writes the result to |source| on success. Returns false and |
| // makes |source| an invalid source on failure. |
| // TODO(mmenke): Long term, we want to remove this. |
| static bool FromEventParameters(base::Value* event_params, Source* source); |
| |
| SourceType type; |
| uint32 id; |
| }; |
| |
| class NET_EXPORT Entry { |
| public: |
| Entry(EventType type, |
| Source source, |
| EventPhase phase, |
| base::TimeTicks time, |
| const ParametersCallback* parameters_callback, |
| LogLevel log_level); |
| ~Entry(); |
| |
| EventType type() const { return type_; } |
| Source source() const { return source_; } |
| EventPhase phase() const { return phase_; } |
| |
| // Serializes the specified event to a Value. The Value also includes the |
| // current time. Caller takes ownership of returned Value. Takes in a time |
| // to allow back-dating entries. |
| base::Value* ToValue() const; |
| |
| // Returns the parameters as a Value. Returns NULL if there are no |
| // parameters. Caller takes ownership of returned Value. |
| base::Value* ParametersToValue() const; |
| |
| private: |
| const EventType type_; |
| const Source source_; |
| const EventPhase phase_; |
| const base::TimeTicks time_; |
| const ParametersCallback* parameters_callback_; |
| |
| // Log level when the event occurred. |
| const LogLevel log_level_; |
| |
| // It is not safe to copy this class, since |parameters_callback_| may |
| // include pointers that become stale immediately after the event is added, |
| // even if the code were modified to keep its own copy of the callback. |
| DISALLOW_COPY_AND_ASSIGN(Entry); |
| }; |
| |
| // An observer, that must ensure its own thread safety, for events |
| // being added to a NetLog. |
| class NET_EXPORT ThreadSafeObserver { |
| public: |
| // Constructs an observer that wants to see network events, with |
| // the specified minimum event granularity. A ThreadSafeObserver can only |
| // observe a single NetLog at a time. |
| // |
| // Observers will be called on the same thread an entry is added on, |
| // and are responsible for ensuring their own thread safety. |
| // |
| // Observers must stop watching a NetLog before either the Observer or the |
| // NetLog is destroyed. |
| ThreadSafeObserver(); |
| |
| // Returns the minimum log level for events this observer wants to |
| // receive. Must not be called when not watching a NetLog. |
| LogLevel log_level() const; |
| |
| // Returns the NetLog we are currently watching, if any. Returns NULL |
| // otherwise. |
| NetLog* net_log() const; |
| |
| // This method will be called on the thread that the event occurs on. It |
| // is the responsibility of the observer to handle it in a thread safe |
| // manner. |
| // |
| // It is illegal for an Observer to call any NetLog or |
| // NetLog::Observer functions in response to a call to OnAddEntry. |
| virtual void OnAddEntry(const Entry& entry) = 0; |
| |
| protected: |
| virtual ~ThreadSafeObserver(); |
| |
| private: |
| friend class NetLog; |
| |
| // Both of these values are only modified by the NetLog. |
| LogLevel log_level_; |
| NetLog* net_log_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver); |
| }; |
| |
| NetLog() {} |
| virtual ~NetLog() {} |
| |
| // Emits a global event to the log stream, with its own unique source ID. |
| void AddGlobalEntry(EventType type); |
| void AddGlobalEntry(EventType type, |
| const NetLog::ParametersCallback& parameters_callback); |
| |
| // Returns a unique ID which can be used as a source ID. All returned IDs |
| // will be unique and greater than 0. |
| virtual uint32 NextID() = 0; |
| |
| // Returns the logging level for this NetLog. This is used to avoid computing |
| // and saving expensive log entries. |
| virtual LogLevel GetLogLevel() const = 0; |
| |
| // Adds an observer and sets its log level. The observer must not be |
| // watching any NetLog, including this one, when this is called. |
| // |
| // Typical observers should specify LOG_BASIC. |
| // |
| // Observers that need to see the full granularity of events can specify |
| // LOG_ALL_BUT_BYTES. However, doing so will have performance consequences. |
| // |
| // NetLog implementations must call NetLog::OnAddObserver to update the |
| // observer's internal state. |
| virtual void AddThreadSafeObserver(ThreadSafeObserver* observer, |
| LogLevel log_level) = 0; |
| |
| // Sets the log level of |observer| to |log_level|. |observer| must be |
| // watching |this|. NetLog implementations must call |
| // NetLog::OnSetObserverLogLevel to update the observer's internal state. |
| virtual void SetObserverLogLevel(ThreadSafeObserver* observer, |
| LogLevel log_level) = 0; |
| |
| // Removes an observer. NetLog implementations must call |
| // NetLog::OnAddObserver to update the observer's internal state. |
| // |
| // For thread safety reasons, it is recommended that this not be called in |
| // an object's destructor. |
| virtual void RemoveThreadSafeObserver(ThreadSafeObserver* observer) = 0; |
| |
| // Converts a time to the string format that the NetLog uses to represent |
| // times. Strings are used since integers may overflow. |
| static std::string TickCountToString(const base::TimeTicks& time); |
| |
| // Returns a C-String symbolic name for |event_type|. |
| static const char* EventTypeToString(EventType event_type); |
| |
| // Returns a dictionary that maps event type symbolic names to their enum |
| // values. Caller takes ownership of the returned Value. |
| static base::Value* GetEventTypesAsValue(); |
| |
| // Returns a C-String symbolic name for |source_type|. |
| static const char* SourceTypeToString(SourceType source_type); |
| |
| // Returns a dictionary that maps source type symbolic names to their enum |
| // values. Caller takes ownership of the returned Value. |
| static base::Value* GetSourceTypesAsValue(); |
| |
| // Returns a C-String symbolic name for |event_phase|. |
| static const char* EventPhaseToString(EventPhase event_phase); |
| |
| // Returns true if |log_level| indicates the actual bytes transferred should |
| // be logged. This is only the case when |log_level| is LOG_ALL. |
| static bool IsLoggingBytes(LogLevel log_level); |
| |
| // Returns true if |log_level| indicates that all events should be logged, |
| // including frequently occuring ones that may impact performances. |
| // This is the case when |log_level| is LOG_ALL or LOG_ALL_BUT_BYTES. |
| static bool IsLoggingAllEvents(LogLevel log_level); |
| |
| // Creates a ParametersCallback that encapsulates a single integer. |
| // Warning: |name| must remain valid for the life of the callback. |
| // TODO(mmenke): Rename this to be consistent with Int64Callback. |
| static ParametersCallback IntegerCallback(const char* name, int value); |
| |
| // Creates a ParametersCallback that encapsulates a single int64. The |
| // callback will return the value as a StringValue, since IntegerValues |
| // only support 32-bit values. |
| // Warning: |name| must remain valid for the life of the callback. |
| static ParametersCallback Int64Callback(const char* name, int64 value); |
| |
| // Creates a ParametersCallback that encapsulates a single UTF8 string. Takes |
| // |value| as a pointer to avoid copying, and emphasize it must be valid for |
| // the life of the callback. |value| may not be NULL. |
| // Warning: |name| and |value| must remain valid for the life of the callback. |
| static ParametersCallback StringCallback(const char* name, |
| const std::string* value); |
| |
| // Same as above, but takes in a UTF16 string. |
| static ParametersCallback StringCallback(const char* name, |
| const string16* value); |
| |
| protected: |
| // Child classes should respond to the new entry here. This includes |
| // creating the Entry object and alerting their observers. |
| virtual void OnAddEntry(const Entry& entry) = 0; |
| |
| // Subclasses must call these in the corresponding functions to set an |
| // observer's |net_log_| and |log_level_| values. |
| void OnAddObserver(ThreadSafeObserver* observer, LogLevel log_level); |
| void OnSetObserverLogLevel(ThreadSafeObserver* observer, |
| LogLevel log_level); |
| void OnRemoveObserver(ThreadSafeObserver* observer); |
| |
| private: |
| friend class BoundNetLog; |
| |
| void AddEntry(EventType type, |
| const Source& source, |
| EventPhase phase, |
| const NetLog::ParametersCallback* parameters_callback); |
| |
| DISALLOW_COPY_AND_ASSIGN(NetLog); |
| }; |
| |
| // Helper that binds a Source to a NetLog, and exposes convenience methods to |
| // output log messages without needing to pass in the source. |
| class NET_EXPORT BoundNetLog { |
| public: |
| BoundNetLog() : net_log_(NULL) {} |
| |
| // Add a log entry to the NetLog for the bound source. |
| void AddEntry(NetLog::EventType type, NetLog::EventPhase phase) const; |
| void AddEntry(NetLog::EventType type, |
| NetLog::EventPhase phase, |
| const NetLog::ParametersCallback& get_parameters) const; |
| |
| // Convenience methods that call AddEntry with a fixed "capture phase" |
| // (begin, end, or none). |
| void BeginEvent(NetLog::EventType type) const; |
| void BeginEvent(NetLog::EventType type, |
| const NetLog::ParametersCallback& get_parameters) const; |
| |
| void EndEvent(NetLog::EventType type) const; |
| void EndEvent(NetLog::EventType type, |
| const NetLog::ParametersCallback& get_parameters) const; |
| |
| void AddEvent(NetLog::EventType type) const; |
| void AddEvent(NetLog::EventType type, |
| const NetLog::ParametersCallback& get_parameters) const; |
| |
| // Just like AddEvent, except |net_error| is a net error code. A parameter |
| // called "net_error" with the indicated value will be recorded for the event. |
| // |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true |
| // error. |
| void AddEventWithNetErrorCode(NetLog::EventType event_type, |
| int net_error) const; |
| |
| // Just like EndEvent, except |net_error| is a net error code. If it's |
| // negative, a parameter called "net_error" with a value of |net_error| is |
| // associated with the event. Otherwise, the end event has no parameters. |
| // |net_error| must not be ERR_IO_PENDING, as it's not a true error. |
| void EndEventWithNetErrorCode(NetLog::EventType event_type, |
| int net_error) const; |
| |
| // Logs a byte transfer event to the NetLog. Determines whether to log the |
| // received bytes or not based on the current logging level. |
| void AddByteTransferEvent(NetLog::EventType event_type, |
| int byte_count, const char* bytes) const; |
| |
| NetLog::LogLevel GetLogLevel() const; |
| |
| // Shortcut for NetLog::IsLoggingBytes(this->GetLogLevel()). |
| bool IsLoggingBytes() const; |
| |
| // Shortcut for NetLog::IsLoggingAllEvents(this->GetLogLevel()). |
| bool IsLoggingAllEvents() const; |
| |
| // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care |
| // of creating a unique source ID, and handles the case of NULL net_log. |
| static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type); |
| |
| const NetLog::Source& source() const { return source_; } |
| NetLog* net_log() const { return net_log_; } |
| |
| private: |
| BoundNetLog(const NetLog::Source& source, NetLog* net_log) |
| : source_(source), net_log_(net_log) { |
| } |
| |
| NetLog::Source source_; |
| NetLog* net_log_; |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_BASE_NET_LOG_H_ |