Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: net/base/net_log_util.cc

Issue 2008007: Replace about:net-internals with the javascript-based frontend.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: improve a comment Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/net_log_util.h ('k') | net/base/net_log_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "net/base/net_log_util.h"
6
7 #include "base/format_macros.h"
8 #include "base/json/json_writer.h"
9 #include "base/string_util.h"
10 #include "base/values.h"
11 #include "net/base/net_errors.h"
12
13 namespace net {
14 namespace {
15
16 class FormatHelper {
17 public:
18 std::string ToString(const std::vector<CapturingNetLog::Entry>& entries,
19 size_t num_entries_truncated) {
20 entries_.clear();
21
22 // Pass 1: Match the start/end of indentation blocks. Fills |entries_|
23 // with the results.
24 PopulateEntries(entries);
25
26 // Pass 2: Figure out the maximum width of each column. This allows us
27 // to right-justify text within each column.
28 size_t max_time_width, max_indentation, max_type_width, max_dt_width;
29 GetMaxExtent(
30 &max_time_width, &max_indentation, &max_type_width, &max_dt_width);
31
32 // Pass 3: Assemble the string.
33 std::string result;
34
35 const int kSpacesPerIndentation = 2;
36
37 for (size_t i = 0; i < entries_.size(); ++i) {
38 if (num_entries_truncated > 0 && i + 1 == entries_.size()) {
39 StringAppendF(&result, " ... Truncated %" PRIuS " entries ...\n",
40 num_entries_truncated);
41 }
42
43 if (entries_[i].block_index != -1 &&
44 static_cast<size_t>(entries_[i].block_index + 1) == i) {
45 // If there were no entries in between the START/END block then don't
46 // bother printing a line for END (it just adds noise, and we already
47 // show the time delta besides START anyway).
48 continue;
49 }
50
51 int indentation_spaces = entries_[i].indentation * kSpacesPerIndentation;
52 std::string entry_str = GetEntryString(i);
53
54 StringAppendF(&result, "t=%s: %s%s",
55 PadStringLeft(GetTimeString(i), max_time_width).c_str(),
56 PadStringLeft("", indentation_spaces).c_str(),
57 entry_str.c_str());
58
59 if (entries_[i].IsBeginEvent()) {
60 // Summarize how long this block lasted.
61 int padding = ((max_indentation - entries_[i].indentation) *
62 kSpacesPerIndentation) + (max_type_width - entry_str.size());
63 StringAppendF(&result, "%s [dt=%s]",
64 PadStringLeft("", padding).c_str(),
65 PadStringLeft(GetBlockDtString(i), max_dt_width).c_str());
66 }
67
68 // Append any custom parameters.
69 NetLog::EventParameters* extra_params =
70 entries_[i].log_entry->extra_parameters;
71
72 if (extra_params) {
73 std::string extra_details;
74 scoped_ptr<Value> extra_details_value(extra_params->ToValue());
75 base::JSONWriter::Write(extra_details_value.get(), true,
76 &extra_details);
77 // JSON writer uses CR LF in its pretty-printer. Normalize to newlines.
78 ReplaceSubstringsAfterOffset(&extra_details, 0, "\r\n", "\n");
79 result.append("\n");
80 result.append(extra_details);
81 }
82
83 if (!extra_params && i + 1 != entries_.size())
84 result += "\n";
85 }
86
87 return result;
88 }
89
90 private:
91 struct Entry {
92 explicit Entry(const CapturingNetLog::Entry* log_entry)
93 : log_entry(log_entry), indentation(0), block_index(-1) {}
94
95 bool IsBeginEvent() const {
96 return log_entry->phase == NetLog::PHASE_BEGIN;
97 }
98
99 bool IsEndEvent() const {
100 return log_entry->phase == NetLog::PHASE_END;
101 }
102
103 const CapturingNetLog::Entry* log_entry;
104 size_t indentation;
105 int block_index; // The index of the matching start / end of block.
106 };
107
108 void PopulateEntries(const std::vector<CapturingNetLog::Entry>& entries) {
109 int current_indentation = 0;
110
111 for (size_t i = 0; i < entries.size(); ++i) {
112 Entry entry(&entries[i]);
113
114 entry.indentation = current_indentation;
115
116 if (entry.IsBeginEvent()) {
117 // Indent everything contained in this block.
118 current_indentation++;
119 }
120
121 if (entry.IsEndEvent()) {
122 int start_index = FindStartOfBlockIndex(entry);
123 if (start_index != -1) {
124 // Point the start / end of block at each other.
125 entry.block_index = start_index;
126 entries_[start_index].block_index = i;
127
128 // Restore the indentation prior to the block.
129 // (Could be more than 1 level if close of blocks are missing).
130 current_indentation = entries_[start_index].indentation;
131 entry.indentation = current_indentation;
132 }
133 }
134
135 entries_.push_back(entry);
136 }
137 }
138
139 int FindStartOfBlockIndex(const Entry& entry) {
140 DCHECK(entry.IsEndEvent());
141
142 // Find the matching start of block by scanning backwards.
143 for (int i = entries_.size() - 1; i >= 0; --i) {
144 if (entries_[i].IsBeginEvent() &&
145 entries_[i].log_entry->type == entry.log_entry->type) {
146 return i;
147 }
148 }
149 return -1; // Start not found.
150 }
151
152 void GetMaxExtent(size_t* max_time_width,
153 size_t* max_indentation,
154 size_t* max_type_width,
155 size_t* max_dt_width) {
156 *max_time_width = *max_indentation = *max_type_width = *max_dt_width = 0;
157 for (size_t i = 0; i < entries_.size(); ++i) {
158 *max_time_width = std::max(*max_time_width, GetTimeString(i).size());
159 if (entries_[i].log_entry->phase != NetLog::PHASE_NONE)
160 *max_type_width = std::max(*max_type_width, GetEntryString(i).size());
161 *max_indentation = std::max(*max_indentation, entries_[i].indentation);
162
163 if (entries_[i].IsBeginEvent())
164 *max_dt_width = std::max(*max_dt_width, GetBlockDtString(i).size());
165 }
166 }
167
168 std::string GetBlockDtString(size_t start_index) {
169 int end_index = entries_[start_index].block_index;
170 if (end_index == -1) {
171 // Block is not closed, implicitly close it at EOF.
172 end_index = entries_.size() - 1;
173 }
174 int64 dt_ms = (entries_[end_index].log_entry->time -
175 entries_[start_index].log_entry->time).InMilliseconds();
176
177 return Int64ToString(dt_ms);
178 }
179
180 std::string GetTimeString(size_t index) {
181 int64 t_ms = (entries_[index].log_entry->time -
182 base::TimeTicks()).InMilliseconds();
183 return Int64ToString(t_ms);
184 }
185
186 std::string GetEntryString(size_t index) {
187 const CapturingNetLog::Entry* entry = entries_[index].log_entry;
188
189 std::string entry_str;
190 NetLog::EventPhase phase = entry->phase;
191
192 entry_str = NetLog::EventTypeToString(entry->type);
193
194 if (phase == NetLog::PHASE_BEGIN &&
195 index + 1 < entries_.size() &&
196 static_cast<size_t>(entries_[index + 1].block_index) == index) {
197 // If this starts an empty block, we will pretend it is a PHASE_NONE
198 // so we don't print the "+" prefix.
199 phase = NetLog::PHASE_NONE;
200 }
201
202 switch (phase) {
203 case NetLog::PHASE_BEGIN:
204 return std::string("+") + entry_str;
205 case NetLog::PHASE_END:
206 return std::string("-") + entry_str;
207 case NetLog::PHASE_NONE:
208 return std::string(" ") + entry_str;
209 default:
210 NOTREACHED();
211 return std::string();
212 }
213 }
214
215 static std::string PadStringLeft(const std::string& str, size_t width) {
216 DCHECK_LE(str.size(), width);
217 std::string padding;
218 padding.resize(width - str.size(), ' ');
219 return padding + str;
220 }
221
222 std::vector<Entry> entries_;
223 };
224
225 } // namespace
226
227 // static
228 std::string NetLogUtil::PrettyPrintAsEventTree(
229 const std::vector<CapturingNetLog::Entry>& entries,
230 size_t num_entries_truncated) {
231 FormatHelper helper;
232 return helper.ToString(entries, num_entries_truncated);
233 }
234
235 } // namespace net
OLDNEW
« no previous file with comments | « net/base/net_log_util.h ('k') | net/base/net_log_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698