1 /* stats.c - statistics from the bus driver
3 * Copyright © 2011-2012 Nokia Corporation
4 * Copyright © 2012-2013 Collabora Ltd.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 #include <dbus/dbus-asv-util.h>
28 #include <dbus/dbus-internals.h>
29 #include <dbus/dbus-connection-internal.h>
31 #include "connection.h"
37 #ifdef DBUS_ENABLE_STATS
40 bus_stats_handle_get_stats (DBusConnection *connection,
41 BusTransaction *transaction,
46 BusConnections *connections;
47 DBusMessage *reply = NULL;
48 DBusMessageIter iter, arr_iter;
49 static dbus_uint32_t stats_serial = 0;
50 dbus_uint32_t in_use, in_free_list, allocated;
52 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
54 context = bus_transaction_get_context (transaction);
55 connections = bus_context_get_connections (context);
57 reply = _dbus_asv_new_method_return (message, &iter, &arr_iter);
64 _dbus_list_get_stats (&in_use, &in_free_list, &allocated);
66 if (!_dbus_asv_add_uint32 (&arr_iter, "Serial", stats_serial++) ||
67 !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolUsedBytes", in_use) ||
68 !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolCachedBytes", in_free_list) ||
69 !_dbus_asv_add_uint32 (&arr_iter, "ListMemPoolAllocatedBytes", allocated))
71 _dbus_asv_abandon (&iter, &arr_iter);
77 if (!_dbus_asv_add_uint32 (&arr_iter, "ActiveConnections",
78 bus_connections_get_n_active (connections)) ||
79 !_dbus_asv_add_uint32 (&arr_iter, "IncompleteConnections",
80 bus_connections_get_n_incomplete (connections)) ||
81 !_dbus_asv_add_uint32 (&arr_iter, "MatchRules",
82 bus_connections_get_total_match_rules (connections)) ||
83 !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRules",
84 bus_connections_get_peak_match_rules (connections)) ||
85 !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRulesPerConnection",
86 bus_connections_get_peak_match_rules_per_conn (connections)) ||
87 !_dbus_asv_add_uint32 (&arr_iter, "BusNames",
88 bus_connections_get_total_bus_names (connections)) ||
89 !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNames",
90 bus_connections_get_peak_bus_names (connections)) ||
91 !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNamesPerConnection",
92 bus_connections_get_peak_bus_names_per_conn (connections)))
94 _dbus_asv_abandon (&iter, &arr_iter);
100 if (!_dbus_asv_close (&iter, &arr_iter))
103 if (!bus_transaction_send_from_driver (transaction, connection, reply))
106 dbus_message_unref (reply);
107 return BUS_RESULT_TRUE;
111 dbus_message_unref (reply);
114 return BUS_RESULT_FALSE;
118 bus_stats_handle_get_connection_stats (DBusConnection *caller_connection,
119 BusTransaction *transaction,
120 DBusMessage *message,
123 BusDriverFound found;
124 DBusMessage *reply = NULL;
125 DBusMessageIter iter, arr_iter;
126 static dbus_uint32_t stats_serial = 0;
127 dbus_uint32_t in_messages, in_bytes, in_fds, in_peak_bytes, in_peak_fds;
128 dbus_uint32_t out_messages, out_bytes, out_fds, out_peak_bytes, out_peak_fds;
129 DBusConnection *stats_connection;
131 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
133 found = bus_driver_get_conn_helper (caller_connection, message,
134 "statistics", NULL, &stats_connection,
139 case BUS_DRIVER_FOUND_SELF:
140 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
141 "GetConnectionStats is not meaningful for the "
142 "message bus \"%s\" itself", DBUS_SERVICE_DBUS);
145 case BUS_DRIVER_FOUND_PEER:
148 case BUS_DRIVER_FOUND_ERROR:
154 _dbus_assert (stats_connection != NULL);
156 reply = _dbus_asv_new_method_return (message, &iter, &arr_iter);
161 /* Bus daemon per-connection stats */
163 if (!_dbus_asv_add_uint32 (&arr_iter, "Serial", stats_serial++) ||
164 !_dbus_asv_add_uint32 (&arr_iter, "MatchRules",
165 bus_connection_get_n_match_rules (stats_connection)) ||
166 !_dbus_asv_add_uint32 (&arr_iter, "PeakMatchRules",
167 bus_connection_get_peak_match_rules (stats_connection)) ||
168 !_dbus_asv_add_uint32 (&arr_iter, "BusNames",
169 bus_connection_get_n_services_owned (stats_connection)) ||
170 !_dbus_asv_add_uint32 (&arr_iter, "PeakBusNames",
171 bus_connection_get_peak_bus_names (stats_connection)) ||
172 !_dbus_asv_add_string (&arr_iter, "UniqueName",
173 bus_connection_get_name (stats_connection)) ||
174 !_dbus_asv_add_uint32 (&arr_iter, "PendingReplies",
175 bus_connection_get_n_pending_replies (stats_connection)) ||
176 !_dbus_asv_add_uint32 (&arr_iter, "PeakPendingReplies",
177 bus_connection_get_peak_pending_replies (stats_connection)))
179 _dbus_asv_abandon (&iter, &arr_iter);
183 /* DBusConnection per-connection stats */
185 _dbus_connection_get_stats (stats_connection,
186 &in_messages, &in_bytes, &in_fds,
187 &in_peak_bytes, &in_peak_fds,
188 &out_messages, &out_bytes, &out_fds,
189 &out_peak_bytes, &out_peak_fds);
191 if (!_dbus_asv_add_uint32 (&arr_iter, "IncomingMessages", in_messages) ||
192 !_dbus_asv_add_uint32 (&arr_iter, "IncomingBytes", in_bytes) ||
193 !_dbus_asv_add_uint32 (&arr_iter, "IncomingFDs", in_fds) ||
194 !_dbus_asv_add_uint32 (&arr_iter, "PeakIncomingBytes", in_peak_bytes) ||
195 !_dbus_asv_add_uint32 (&arr_iter, "PeakIncomingFDs", in_peak_fds) ||
196 !_dbus_asv_add_uint32 (&arr_iter, "OutgoingMessages", out_messages) ||
197 !_dbus_asv_add_uint32 (&arr_iter, "OutgoingBytes", out_bytes) ||
198 !_dbus_asv_add_uint32 (&arr_iter, "OutgoingFDs", out_fds) ||
199 !_dbus_asv_add_uint32 (&arr_iter, "PeakOutgoingBytes", out_peak_bytes) ||
200 !_dbus_asv_add_uint32 (&arr_iter, "PeakOutgoingFDs", out_peak_fds))
202 _dbus_asv_abandon (&iter, &arr_iter);
208 if (!_dbus_asv_close (&iter, &arr_iter))
211 if (!bus_transaction_send_from_driver (transaction, caller_connection,
215 dbus_message_unref (reply);
216 return BUS_RESULT_TRUE;
223 dbus_message_unref (reply);
225 return BUS_RESULT_FALSE;
230 bus_stats_handle_get_all_match_rules (DBusConnection *caller_connection,
231 BusTransaction *transaction,
232 DBusMessage *message,
236 DBusString bus_name_str;
237 DBusMessage *reply = NULL;
238 DBusMessageIter iter, hash_iter, entry_iter, arr_iter;
239 BusRegistry *registry;
240 char **services = NULL;
242 DBusConnection *conn_filter = NULL;
243 BusMatchmaker *matchmaker;
246 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
248 registry = bus_connection_get_registry (caller_connection);
249 context = bus_transaction_get_context (transaction);
250 matchmaker = bus_context_get_matchmaker (context);
252 if (!bus_registry_list_services (registry, &services, &services_len))
255 reply = dbus_message_new_method_return (message);
259 dbus_message_iter_init_append (reply, &iter);
261 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sas}",
265 for (i = 0 ; i < services_len ; i++)
269 /* To avoid duplicate entries, only look for unique names */
270 if (services[i][0] != ':')
273 _dbus_string_init_const (&bus_name_str, services[i]);
274 service = bus_registry_lookup (registry, &bus_name_str);
275 _dbus_assert (service != NULL);
277 conn_filter = bus_service_get_primary_owners_connection (service);
278 _dbus_assert (conn_filter != NULL);
280 if (!dbus_message_iter_open_container (&hash_iter, DBUS_TYPE_DICT_ENTRY, NULL,
283 dbus_message_iter_abandon_container (&iter, &hash_iter);
287 if (!dbus_message_iter_append_basic (&entry_iter, DBUS_TYPE_STRING, &services[i]))
289 dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
290 dbus_message_iter_abandon_container (&iter, &hash_iter);
294 if (!dbus_message_iter_open_container (&entry_iter, DBUS_TYPE_ARRAY, "s",
297 dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
298 dbus_message_iter_abandon_container (&iter, &hash_iter);
302 if (!bus_match_rule_dump (matchmaker, conn_filter, &arr_iter))
304 dbus_message_iter_abandon_container (&entry_iter, &arr_iter);
305 dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
306 dbus_message_iter_abandon_container (&iter, &hash_iter);
310 if (!dbus_message_iter_close_container (&entry_iter, &arr_iter))
312 dbus_message_iter_abandon_container (&hash_iter, &entry_iter);
313 dbus_message_iter_abandon_container (&iter, &hash_iter);
316 if (!dbus_message_iter_close_container (&hash_iter, &entry_iter))
318 dbus_message_iter_abandon_container (&iter, &hash_iter);
323 if (!dbus_message_iter_close_container (&iter, &hash_iter))
326 if (!bus_transaction_send_from_driver (transaction, caller_connection,
330 dbus_message_unref (reply);
331 dbus_free_string_array (services);
336 dbus_message_unref (reply);
338 dbus_free_string_array (services);