• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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_LOAD_LOG_H_
6 #define NET_BASE_LOAD_LOG_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/ref_counted.h"
12 #include "base/time.h"
13 
14 namespace net {
15 
16 // LoadLog stores information associated with an individual request. This
17 // includes event traces (used to build up profiling information), error
18 // return codes from network modules, and arbitrary text messages.
19 //
20 // Note that LoadLog is NOT THREADSAFE, however it is RefCountedThreadSafe so
21 // that it can be AddRef() / Release() across threads.
22 class LoadLog : public base::RefCountedThreadSafe<LoadLog> {
23  public:
24    // TODO(eroman): Really, EventType and EventPhase should be
25    // Event::Type and Event::Phase, to be consisent with Entry.
26    // But there lots of consumers to change!
27   enum EventType {
28 #define EVENT_TYPE(label) TYPE_ ## label,
29 #include "net/base/load_log_event_type_list.h"
30 #undef EVENT_TYPE
31   };
32 
33   // The 'phase' of an event trace (whether it marks the beginning or end
34   // of an event.).
35   enum EventPhase {
36     PHASE_NONE,
37     PHASE_BEGIN,
38     // TODO(eroman): DEPRECATED: Use TYPE_STRING_LITERAL instead.
39     PHASE_END,
40   };
41 
42   struct Event {
EventEvent43     Event(EventType type, EventPhase phase) : type(type), phase(phase) {}
EventEvent44     Event() {}
45 
46     EventType type;
47     EventPhase phase;
48   };
49 
50   struct Entry {
51     enum Type {
52       // This entry describes an event trace.
53       TYPE_EVENT,
54 
55       // This entry describes a network error code that was returned.
56       TYPE_ERROR_CODE,
57 
58       // This entry is a free-form std::string.
59       TYPE_STRING,
60 
61       // This entry is a C-string literal.
62       TYPE_STRING_LITERAL,
63     };
64 
EntryEntry65     Entry(base::TimeTicks time, int error_code)
66         : type(TYPE_ERROR_CODE), time(time), error_code(error_code) {
67     }
68 
EntryEntry69     Entry(base::TimeTicks time, const Event& event)
70         : type(TYPE_EVENT), time(time), event(event) {
71     }
72 
EntryEntry73     Entry(base::TimeTicks time, const std::string& string)
74         : type(TYPE_STRING), time(time), string(string) {
75     }
76 
EntryEntry77     Entry(base::TimeTicks time, const char* literal)
78         : type(TYPE_STRING_LITERAL), time(time), literal(literal) {
79     }
80 
81     Type type;
82     base::TimeTicks time;
83 
84     // The following is basically a union, only one of them should be
85     // used depending on what |type| is.
86     Event event;          // valid when (type == TYPE_EVENT).
87     int error_code;       // valid when (type == TYPE_ERROR_CODE).
88     std::string string;   // valid when (type == TYPE_STRING).
89     const char* literal;  // valid when (type == TYPE_STRING_LITERAL).
90   };
91 
92   // Ordered set of entries that were logged.
93   // TODO(eroman): use a StackVector or array to avoid allocations.
94   typedef std::vector<Entry> EntryList;
95 
96   // Value for max_num_entries to indicate the LoadLog has no size limit.
97   static const size_t kUnbounded = static_cast<size_t>(-1);
98 
99   // Creates a log, which can hold up to |max_num_entries| entries.
100   // If |max_num_entries| is |kUnbounded|, then the log can grow arbitrarily
101   // large.
102   //
103   // If entries are dropped because the log has grown too large, the final entry
104   // will be overwritten.
105   explicit LoadLog(size_t max_num_entries);
106 
107   // --------------------------------------------------------------------------
108 
109   // The public interface for adding events to the log are static methods.
110   // This makes it easier to deal with optionally NULL LoadLog.
111 
112   // Adds an instantaneous event to the log.
113   // TODO(eroman): DEPRECATED: use AddStringLiteral() instead.
AddEvent(LoadLog * log,EventType event_type)114   static void AddEvent(LoadLog* log, EventType event_type) {
115     if (log)
116       log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_NONE)));
117   }
118 
119   // Adds the start of an event to the log. Presumably this event type measures
120   // a time duration, and will be matched by a call to EndEvent(event_type).
BeginEvent(LoadLog * log,EventType event_type)121   static void BeginEvent(LoadLog* log, EventType event_type) {
122     if (log)
123       log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_BEGIN)));
124   }
125 
126   // Adds the end of an event to the log. Presumably this event type measures
127   // a time duration, and we are matching an earlier call to
128   // BeginEvent(event_type).
EndEvent(LoadLog * log,EventType event_type)129   static void EndEvent(LoadLog* log, EventType event_type) {
130     if (log)
131       log->Add(Entry(base::TimeTicks::Now(), Event(event_type, PHASE_END)));
132   }
133 
134   // |literal| should be a string literal (i.e. lives in static storage).
AddStringLiteral(LoadLog * log,const char * literal)135   static void AddStringLiteral(LoadLog* log, const char* literal) {
136     if (log)
137       log->Add(Entry(base::TimeTicks::Now(), literal));
138   }
139 
AddString(LoadLog * log,const std::string & string)140   static void AddString(LoadLog* log, const std::string& string) {
141     if (log)
142       log->Add(Entry(base::TimeTicks::Now(), string));
143   }
144 
AddErrorCode(LoadLog * log,int error)145   static void AddErrorCode(LoadLog* log, int error) {
146     if (log)
147       log->Add(Entry(base::TimeTicks::Now(), error));
148   }
149 
IsUnbounded(const LoadLog * log)150   static bool IsUnbounded(const LoadLog* log) {
151     return log && log->is_unbounded();
152   }
153 
154   // --------------------------------------------------------------------------
155 
156   // Returns the list of all entries in the log.
entries()157   const EntryList& entries() const {
158     return entries_;
159   }
160 
161   // Returns the number of entries that were dropped from the log because the
162   // maximum size had been reached.
num_entries_truncated()163   size_t num_entries_truncated() const {
164     return num_entries_truncated_;
165   }
166 
167   // Returns the bound on the size of the log.
max_num_entries()168   size_t max_num_entries() const {
169     return max_num_entries_;
170   }
171 
is_unbounded()172   bool is_unbounded() const {
173     return max_num_entries_ == kUnbounded;
174   }
175 
176   // Returns a C-String symbolic name for |event|.
177   static const char* EventTypeToString(EventType event_type);
178 
179   void Add(const Entry& entry);
180 
181   // Copies all entries from |log|, appending it to the end of |this|.
182   void Append(const LoadLog* log);
183 
184  private:
185   friend class base::RefCountedThreadSafe<LoadLog>;
186 
~LoadLog()187   ~LoadLog() {}
188 
189   EntryList entries_;
190   size_t num_entries_truncated_;
191   size_t max_num_entries_;;
192 };
193 
194 }  // namespace net
195 
196 #endif  // NET_BASE_LOAD_LOG_H_
197