summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/passive_log_collector.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/net/passive_log_collector.h')
-rw-r--r--chrome/browser/net/passive_log_collector.h179
1 files changed, 101 insertions, 78 deletions
diff --git a/chrome/browser/net/passive_log_collector.h b/chrome/browser/net/passive_log_collector.h
index 2c59b67..a514428 100644
--- a/chrome/browser/net/passive_log_collector.h
+++ b/chrome/browser/net/passive_log_collector.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_NET_PASSIVE_LOG_COLLECTOR_H_
#define CHROME_BROWSER_NET_PASSIVE_LOG_COLLECTOR_H_
+#include <deque>
#include <string>
#include <vector>
@@ -15,6 +16,21 @@
#include "chrome/browser/net/chrome_net_log.h"
#include "net/base/net_log.h"
+// PassiveLogCollector watches the NetLog event stream, and saves the network
+// event for recent requests, in a circular buffer.
+//
+// This is done so that when a network problem is encountered (performance
+// problem, or error), about:net-internals can be opened shortly after the
+// problem and it will contain a trace for the problem request.
+//
+// (This is in contrast to the "active logging" which captures every single
+// network event, but requires capturing to have been enabled *prior* to
+// encountering the problem. Active capturing is enabled as long as
+// about:net-internals is open).
+//
+// The data captured by PassiveLogCollector is grouped by NetLog::Source, into
+// a RequestInfo structure. These in turn are grouped by NetLog::SourceType, and
+// owned by a RequestTrackerBase instance for the specific source type.
class PassiveLogCollector : public ChromeNetLog::Observer {
public:
// This structure encapsulates all of the parameters of a captured event,
@@ -40,16 +56,13 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
};
typedef std::vector<Entry> EntryList;
+ typedef std::vector<net::NetLog::Source> SourceDependencyList;
+ // TODO(eroman): Rename to SourceInfo.
struct RequestInfo {
RequestInfo()
: source_id(net::NetLog::Source::kInvalidId),
- num_entries_truncated(0),
- total_bytes_transmitted(0),
- total_bytes_received(0),
- bytes_transmitted(0),
- bytes_received(0),
- last_tx_rx_position(0) {}
+ num_entries_truncated(0), reference_count(0), is_alive(true) {}
// Returns the URL that corresponds with this source. This is
// only meaningful for certain source types (URL_REQUEST, SOCKET_STREAM).
@@ -59,15 +72,21 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
uint32 source_id;
EntryList entries;
size_t num_entries_truncated;
- net::NetLog::Source subordinate_source;
-
- // Only used in SocketTracker.
- uint64 total_bytes_transmitted;
- uint64 total_bytes_received;
- uint64 bytes_transmitted;
- uint64 bytes_received;
- uint32 last_tx_rx_position; // The |order| of the last Tx or Rx entry.
- base::TimeTicks last_tx_rx_time; // The |time| of the last Tx or Rx entry.
+
+ // List of other sources which contain information relevant to this
+ // request (for example, a url request might depend on the log items
+ // for a connect job and for a socket that were bound to it.)
+ SourceDependencyList dependencies;
+
+ // Holds the count of how many other sources have added this as a
+ // dependent source. When it is 0, it means noone has referenced it so it
+ // can be deleted normally.
+ int reference_count;
+
+ // |is_alive| is set to false once the request has been added to the
+ // tracker's graveyard (it may still be kept around due to a non-zero
+ // reference_count, but it is still considered "dead").
+ bool is_alive;
};
typedef std::vector<RequestInfo> RequestInfoList;
@@ -76,19 +95,32 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
// URLRequests/SocketStreams/ConnectJobs.
class RequestTrackerBase {
public:
- explicit RequestTrackerBase(size_t max_graveyard_size);
+ RequestTrackerBase(size_t max_graveyard_size, PassiveLogCollector* parent);
- void OnAddEntry(const Entry& entry);
+ virtual ~RequestTrackerBase();
- RequestInfoList GetLiveRequests() const;
- void ClearRecentlyDeceased();
- RequestInfoList GetRecentlyDeceased() const;
+ void OnAddEntry(const Entry& entry);
+ // Clears all the passively logged data from this tracker.
void Clear();
// Appends all the captured entries to |out|. The ordering is undefined.
void AppendAllEntries(EntryList* out) const;
+#ifdef UNIT_TEST
+ // Helper used to inspect the current state by unit-tests.
+ // Retuns a copy of the requests held by the tracker.
+ RequestInfoList GetAllDeadOrAliveRequests(bool is_alive) const {
+ RequestInfoList result;
+ for (SourceIDToInfoMap::const_iterator it = requests_.begin();
+ it != requests_.end(); ++it) {
+ if (it->second.is_alive == is_alive)
+ result.push_back(it->second);
+ }
+ return result;
+ }
+#endif
+
protected:
enum Action {
ACTION_NONE,
@@ -96,29 +128,45 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
ACTION_MOVE_TO_GRAVEYARD,
};
- // Finds a request, either in the live entries or the graveyard and returns
- // it.
- RequestInfo* GetRequestInfo(uint32 id);
-
- // When GetLiveRequests() is called, RequestTrackerBase calls this method
- // for each entry after adding it to the list which will be returned
- // to the caller.
- virtual void OnLiveRequest(RequestInfo* info) const {}
+ // Makes |info| hold a reference to |source|. This way |source| will be
+ // kept alive at least as long as |info|.
+ void AddReferenceToSourceDependency(const net::NetLog::Source& source,
+ RequestInfo* info);
private:
typedef base::hash_map<uint32, RequestInfo> SourceIDToInfoMap;
+ typedef std::deque<uint32> DeletionQueue;
// Updates |out_info| with the information from |entry|. Returns an action
// to perform for this map entry on completion.
virtual Action DoAddEntry(const Entry& entry, RequestInfo* out_info) = 0;
- void RemoveFromLiveRequests(uint32 source_id);
- void InsertIntoGraveyard(const RequestInfo& info);
+ // Removes |source_id| from |requests_|. This also releases any references
+ // to dependencies held by this source.
+ void DeleteRequestInfo(uint32 source_id);
+
+ // Adds |source_id| to the FIFO queue (graveyard) for deletion.
+ void AddToDeletionQueue(uint32 source_id);
+
+ // Adds/Releases a reference from the source with ID |source_id|.
+ // Use |offset=-1| to do a release, and |offset=1| for an addref.
+ void AdjustReferenceCountForSource(int offset, uint32 source_id);
+
+ // Releases all the references to sources held by |info|.
+ void ReleaseAllReferencesToDependencies(RequestInfo* info);
+
+ // This map contains all of the requests being tracked by this tracker.
+ // (It includes both the "live" requests, and the "dead" ones.)
+ SourceIDToInfoMap requests_;
- SourceIDToInfoMap live_requests_;
size_t max_graveyard_size_;
- size_t next_graveyard_index_;
- RequestInfoList graveyard_;
+
+ // FIFO queue for entries in |requests_| that are no longer alive, and
+ // can be deleted. This buffer is also called "graveyard" elsewhere. We
+ // queue requests for deletion so they can persist a bit longer.
+ DeletionQueue deletion_queue_;
+
+ PassiveLogCollector* parent_;
DISALLOW_COPY_AND_ASSIGN(RequestTrackerBase);
};
@@ -128,9 +176,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
public:
static const size_t kMaxGraveyardSize;
- ConnectJobTracker();
-
- void AppendLogEntries(RequestInfo* out_info, uint32 connect_id);
+ explicit ConnectJobTracker(PassiveLogCollector* parent);
protected:
virtual Action DoAddEntry(const Entry& entry, RequestInfo* out_info);
@@ -145,14 +191,10 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
SocketTracker();
- void AppendLogEntries(RequestInfo* out_info, uint32 socket_id, bool clear);
-
protected:
virtual Action DoAddEntry(const Entry& entry, RequestInfo* out_info);
private:
- void ClearInfo(RequestInfo* info);
-
DISALLOW_COPY_AND_ASSIGN(SocketTracker);
};
@@ -161,39 +203,27 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
public:
static const size_t kMaxGraveyardSize;
- RequestTracker(ConnectJobTracker* connect_job_tracker,
- SocketTracker* socket_tracker);
-
- void IntegrateSubordinateSource(RequestInfo* info,
- bool clear_entries) const;
+ explicit RequestTracker(PassiveLogCollector* parent);
protected:
virtual Action DoAddEntry(const Entry& entry, RequestInfo* out_info);
- virtual void OnLiveRequest(RequestInfo* info) const {
- IntegrateSubordinateSource(info, false);
- }
-
private:
- ConnectJobTracker* connect_job_tracker_;
- SocketTracker* socket_tracker_;
-
DISALLOW_COPY_AND_ASSIGN(RequestTracker);
};
- // Tracks the log entries for the last seen SOURCE_INIT_PROXY_RESOLVER.
- class InitProxyResolverTracker {
+ // Specialization of RequestTrackerBase for handling
+ // SOURCE_INIT_PROXY_RESOLVER.
+ class InitProxyResolverTracker : public RequestTrackerBase {
public:
- InitProxyResolverTracker();
+ static const size_t kMaxGraveyardSize;
- void OnAddEntry(const Entry& entry);
+ InitProxyResolverTracker();
- const EntryList& entries() const {
- return entries_;
- }
+ protected:
+ virtual Action DoAddEntry(const Entry& entry, RequestInfo* out_info);
private:
- EntryList entries_;
DISALLOW_COPY_AND_ASSIGN(InitProxyResolverTracker);
};
@@ -221,32 +251,20 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
net::NetLog::EventPhase phase,
net::NetLog::EventParameters* params);
+ // Returns the tracker to use for sources of type |source_type|, or NULL.
+ RequestTrackerBase* GetTrackerForSourceType(
+ net::NetLog::SourceType source_type);
+
// Clears all of the passively logged data.
void Clear();
- RequestTracker* url_request_tracker() {
- return &url_request_tracker_;
- }
-
- RequestTracker* socket_stream_tracker() {
- return &socket_stream_tracker_;
- }
-
- InitProxyResolverTracker* init_proxy_resolver_tracker() {
- return &init_proxy_resolver_tracker_;
- }
-
- SpdySessionTracker* spdy_session_tracker() {
- return &spdy_session_tracker_;
- }
-
// Fills |out| with the full list of events that have been passively
// captured. The list is ordered by capture time.
void GetAllCapturedEvents(EntryList* out) const;
private:
- FRIEND_TEST_ALL_PREFIXES(PassiveLogCollectorTest, LostConnectJob);
- FRIEND_TEST_ALL_PREFIXES(PassiveLogCollectorTest, LostSocket);
+ FRIEND_TEST_ALL_PREFIXES(PassiveLogCollectorTest,
+ HoldReferenceToDependentSource);
ConnectJobTracker connect_job_tracker_;
SocketTracker socket_tracker_;
@@ -255,6 +273,11 @@ class PassiveLogCollector : public ChromeNetLog::Observer {
InitProxyResolverTracker init_proxy_resolver_tracker_;
SpdySessionTracker spdy_session_tracker_;
+ // This array maps each NetLog::SourceType to one of the tracker instances
+ // defined above. Use of this array avoid duplicating the list of trackers
+ // elsewhere.
+ RequestTrackerBase* trackers_[net::NetLog::SOURCE_COUNT];
+
// The count of how many events have flowed through this log. Used to set the
// "order" field on captured events.
uint32 num_events_seen_;