| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/net_log_util.h" | 5 #include "net/base/net_log_util.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 | 10 |
| 11 namespace net { | 11 namespace net { |
| 12 namespace { | 12 namespace { |
| 13 | 13 |
| 14 class FormatHelper { | 14 class FormatHelper { |
| 15 public: | 15 public: |
| 16 std::string ToString(const std::vector<NetLog::Entry>& entries, | 16 std::string ToString(const std::vector<CapturingNetLog::Entry>& entries, |
| 17 size_t num_entries_truncated) { | 17 size_t num_entries_truncated) { |
| 18 entries_.clear(); | 18 entries_.clear(); |
| 19 | 19 |
| 20 // Pass 1: Match the start/end of indentation blocks. Fills |entries_| | 20 // Pass 1: Match the start/end of indentation blocks. Fills |entries_| |
| 21 // with the results. | 21 // with the results. |
| 22 PopulateEntries(entries); | 22 PopulateEntries(entries); |
| 23 | 23 |
| 24 // Pass 2: Figure out the maximum width of each column. This allows us | 24 // Pass 2: Figure out the maximum width of each column. This allows us |
| 25 // to right-justify text within each column. | 25 // to right-justify text within each column. |
| 26 size_t max_time_width, max_indentation, max_type_width, max_dt_width; | 26 size_t max_time_width, max_indentation, max_type_width, max_dt_width; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 42 static_cast<size_t>(entries_[i].block_index + 1) == i) { | 42 static_cast<size_t>(entries_[i].block_index + 1) == i) { |
| 43 // If there were no entries in between the START/END block then don't | 43 // If there were no entries in between the START/END block then don't |
| 44 // bother printing a line for END (it just adds noise, and we already | 44 // bother printing a line for END (it just adds noise, and we already |
| 45 // show the time delta besides START anyway). | 45 // show the time delta besides START anyway). |
| 46 continue; | 46 continue; |
| 47 } | 47 } |
| 48 | 48 |
| 49 int indentation_spaces = entries_[i].indentation * kSpacesPerIndentation; | 49 int indentation_spaces = entries_[i].indentation * kSpacesPerIndentation; |
| 50 std::string entry_str = GetEntryString(i); | 50 std::string entry_str = GetEntryString(i); |
| 51 | 51 |
| 52 // Hack to better print known event types. |
| 53 if (entries_[i].log_entry->type == NetLog::TYPE_TODO_STRING || |
| 54 entries_[i].log_entry->type == NetLog::TYPE_TODO_STRING_LITERAL) { |
| 55 // Don't display the TODO_STRING type. |
| 56 entry_str = StringPrintf( |
| 57 " \"%s\"", |
| 58 entries_[i].log_entry->extra_parameters->ToString().c_str()); |
| 59 } |
| 60 |
| 52 StringAppendF(&result, "t=%s: %s%s", | 61 StringAppendF(&result, "t=%s: %s%s", |
| 53 PadStringLeft(GetTimeString(i), max_time_width).c_str(), | 62 PadStringLeft(GetTimeString(i), max_time_width).c_str(), |
| 54 PadStringLeft("", indentation_spaces).c_str(), | 63 PadStringLeft("", indentation_spaces).c_str(), |
| 55 entry_str.c_str()); | 64 entry_str.c_str()); |
| 56 | 65 |
| 57 if (entries_[i].IsBeginEvent()) { | 66 if (entries_[i].IsBeginEvent()) { |
| 58 // Summarize how long this block lasted. | 67 // Summarize how long this block lasted. |
| 59 int padding = ((max_indentation - entries_[i].indentation) * | 68 int padding = ((max_indentation - entries_[i].indentation) * |
| 60 kSpacesPerIndentation) + (max_type_width - entry_str.size()); | 69 kSpacesPerIndentation) + (max_type_width - entry_str.size()); |
| 61 StringAppendF(&result, "%s [dt=%s]", | 70 StringAppendF(&result, "%s [dt=%s]", |
| 62 PadStringLeft("", padding).c_str(), | 71 PadStringLeft("", padding).c_str(), |
| 63 PadStringLeft(GetBlockDtString(i), max_dt_width).c_str()); | 72 PadStringLeft(GetBlockDtString(i), max_dt_width).c_str()); |
| 64 } | 73 } |
| 65 | 74 |
| 75 // Append any custom parameters. |
| 76 NetLog::EventParameters* extra_params = |
| 77 entries_[i].log_entry->extra_parameters; |
| 78 NetLog::EventType type = entries_[i].log_entry->type; |
| 79 NetLog::EventPhase phase = entries_[i].log_entry->phase; |
| 80 |
| 81 if (type != NetLog::TYPE_TODO_STRING && extra_params) { |
| 82 std::string extra_details; |
| 83 |
| 84 // Hacks to better print known event types. |
| 85 if (type == NetLog::TYPE_URL_REQUEST_START || |
| 86 type == NetLog::TYPE_SOCKET_STREAM_CONNECT) { |
| 87 if (phase == NetLog::PHASE_BEGIN) { |
| 88 extra_details = |
| 89 StringPrintf("url: %s", extra_params->ToString().c_str()); |
| 90 } else if (phase == NetLog::PHASE_END) { |
| 91 int error_code = static_cast<NetLogIntegerParameter*>( |
| 92 extra_params)->value(); |
| 93 extra_details = StringPrintf("net error: %d (%s)", |
| 94 error_code, |
| 95 ErrorToString(error_code)); |
| 96 } |
| 97 } else if (type == NetLog::TYPE_SOCKET_POOL_CONNECT_JOB) { |
| 98 extra_details = |
| 99 StringPrintf("group: %s", extra_params->ToString().c_str()); |
| 100 } else { |
| 101 extra_details = extra_params->ToString(); |
| 102 } |
| 103 |
| 104 int indentation = max_time_width + indentation_spaces + |
| 105 kSpacesPerIndentation + 5; |
| 106 |
| 107 StringAppendF( |
| 108 &result, |
| 109 "\n%s%s", |
| 110 PadStringLeft("", indentation).c_str(), |
| 111 extra_details.c_str()); |
| 112 } |
| 113 |
| 66 if (i + 1 != entries_.size()) | 114 if (i + 1 != entries_.size()) |
| 67 result += "\n"; | 115 result += "\n"; |
| 68 } | 116 } |
| 69 | 117 |
| 70 return result; | 118 return result; |
| 71 } | 119 } |
| 72 | 120 |
| 73 private: | 121 private: |
| 74 struct Entry { | 122 struct Entry { |
| 75 explicit Entry(const NetLog::Entry* log_entry) | 123 explicit Entry(const CapturingNetLog::Entry* log_entry) |
| 76 : log_entry(log_entry), indentation(0), block_index(-1) {} | 124 : log_entry(log_entry), indentation(0), block_index(-1) {} |
| 77 | 125 |
| 78 bool IsBeginEvent() const { | 126 bool IsBeginEvent() const { |
| 79 return log_entry->type == NetLog::Entry::TYPE_EVENT && | 127 return log_entry->phase == NetLog::PHASE_BEGIN; |
| 80 log_entry->event.phase == NetLog::PHASE_BEGIN; | |
| 81 } | 128 } |
| 82 | 129 |
| 83 bool IsEndEvent() const { | 130 bool IsEndEvent() const { |
| 84 return log_entry->type == NetLog::Entry::TYPE_EVENT && | 131 return log_entry->phase == NetLog::PHASE_END; |
| 85 log_entry->event.phase == NetLog::PHASE_END; | |
| 86 } | 132 } |
| 87 | 133 |
| 88 const NetLog::Entry* log_entry; | 134 const CapturingNetLog::Entry* log_entry; |
| 89 size_t indentation; | 135 size_t indentation; |
| 90 int block_index; // The index of the matching start / end of block. | 136 int block_index; // The index of the matching start / end of block. |
| 91 }; | 137 }; |
| 92 | 138 |
| 93 void PopulateEntries(const std::vector<NetLog::Entry>& entries) { | 139 void PopulateEntries(const std::vector<CapturingNetLog::Entry>& entries) { |
| 94 int current_indentation = 0; | 140 int current_indentation = 0; |
| 95 | 141 |
| 96 for (size_t i = 0; i < entries.size(); ++i) { | 142 for (size_t i = 0; i < entries.size(); ++i) { |
| 97 Entry entry(&entries[i]); | 143 Entry entry(&entries[i]); |
| 98 | 144 |
| 99 entry.indentation = current_indentation; | 145 entry.indentation = current_indentation; |
| 100 | 146 |
| 101 if (entry.IsBeginEvent()) { | 147 if (entry.IsBeginEvent()) { |
| 102 // Indent everything contained in this block. | 148 // Indent everything contained in this block. |
| 103 current_indentation++; | 149 current_indentation++; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 120 entries_.push_back(entry); | 166 entries_.push_back(entry); |
| 121 } | 167 } |
| 122 } | 168 } |
| 123 | 169 |
| 124 int FindStartOfBlockIndex(const Entry& entry) { | 170 int FindStartOfBlockIndex(const Entry& entry) { |
| 125 DCHECK(entry.IsEndEvent()); | 171 DCHECK(entry.IsEndEvent()); |
| 126 | 172 |
| 127 // Find the matching start of block by scanning backwards. | 173 // Find the matching start of block by scanning backwards. |
| 128 for (int i = entries_.size() - 1; i >= 0; --i) { | 174 for (int i = entries_.size() - 1; i >= 0; --i) { |
| 129 if (entries_[i].IsBeginEvent() && | 175 if (entries_[i].IsBeginEvent() && |
| 130 entries_[i].log_entry->event.type == entry.log_entry->event.type) { | 176 entries_[i].log_entry->type == entry.log_entry->type) { |
| 131 return i; | 177 return i; |
| 132 } | 178 } |
| 133 } | 179 } |
| 134 return -1; // Start not found. | 180 return -1; // Start not found. |
| 135 } | 181 } |
| 136 | 182 |
| 137 void GetMaxExtent(size_t* max_time_width, | 183 void GetMaxExtent(size_t* max_time_width, |
| 138 size_t* max_indentation, | 184 size_t* max_indentation, |
| 139 size_t* max_type_width, | 185 size_t* max_type_width, |
| 140 size_t* max_dt_width) { | 186 size_t* max_dt_width) { |
| 141 *max_time_width = *max_indentation = *max_type_width = *max_dt_width = 0; | 187 *max_time_width = *max_indentation = *max_type_width = *max_dt_width = 0; |
| 142 for (size_t i = 0; i < entries_.size(); ++i) { | 188 for (size_t i = 0; i < entries_.size(); ++i) { |
| 143 *max_time_width = std::max(*max_time_width, GetTimeString(i).size()); | 189 *max_time_width = std::max(*max_time_width, GetTimeString(i).size()); |
| 144 if (entries_[i].log_entry->type == NetLog::Entry::TYPE_EVENT) | 190 if (entries_[i].log_entry->phase != NetLog::PHASE_NONE) |
| 145 *max_type_width = std::max(*max_type_width, GetEntryString(i).size()); | 191 *max_type_width = std::max(*max_type_width, GetEntryString(i).size()); |
| 146 *max_indentation = std::max(*max_indentation, entries_[i].indentation); | 192 *max_indentation = std::max(*max_indentation, entries_[i].indentation); |
| 147 | 193 |
| 148 if (entries_[i].IsBeginEvent()) | 194 if (entries_[i].IsBeginEvent()) |
| 149 *max_dt_width = std::max(*max_dt_width, GetBlockDtString(i).size()); | 195 *max_dt_width = std::max(*max_dt_width, GetBlockDtString(i).size()); |
| 150 } | 196 } |
| 151 } | 197 } |
| 152 | 198 |
| 153 std::string GetBlockDtString(size_t start_index) { | 199 std::string GetBlockDtString(size_t start_index) { |
| 154 int end_index = entries_[start_index].block_index; | 200 int end_index = entries_[start_index].block_index; |
| 155 if (end_index == -1) { | 201 if (end_index == -1) { |
| 156 // Block is not closed, implicitly close it at EOF. | 202 // Block is not closed, implicitly close it at EOF. |
| 157 end_index = entries_.size() - 1; | 203 end_index = entries_.size() - 1; |
| 158 } | 204 } |
| 159 int64 dt_ms = (entries_[end_index].log_entry->time - | 205 int64 dt_ms = (entries_[end_index].log_entry->time - |
| 160 entries_[start_index].log_entry->time).InMilliseconds(); | 206 entries_[start_index].log_entry->time).InMilliseconds(); |
| 161 | 207 |
| 162 return Int64ToString(dt_ms); | 208 return Int64ToString(dt_ms); |
| 163 } | 209 } |
| 164 | 210 |
| 165 std::string GetTimeString(size_t index) { | 211 std::string GetTimeString(size_t index) { |
| 166 int64 t_ms = (entries_[index].log_entry->time - | 212 int64 t_ms = (entries_[index].log_entry->time - |
| 167 base::TimeTicks()).InMilliseconds(); | 213 base::TimeTicks()).InMilliseconds(); |
| 168 return Int64ToString(t_ms); | 214 return Int64ToString(t_ms); |
| 169 } | 215 } |
| 170 | 216 |
| 171 std::string GetEntryString(size_t index) { | 217 std::string GetEntryString(size_t index) { |
| 172 const NetLog::Entry* entry = entries_[index].log_entry; | 218 const CapturingNetLog::Entry* entry = entries_[index].log_entry; |
| 173 | 219 |
| 174 std::string entry_str; | 220 std::string entry_str; |
| 175 NetLog::EventPhase phase = NetLog::PHASE_NONE; | 221 NetLog::EventPhase phase = entry->phase; |
| 176 switch (entry->type) { | |
| 177 case NetLog::Entry::TYPE_EVENT: | |
| 178 entry_str = NetLog::EventTypeToString(entry->event.type); | |
| 179 phase = entry->event.phase; | |
| 180 | 222 |
| 181 if (phase == NetLog::PHASE_BEGIN && | 223 entry_str = NetLog::EventTypeToString(entry->type); |
| 182 index + 1 < entries_.size() && | 224 |
| 183 static_cast<size_t>(entries_[index + 1].block_index) == index) { | 225 if (phase == NetLog::PHASE_BEGIN && |
| 184 // If this starts an empty block, we will pretend it is a PHASE_NONE | 226 index + 1 < entries_.size() && |
| 185 // so we don't print the "+" prefix. | 227 static_cast<size_t>(entries_[index + 1].block_index) == index) { |
| 186 phase = NetLog::PHASE_NONE; | 228 // If this starts an empty block, we will pretend it is a PHASE_NONE |
| 187 } | 229 // so we don't print the "+" prefix. |
| 188 break; | 230 phase = NetLog::PHASE_NONE; |
| 189 case NetLog::Entry::TYPE_ERROR_CODE: | |
| 190 entry_str = StringPrintf("error code: %d (%s)", | |
| 191 entry->error_code, | |
| 192 ErrorToString(entry->error_code)); | |
| 193 break; | |
| 194 case NetLog::Entry::TYPE_STRING: | |
| 195 entry_str = StringPrintf("\"%s\"", entry->string.c_str()); | |
| 196 break; | |
| 197 case NetLog::Entry::TYPE_STRING_LITERAL: | |
| 198 entry_str = StringPrintf("\"%s\"", entry->literal); | |
| 199 break; | |
| 200 default: | |
| 201 NOTREACHED(); | |
| 202 } | 231 } |
| 203 | 232 |
| 204 switch (phase) { | 233 switch (phase) { |
| 205 case NetLog::PHASE_BEGIN: | 234 case NetLog::PHASE_BEGIN: |
| 206 return std::string("+") + entry_str; | 235 return std::string("+") + entry_str; |
| 207 case NetLog::PHASE_END: | 236 case NetLog::PHASE_END: |
| 208 return std::string("-") + entry_str; | 237 return std::string("-") + entry_str; |
| 209 case NetLog::PHASE_NONE: | 238 case NetLog::PHASE_NONE: |
| 210 return std::string(" ") + entry_str; | 239 return std::string(" ") + entry_str; |
| 211 default: | 240 default: |
| 212 NOTREACHED(); | 241 NOTREACHED(); |
| 213 return std::string(); | 242 return std::string(); |
| 214 } | 243 } |
| 215 } | 244 } |
| 216 | 245 |
| 217 static std::string PadStringLeft(const std::string& str, size_t width) { | 246 static std::string PadStringLeft(const std::string& str, size_t width) { |
| 218 DCHECK_LE(str.size(), width); | 247 DCHECK_LE(str.size(), width); |
| 219 std::string padding; | 248 std::string padding; |
| 220 padding.resize(width - str.size(), ' '); | 249 padding.resize(width - str.size(), ' '); |
| 221 return padding + str; | 250 return padding + str; |
| 222 } | 251 } |
| 223 | 252 |
| 224 std::vector<Entry> entries_; | 253 std::vector<Entry> entries_; |
| 225 }; | 254 }; |
| 226 | 255 |
| 227 } // namespace | 256 } // namespace |
| 228 | 257 |
| 229 // static | 258 // static |
| 230 std::string NetLogUtil::PrettyPrintAsEventTree( | 259 std::string NetLogUtil::PrettyPrintAsEventTree( |
| 231 const std::vector<NetLog::Entry>& entries, | 260 const std::vector<CapturingNetLog::Entry>& entries, |
| 232 size_t num_entries_truncated) { | 261 size_t num_entries_truncated) { |
| 233 FormatHelper helper; | 262 FormatHelper helper; |
| 234 return helper.ToString(entries, num_entries_truncated); | 263 return helper.ToString(entries, num_entries_truncated); |
| 235 } | 264 } |
| 236 | 265 |
| 237 } // namespace net | 266 } // namespace net |
| OLD | NEW |