munin_core.module 7.6 KB

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