munin_core.module 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. // $Id$
  3. /**
  4. * @file
  5. * Core Drupal instrumentation for Munin
  6. *
  7. * @author Frederic G. MARAND
  8. *
  9. * @copyright (c) 2011 Ouest Systèmes Informatiques
  10. *
  11. * Licensed under the General Public License version 2 or later.
  12. */
  13. /**
  14. * Implements hook_munin_api_info().
  15. *
  16. * @return
  17. * An array of Munin probes informations, index by probe name.
  18. */
  19. function munin_core_munin_api_info() {
  20. $int = array(
  21. '#graph_printf' => "'%d'",
  22. );
  23. /**
  24. * Ignore anon and auth roles: no user carries them in users_roles anyway.
  25. */
  26. $sq = 'SELECT r.rid, r.name FROM {role} r WHERE r.rid > 2 ORDER BY 2';
  27. $q = db_query($sq);
  28. $roles = array();
  29. while ($o = db_fetch_object($q)) {
  30. $roles[$o->rid] = $o->name;
  31. }
  32. $ret = array(
  33. '#title' => t('Drupal'),
  34. '#description' => t('Graphs about Drupal core'),
  35. 'munin_core' => array(
  36. '#title' => t('Core user-related statistics'),
  37. '#info' => t('Core statistics regarding users and sessions.'),
  38. '#graph_vlabel' => t('Anon/blocked (-) vs Logged/Active (+)'),
  39. 'anon_current' => $int + array(
  40. '#label' => t('Sessions, anon'),
  41. '#type' => MUNIN_API_GAUGE,
  42. '#info' => t('The number of anonymous sessions not older than 5 minutes. Only meaningful if you are not using an alternate sessions implementation not using the sessions table.'),
  43. '#graph' => 'no',
  44. ),
  45. 'user_current' => $int + array(
  46. '#label' => t('Sessions'),
  47. '#type' => MUNIN_API_GAUGE,
  48. '#info' => t('The number of sessions not older than 5 minutes. Only meaningful if you are not using an alternate sessions implementation not using the sessions table. Anonymous sessions display as negative.'),
  49. '#negative' => 'anon_current',
  50. ),
  51. 'user_blocked_count' => $int + array(
  52. '#label' => t('Users, blocked'),
  53. '#type' => MUNIN_API_GAUGE,
  54. '#info' => t('The number of users with status = 0'),
  55. '#graph' => 'no',
  56. ),
  57. 'user_active_count' => $int + array(
  58. '#label' => t('Users'),
  59. '#type' => MUNIN_API_GAUGE,
  60. '#info' => t('The number of users. Blocked users display as negative.'),
  61. '#negative' => 'user_blocked_count',
  62. ),
  63. ),
  64. 'munin_core_roles' => array(
  65. '#title' => t('Core role statistics'),
  66. '#info' => t('Information about users roles.'),
  67. '#graph_vlabel' => t('Users by roles'),
  68. ),
  69. 'munin_core_content' => array(
  70. '#title' => t('Core content statistics'),
  71. '#info' => t('Information about nodes, comments and terms.'),
  72. '#graph_vlabel' => t('Entries unpub(-)/pub(+)'),
  73. 'node_count_unpub' => $int + array(
  74. '#label' => t('Nodes, unpublished'),
  75. '#type' => MUNIN_API_GAUGE,
  76. '#graph' => 'no',
  77. ),
  78. 'node_count' => $int + array(
  79. '#label' => t('Nodes'),
  80. '#info' => t('Unpublished nodes display as negative.'),
  81. '#type' => MUNIN_API_GAUGE,
  82. '#negative' => 'node_count_unpub',
  83. ),
  84. 'comment_count_unpub' => $int + array(
  85. '#label' => t('Comments, unpublished'),
  86. '#type' => MUNIN_API_GAUGE,
  87. '#graph' => 'no',
  88. ),
  89. 'comment_count' => $int + array(
  90. '#label' => t('Comments'),
  91. '#info' => t('Unpublished comments display as negative.'),
  92. '#type' => MUNIN_API_GAUGE,
  93. '#negative' => 'comment_count_unpub',
  94. ),
  95. ),
  96. 'munin_core_taxonomy' => array(
  97. '#title' => t('Core taxonomy statistics'),
  98. '#info' => t('Core statistics regarding taxonomy.'),
  99. '#graph_vlabel' => t('Vocabularies (-)/Terms (+)'),
  100. 'vocab_count' => $int + array(
  101. '#label' => t('Vocabularies'),
  102. '#info' => t('Vocabularies'),
  103. '#type' => MUNIN_API_GAUGE,
  104. ),
  105. 'term_count' => $int + array(
  106. '#label' => t('Terms'),
  107. '#info' => t('Total terms across all vocabularies'),
  108. '#type' => MUNIN_API_GAUGE,
  109. ),
  110. ),
  111. );
  112. foreach ($roles as $rid => $name) {
  113. $machine_name = str_replace(' ', '_', $name);
  114. $ret['munin_core_roles']['role_'. $machine_name] = $int + array(
  115. '#label' => $name,
  116. '#info' => t('Number of users with the @role role', array('@role' => $name)),
  117. '#type' => MUNIN_API_GAUGE,
  118. );
  119. }
  120. variable_set('munin_core_roles', $roles);
  121. return $ret;
  122. }
  123. /**
  124. * Implements hook_munin_api_fetch().
  125. *
  126. * TODO Reduce the number of queries by integrating the filters.
  127. */
  128. function munin_core_munin_api_fetch($graph_name) {
  129. switch ($graph_name) {
  130. case 'munin_core':
  131. $sq = 'SELECT COUNT(u.uid) cnt, u.status FROM {users} u WHERE u.uid <> 0 GROUP BY 2';
  132. $result = db_query($sq);
  133. $users = array(0 => 0, 1 => 0);
  134. while ($row = db_fetch_object($result)) {
  135. $users[$row->status] = $row->cnt;
  136. }
  137. $ret['user_active_count'] = $users[1];
  138. $ret['user_blocked_count'] = $users[0];
  139. $sq = 'SELECT COUNT(*) cnt FROM {sessions} s WHERE s.uid <> 0 AND s.timestamp >= UNIX_TIMESTAMP() - 5*60';
  140. $ret['user_current'] = db_result(db_query($sq));
  141. $sq = 'SELECT COUNT(*) cnt FROM {sessions} s WHERE s.uid = 0 AND s.timestamp >= UNIX_TIMESTAMP() - 5*60';
  142. $ret['anon_current'] = db_result(db_query($sq));
  143. break;
  144. case 'munin_core_roles':
  145. $roles = variable_get('munin_core_roles', array());
  146. $ph = db_placeholders($roles);
  147. $sq = <<<EOT
  148. SELECT COUNT(ur.uid) cnt, r.rid, r.name
  149. FROM {role} r
  150. LEFT JOIN {users_roles} ur ON r.rid = ur.rid
  151. WHERE r.rid IN ($ph)
  152. GROUP BY 2, 3
  153. EOT;
  154. $ret = array();
  155. $q = db_query($sq, array_keys($roles));
  156. while ($o = db_fetch_object($q)) {
  157. $name = str_replace(' ', '_', $o->name);
  158. $ret['role_'. $name] = empty($o->cnt) ? 0 : $o->cnt; // Can be NULL
  159. }
  160. break;
  161. case 'munin_core_content':
  162. $ret = array(
  163. 'node_count_unpub' => 0,
  164. 'node_count' => 0,
  165. 'comment_count_unpub' => 0,
  166. 'comment_count' => 0,
  167. );
  168. $sq = 'SELECT COUNT(*) cnt, n.status FROM {node} n GROUP BY n.status';
  169. // No db_rewrite_sql(): this is an administrative mechanism
  170. $q = db_query($sq);
  171. while ($o = db_fetch_object($q)) {
  172. switch ($o->status) {
  173. case 0:
  174. $ret['node_count_unpub'] = $o->cnt;
  175. break;
  176. case 1:
  177. $ret['node_count'] = $o->cnt;
  178. break;
  179. default:
  180. watchdog('munin_core', 'Nodes with status @status reported: @count', array(
  181. '@status' => $o->status,
  182. '@count' => $o->cnt,
  183. ), WATCHDOG_NOTICE);
  184. }
  185. }
  186. $sq = 'SELECT COUNT(*) cnt, c.status FROM {comments} c GROUP BY c.status';
  187. $q = db_query($sq);
  188. // No db_rewrite_sql(): this is an administrative mechanism
  189. while ($o = db_fetch_object($q)) {
  190. switch ($o->status) {
  191. case 1:
  192. $ret['comment_count_unpub'] = $o->cnt;
  193. break;
  194. case 0:
  195. $ret['comment_count'] = $o->cnt;
  196. break;
  197. default:
  198. watchdog('munin_core', 'Comments with status @status reported: @count', array(
  199. '@status' => $o->status,
  200. '@count' => $o->cnt,
  201. ), WATCHDOG_NOTICE);
  202. }
  203. }
  204. break;
  205. case 'munin_core_taxonomy':
  206. $sq = 'SELECT COUNT(*) FROM {term_data}';
  207. $ret['term_count'] = db_result(db_query($sq));
  208. $sq = 'SELECT COUNT(*) FROM {vocabulary}';
  209. $ret['vocab_count'] = db_result(db_query($sq));
  210. break;
  211. }
  212. return $ret;
  213. }