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