1 /* stats.c - statistics from the bus driver
3 * Licensed under the Academic Free License version 2.1
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <dbus/dbus-internals.h>
25 #include <dbus/dbus-connection-internal.h>
27 #include "connection.h"
31 #ifdef DBUS_ENABLE_STATS
34 new_asv_reply (DBusMessage *message,
35 DBusMessageIter *iter,
36 DBusMessageIter *arr_iter)
38 DBusMessage *reply = dbus_message_new_method_return (message);
43 dbus_message_iter_init_append (reply, iter);
45 if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}",
48 dbus_message_unref (reply);
56 open_asv_entry (DBusMessageIter *arr_iter,
57 DBusMessageIter *entry_iter,
60 DBusMessageIter *var_iter)
62 if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY,
66 if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key))
68 dbus_message_iter_abandon_container (arr_iter, entry_iter);
72 if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT,
75 dbus_message_iter_abandon_container (arr_iter, entry_iter);
83 close_asv_entry (DBusMessageIter *arr_iter,
84 DBusMessageIter *entry_iter,
85 DBusMessageIter *var_iter)
87 if (!dbus_message_iter_close_container (entry_iter, var_iter))
89 dbus_message_iter_abandon_container (arr_iter, entry_iter);
93 if (!dbus_message_iter_close_container (arr_iter, entry_iter))
100 close_asv_reply (DBusMessageIter *iter,
101 DBusMessageIter *arr_iter)
103 return dbus_message_iter_close_container (iter, arr_iter);
107 abandon_asv_entry (DBusMessageIter *arr_iter,
108 DBusMessageIter *entry_iter,
109 DBusMessageIter *var_iter)
111 dbus_message_iter_abandon_container (entry_iter, var_iter);
112 dbus_message_iter_abandon_container (arr_iter, entry_iter);
116 abandon_asv_reply (DBusMessageIter *iter,
117 DBusMessageIter *arr_iter)
119 dbus_message_iter_abandon_container (iter, arr_iter);
123 asv_add_uint32 (DBusMessageIter *iter,
124 DBusMessageIter *arr_iter,
128 DBusMessageIter entry_iter, var_iter;
130 if (!open_asv_entry (arr_iter, &entry_iter, key, DBUS_TYPE_UINT32_AS_STRING,
134 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_UINT32,
137 abandon_asv_entry (arr_iter, &entry_iter, &var_iter);
141 if (!close_asv_entry (arr_iter, &entry_iter, &var_iter))
147 abandon_asv_reply (iter, arr_iter);
152 asv_add_string (DBusMessageIter *iter,
153 DBusMessageIter *arr_iter,
157 DBusMessageIter entry_iter, var_iter;
159 if (!open_asv_entry (arr_iter, &entry_iter, key, DBUS_TYPE_STRING_AS_STRING,
163 if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_STRING,
166 abandon_asv_entry (arr_iter, &entry_iter, &var_iter);
170 if (!close_asv_entry (arr_iter, &entry_iter, &var_iter))
176 abandon_asv_reply (iter, arr_iter);
181 bus_stats_handle_get_stats (DBusConnection *connection,
182 BusTransaction *transaction,
183 DBusMessage *message,
186 BusConnections *connections;
187 DBusMessage *reply = NULL;
188 DBusMessageIter iter, arr_iter;
189 static dbus_uint32_t stats_serial = 0;
190 dbus_uint32_t in_use, in_free_list, allocated;
192 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
194 connections = bus_transaction_get_connections (transaction);
196 reply = new_asv_reply (message, &iter, &arr_iter);
203 if (!asv_add_uint32 (&iter, &arr_iter, "Serial", stats_serial++))
206 if (!_dbus_list_get_stats (&in_use, &in_free_list, &allocated) ||
207 !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolUsedBytes", in_use) ||
208 !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolCachedBytes",
210 !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolAllocatedBytes",
216 if (!asv_add_uint32 (&iter, &arr_iter, "ActiveConnections",
217 bus_connections_get_n_active (connections)) ||
218 !asv_add_uint32 (&iter, &arr_iter, "IncompleteConnections",
219 bus_connections_get_n_incomplete (connections)) ||
220 !asv_add_uint32 (&iter, &arr_iter, "MatchRules",
221 bus_connections_get_total_match_rules (connections)) ||
222 !asv_add_uint32 (&iter, &arr_iter, "PeakMatchRules",
223 bus_connections_get_peak_match_rules (connections)) ||
224 !asv_add_uint32 (&iter, &arr_iter, "PeakMatchRulesPerConnection",
225 bus_connections_get_peak_match_rules_per_conn (connections)) ||
226 !asv_add_uint32 (&iter, &arr_iter, "BusNames",
227 bus_connections_get_total_bus_names (connections)) ||
228 !asv_add_uint32 (&iter, &arr_iter, "PeakBusNames",
229 bus_connections_get_peak_bus_names (connections)) ||
230 !asv_add_uint32 (&iter, &arr_iter, "PeakBusNamesPerConnection",
231 bus_connections_get_peak_bus_names_per_conn (connections)))
236 if (!close_asv_reply (&iter, &arr_iter))
239 if (!bus_transaction_send_from_driver (transaction, connection, reply))
242 dbus_message_unref (reply);
247 dbus_message_unref (reply);
254 bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
255 BusTransaction *transaction,
256 DBusMessage *message,
259 const char *bus_name = NULL;
260 DBusString bus_name_str;
261 DBusMessage *reply = NULL;
262 DBusMessageIter iter, arr_iter;
263 static dbus_uint32_t stats_serial = 0;
264 dbus_uint32_t in_messages, in_bytes, in_fds, in_peak_bytes, in_peak_fds;
265 dbus_uint32_t out_messages, out_bytes, out_fds, out_peak_bytes, out_peak_fds;
266 BusRegistry *registry;
268 DBusConnection *stats_connection;
270 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
272 registry = bus_connection_get_registry (caller_connection);
274 if (! dbus_message_get_args (message, error,
275 DBUS_TYPE_STRING, &bus_name,
279 _dbus_string_init_const (&bus_name_str, bus_name);
280 service = bus_registry_lookup (registry, &bus_name_str);
284 dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER,
285 "Bus name '%s' has no owner", bus_name);
289 stats_connection = bus_service_get_primary_owners_connection (service);
290 _dbus_assert (stats_connection != NULL);
292 reply = new_asv_reply (message, &iter, &arr_iter);
297 /* Bus daemon per-connection stats */
299 if (!asv_add_uint32 (&iter, &arr_iter, "Serial", stats_serial++) ||
300 !asv_add_uint32 (&iter, &arr_iter, "MatchRules",
301 bus_connection_get_n_match_rules (stats_connection)) ||
302 !asv_add_uint32 (&iter, &arr_iter, "PeakMatchRules",
303 bus_connection_get_peak_match_rules (stats_connection)) ||
304 !asv_add_uint32 (&iter, &arr_iter, "BusNames",
305 bus_connection_get_n_services_owned (stats_connection)) ||
306 !asv_add_uint32 (&iter, &arr_iter, "PeakBusNames",
307 bus_connection_get_peak_bus_names (stats_connection)) ||
308 !asv_add_string (&iter, &arr_iter, "UniqueName",
309 bus_connection_get_name (stats_connection)))
312 /* DBusConnection per-connection stats */
314 _dbus_connection_get_stats (stats_connection,
315 &in_messages, &in_bytes, &in_fds,
316 &in_peak_bytes, &in_peak_fds,
317 &out_messages, &out_bytes, &out_fds,
318 &out_peak_bytes, &out_peak_fds);
320 if (!asv_add_uint32 (&iter, &arr_iter, "IncomingMessages", in_messages) ||
321 !asv_add_uint32 (&iter, &arr_iter, "IncomingBytes", in_bytes) ||
322 !asv_add_uint32 (&iter, &arr_iter, "IncomingFDs", in_fds) ||
323 !asv_add_uint32 (&iter, &arr_iter, "PeakIncomingBytes", in_peak_bytes) ||
324 !asv_add_uint32 (&iter, &arr_iter, "PeakIncomingFDs", in_peak_fds) ||
325 !asv_add_uint32 (&iter, &arr_iter, "OutgoingMessages", out_messages) ||
326 !asv_add_uint32 (&iter, &arr_iter, "OutgoingBytes", out_bytes) ||
327 !asv_add_uint32 (&iter, &arr_iter, "OutgoingFDs", out_fds) ||
328 !asv_add_uint32 (&iter, &arr_iter, "PeakOutgoingBytes", out_peak_bytes) ||
329 !asv_add_uint32 (&iter, &arr_iter, "PeakOutgoingFDs", out_peak_fds))
334 if (!close_asv_reply (&iter, &arr_iter))
337 if (!bus_transaction_send_from_driver (transaction, caller_connection,
341 dbus_message_unref (reply);
346 dbus_message_unref (reply);