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

Side by Side Diff: dbus/dbus_statistics.cc

Issue 11363173: Add DBusStatistics and DBusLogSource to log and show dbus stats (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "dbus/dbus_statistics.h"
6
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/stl_util.h"
10 #include "base/stringprintf.h"
11
12 namespace dbus {
13
14 namespace {
15
16 // Used to store dbus statistics sorted alphabetically by service, interface,
17 // then method (using std::string <).
18 struct Stat {
19 Stat(const std::string& service,
20 const std::string& interface,
21 const std::string& method)
22 : service(service),
23 interface(interface),
24 method(method),
25 sent_calls(0),
26 received_calls(0),
27 sent_blocking_calls(0) {
28 }
29 std::string service;
30 std::string interface;
31 std::string method;
32 int sent_calls;
33 int received_calls;
34 int sent_blocking_calls;
satorux1 2012/11/13 04:11:06 sent_method_calls, etc. to be more specific? We ca
stevenjb 2012/11/13 19:54:15 Done.
35
36 bool Compare(const Stat& other) const {
37 if (service != other.service)
38 return service < other.service;
39 if (interface != other.interface)
40 return interface < other.interface;
41 return method < other.method;
42 }
43
44 struct PtrCompare {
45 bool operator()(Stat* lhs, Stat* rhs) const {
46 DCHECK(lhs && rhs);
47 return lhs->Compare(*rhs);
48 }
49 };
50 };
51
52 typedef std::set<Stat*, Stat::PtrCompare> StatSet;
53
54 //------------------------------------------------------------------------------
55 // DBusStatistics
56
57 // Simple class for gathering DBus usage statistics.
58 class DBusStatistics {
59 public:
60 DBusStatistics() : start_time_(base::Time::Now()) {
61 }
62
63 ~DBusStatistics() {
64 STLDeleteContainerPointers(stats_.begin(), stats_.end());
65 }
66
67 // Enum to specify which field in Stat to increment in AddStat
68 enum StatType {
69 TYPE_SENT,
70 TYPE_RECEIVED,
71 TYPE_SENT_BLOCKING
satorux1 2012/11/13 04:11:06 likewise, TYPE_SENT_METHOD_CALL, etc. to be more s
stevenjb 2012/11/13 19:54:15 Done.
72 };
73
74 // Add a call to |method| for |interface|. See also MethodCall in message.h.
75 void AddStat(const std::string& service,
76 const std::string& interface,
77 const std::string& method,
78 StatType type) {
79 Stat* stat = GetStat(service, interface, method, true);
hashimoto 2012/11/13 06:11:44 DCHECK(stat)?
stevenjb 2012/11/13 19:54:15 Done.
80 if (type == TYPE_SENT)
81 ++stat->sent_calls;
82 else if (type == TYPE_RECEIVED)
83 ++stat->received_calls;
84 else if (type == TYPE_SENT_BLOCKING)
85 ++stat->sent_blocking_calls;
86 else
87 NOTREACHED();
88 }
89
90 // Look up the Stat entry in |stats_|. If |add_stat| is true, add a new entry
91 // if one does not already exist.
92 Stat* GetStat(const std::string& service,
93 const std::string& interface,
94 const std::string& method,
95 bool add_stat) {
96 scoped_ptr<Stat> stat(new Stat(service, interface, method));
97 StatSet::iterator found = stats_.find(stat.get());
98 if (found != stats_.end())
99 return *found;
100 if (!add_stat)
101 return NULL;
102 found = stats_.insert(stat.release()).first;
103 return *found;
104 }
105
106 StatSet& stats() { return stats_; }
107 base::Time start_time() { return start_time_; }
108
109 private:
110 StatSet stats_;
111 base::Time start_time_;
112
113 DISALLOW_COPY_AND_ASSIGN(DBusStatistics);
114 };
115
116 DBusStatistics* g_dbus_statistics = NULL;
117
118 } // namespace
119
120 //------------------------------------------------------------------------------
121
122 namespace statistics {
123
124 void Initialize() {
125 if (g_dbus_statistics)
126 delete g_dbus_statistics; // reset statistics
127 g_dbus_statistics = new DBusStatistics();
128 }
129
130 void Shutdown() {
131 delete g_dbus_statistics;
132 g_dbus_statistics = NULL;
133 }
134
135 void AddSentMethodCall(const std::string& service,
136 const std::string& interface,
137 const std::string& method) {
138 if (!g_dbus_statistics)
139 return;
140 g_dbus_statistics->AddStat(
141 service, interface, method, DBusStatistics::TYPE_SENT);
142 }
143
144 void AddReceivedSignal(const std::string& service,
145 const std::string& interface,
146 const std::string& method) {
147 if (!g_dbus_statistics)
148 return;
149 g_dbus_statistics->AddStat(
150 service, interface, method, DBusStatistics::TYPE_RECEIVED);
151 }
152
153 void AddBlockingSentMethodCall(const std::string& service,
154 const std::string& interface,
155 const std::string& method) {
156 if (!g_dbus_statistics)
157 return;
158 g_dbus_statistics->AddStat(
159 service, interface, method, DBusStatistics::TYPE_SENT_BLOCKING);
160 }
161
162 std::string GetAsString(ShowInString show, FormatString format) {
163 if (!g_dbus_statistics)
164 return "DBusStatistics not initialized.";
165
166 const StatSet& stats = g_dbus_statistics->stats();
167 if (stats.empty())
168 return "No DBus calls.";
169
170 base::TimeDelta dtime = base::Time::Now() - g_dbus_statistics->start_time();
171 int dminutes = dtime.InMinutes();
172 dminutes = std::max(dminutes, 1);
173
174 std::string result;
175 int sent = 0, received = 0, sent_blocking = 0;
176 // Stats are stored in order by service, then interface, then method.
177 for (StatSet::const_iterator iter = stats.begin(); iter != stats.end(); ) {
178 StatSet::const_iterator cur_iter = iter;
179 StatSet::const_iterator next_iter = ++iter;
180 const Stat* stat = *cur_iter;
181 sent += stat->sent_calls;
182 received += stat->received_calls;
183 sent_blocking += stat->sent_blocking_calls;
184 // If this is not the last stat, and if the next stat matches the current
185 // stat, continue.
186 if (next_iter != stats.end() &&
187 (*next_iter)->service == stat->service &&
188 (show < SHOW_SERVICE || (*next_iter)->interface == stat->interface) &&
189 (show < SHOW_METHOD || (*next_iter)->method == stat->method))
190 continue;
191
192 if (!sent && !received && !sent_blocking)
193 continue; // No stats collected for this line, skip it and continue.
194
195 // Add a line to the result and clear the counts.
196 std::string line;
197 if (show == SHOW_SERVICE) {
198 line += stat->service;
199 } else {
200 // The interface usually includes the service so don't show both.
201 line += stat->interface;
202 if (show >= SHOW_METHOD)
203 line += "." + stat->method;
204 }
205 line += StringPrintf(":");
206 if (sent_blocking) {
207 line += StringPrintf(" Sent (BLOCKING):");
208 if (format == FORMAT_TOTALS)
209 line += StringPrintf(" %d", sent_blocking);
210 else if (format == FORMAT_PER_MINUTE)
211 line += StringPrintf(" %d/min", sent_blocking / dminutes);
212 else if (format == FORMAT_ALL)
213 line += StringPrintf(" %d (%d/min)",
214 sent_blocking, sent_blocking / dminutes);
215 }
216 if (sent) {
217 line += StringPrintf(" Sent:");
218 if (format == FORMAT_TOTALS)
219 line += StringPrintf(" %d", sent);
220 else if (format == FORMAT_PER_MINUTE)
221 line += StringPrintf(" %d/min", sent / dminutes);
222 else if (format == FORMAT_ALL)
223 line += StringPrintf(" %d (%d/min)", sent, sent / dminutes);
224 }
225 if (received) {
226 line += StringPrintf(" Received:");
227 if (format == FORMAT_TOTALS)
228 line += StringPrintf(" %d", received);
229 else if (format == FORMAT_PER_MINUTE)
230 line += StringPrintf(" %d/min", received / dminutes);
231 else if (format == FORMAT_ALL)
232 line += StringPrintf(" %d (%d/min)", received, received / dminutes);
233 }
234 result += line + "\n";
235 sent = 0;
236 sent_blocking = 0;
237 received = 0;
238 }
239 return result;
240 }
241
242 namespace testing {
243
244 bool GetCalls(const std::string& service,
245 const std::string& interface,
246 const std::string& method,
247 int* sent,
248 int* received,
249 int* blocking) {
250 if (!g_dbus_statistics)
251 return false;
252 Stat* stat = g_dbus_statistics->GetStat(service, interface, method, false);
253 if (!stat)
254 return false;
255 *sent = stat->sent_calls;
256 *received = stat->received_calls;
257 *blocking = stat->sent_blocking_calls;
258 return true;
259 }
260
261 } // namespace testing
262
263 } // namespace statistics
264 } // namespace dbus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698