watchdog.drush.inc

  1. 8.0.x commands/core/watchdog.drush.inc
  2. 6.x commands/core/watchdog.drush.inc
  3. 7.x commands/core/watchdog.drush.inc
  4. 3.x commands/core/watchdog.drush.inc
  5. 4.x commands/core/watchdog.drush.inc
  6. 5.x commands/core/watchdog.drush.inc
  7. master commands/core/watchdog.drush.inc

Functions

Namesort descending Description
core_watchdog_format_result Format a watchdog database row.
core_watchdog_message_types Helper function to obtain the message types based on drupal version.
core_watchdog_query Build a WHERE snippet based on given parameters.
drush_core_watchdog_delete Command callback.
drush_core_watchdog_list Command callback.
drush_core_watchdog_show Command callback.
drush_core_watchdog_show_many Print a table of watchdog messages.
drush_core_watchdog_show_one Print a watchdog message.
watchdog_drush_command Implementation of hook_drush_command().
watchdog_drush_help Implementation of hook_drush_help().

File

commands/core/watchdog.drush.inc
View source
  1. <?php
  2. /**
  3. * Implementation of hook_drush_help().
  4. */
  5. function watchdog_drush_help($section) {
  6. switch ($section) {
  7. case 'drush:watchdog-list':
  8. return dt('Show available message types and severity levels. A prompt will ask for a choice to show watchdog messages.');
  9. case 'drush:watchdog-show':
  10. return dt('Show watchdog messages. Arguments and options can be combined to configure which messages to show.');
  11. case 'drush:watchdog-delete':
  12. return dt('Delete watchdog messages. Arguments or options must be provided to specify which messages to delete.');
  13. }
  14. }
  15. /**
  16. * Implementation of hook_drush_command().
  17. */
  18. function watchdog_drush_command() {
  19. $items['watchdog-list'] = array(
  20. 'description' => 'Show available message types and severity levels. A prompt will ask for a choice to show watchdog messages.',
  21. 'drupal dependencies' => array('dblog'),
  22. 'outputformat' => array(
  23. 'default' => 'table',
  24. 'pipe-format' => 'var_export',
  25. 'field-labels' => array('wid' => 'ID', 'type' => 'Type', 'message' => 'Message', 'severity' => 'Severity', 'location' => 'Location', 'hostname' => 'Hostname', 'date' => 'Date', 'username' => 'Username'),
  26. 'fields-default' => array('wid', 'date', 'type', 'severity', 'message'),
  27. 'column-widths' => array('type' => 8, 'severity' => 8),
  28. 'output-data-type' => 'format-table',
  29. ),
  30. 'aliases' => array('wd-list'),
  31. );
  32. $items['watchdog-show'] = array(
  33. 'description' => 'Show watchdog messages.',
  34. 'drupal dependencies' => array('dblog'),
  35. 'arguments' => array(
  36. 'wid' => 'Optional id of a watchdog message to show in detail. If not provided, a listing of most recent 10 messages will be displayed. Alternatively if a string is provided, watchdog messages will be filtered by it.',
  37. ),
  38. 'options' => array(
  39. 'count' => 'The number of messages to show. Defaults to 10.',
  40. 'severity' => 'Restrict to messages of a given severity level.',
  41. 'type' => 'Restrict to messages of a given type.',
  42. 'tail' => 'Continuously show new watchdog messages until interrupted.',
  43. 'sleep-delay' => 'To be used in conjunction with --tail. This is the number of seconds to wait between each poll to the database. Delay is 1 second by default.',
  44. 'extended' => 'Return extended information about each message.',
  45. ),
  46. 'examples' => array(
  47. 'drush watchdog-show' => 'Show a listing of most recent 10 messages.',
  48. 'drush watchdog-show 64' => 'Show in detail message with id 64.',
  49. 'drush watchdog-show "cron run succesful"' => 'Show a listing of most recent 10 messages containing the string "cron run succesful".',
  50. 'drush watchdog-show --count=46' => 'Show a listing of most recent 46 messages.',
  51. 'drush watchdog-show --severity=notice' => 'Show a listing of most recent 10 messages with a severity of notice.',
  52. 'drush watchdog-show --type=php' => 'Show a listing of most recent 10 messages of type php.',
  53. 'drush watchdog-show --tail --extended' => 'Show a listing of most recent 10 messages with extended information about each one and continue showing messages as they are registered in the watchdog.',
  54. 'drush watchdog-show --tail --sleep-delay=2' => 'Do a tail of the watchdog with a delay of two seconds between each poll to the database.',
  55. ),
  56. 'outputformat' => array(
  57. 'default' => 'table',
  58. 'pipe-format' => 'var_export',
  59. 'field-labels' => array('wid' => 'ID', 'type' => 'Type', 'message' => 'Message', 'severity' => 'Severity', 'location' => 'Location', 'hostname' => 'Hostname', 'date' => 'Date', 'username' => 'Username'),
  60. 'fields-default' => array('wid', 'date', 'type', 'severity', 'message'),
  61. 'column-widths' => array('type' => 8, 'severity' => 8),
  62. 'output-data-type' => 'format-table',
  63. ),
  64. 'aliases' => array('wd-show', 'ws'),
  65. );
  66. $items['watchdog-delete'] = array(
  67. 'description' => 'Delete watchdog messages.',
  68. 'drupal dependencies' => array('dblog'),
  69. 'options' => array(
  70. 'severity' => 'Delete messages of a given severity level.',
  71. 'type' => 'Delete messages of a given type.',
  72. ),
  73. 'examples' => array(
  74. 'drush watchdog-delete all' => 'Delete all messages.',
  75. 'drush watchdog-delete 64' => 'Delete messages with id 64.',
  76. 'drush watchdog-delete "cron run succesful"' => 'Delete messages containing the string "cron run succesful".',
  77. 'drush watchdog-delete --severity=notice' => 'Delete all messages with a severity of notice.',
  78. 'drush watchdog-delete --type=cron' => 'Delete all messages of type cron.',
  79. ),
  80. 'aliases' => array('wd-del', 'wd-delete'),
  81. );
  82. return $items;
  83. }
  84. /**
  85. * Command callback.
  86. */
  87. function drush_core_watchdog_list() {
  88. $options['-- types --'] = dt('== message types ==');
  89. $types = core_watchdog_message_types();
  90. foreach ($types as $type) {
  91. $options[] = $type;
  92. }
  93. $options['-- levels --'] = dt('== severity levels ==');
  94. drush_include_engine('drupal', 'environment');
  95. $severities = core_watchdog_severity_levels();
  96. foreach ($severities as $key => $value) {
  97. $options[] = "$value($key)";
  98. }
  99. $option = drush_choice($options, dt('Select a message type or severity level.'));
  100. if ($option === FALSE) {
  101. return drush_user_abort();
  102. }
  103. $ntypes = count($types);
  104. if ($option < $ntypes) {
  105. drush_set_option('type', $types[$option]);
  106. }
  107. else {
  108. drush_set_option('severity', $option - $ntypes);
  109. }
  110. return drush_core_watchdog_show_many();
  111. }
  112. /**
  113. * Command callback.
  114. */
  115. function drush_core_watchdog_show($arg = NULL) {
  116. if (is_numeric($arg)) {
  117. return drush_core_watchdog_show_one($arg);
  118. }
  119. else {
  120. return drush_core_watchdog_show_many($arg);
  121. }
  122. }
  123. /**
  124. * Print a watchdog message.
  125. *
  126. * @param $wid
  127. * The id of the message to show.
  128. */
  129. function drush_core_watchdog_show_one($wid) {
  130. drush_set_default_outputformat('key-value-list', array('fields-default' => array('wid', 'type', 'message', 'severity', 'date'),));
  131. $rsc = drush_db_select('watchdog', '*', 'wid = :wid', array(':wid' => $wid), 0, 1);
  132. $result = drush_db_fetch_object($rsc);
  133. if (!$result) {
  134. return drush_set_error(dt('Watchdog message #!wid not found.', array('!wid' => $wid)));
  135. }
  136. $result = core_watchdog_format_result($result, TRUE);
  137. return array($result->wid => (array)$result);
  138. }
  139. /**
  140. * Print a table of watchdog messages.
  141. *
  142. * @param $filter
  143. * String to filter the message's text by.
  144. */
  145. function drush_core_watchdog_show_many($filter = NULL) {
  146. $count = drush_get_option('count', 10);
  147. $type = drush_get_option('type');
  148. $severity = drush_get_option('severity');
  149. $tail = drush_get_option('tail', FALSE);
  150. $extended = drush_get_option('extended', FALSE);
  151. $where = core_watchdog_query($type, $severity, $filter);
  152. if ($where === FALSE) {
  153. return drush_log(dt('Aborting.'));
  154. }
  155. $rsc = drush_db_select('watchdog', '*', $where['where'], $where['args'], 0, $count, 'wid', 'DESC');
  156. if ($rsc === FALSE) {
  157. return drush_log(dt('Aborting.'));
  158. }
  159. $table = array();
  160. while ($result = drush_db_fetch_object($rsc)) {
  161. $row = core_watchdog_format_result($result, $extended);
  162. $table[$row->wid] = (array)$row;
  163. }
  164. if (empty($table) && !$tail) {
  165. drush_log(dt('No log messages available.'), 'ok');
  166. return array();
  167. }
  168. else {
  169. drush_log(dt('Most recent !count watchdog log messages:', array('!count' => $count)));
  170. }
  171. if ($tail) {
  172. $field_list = array('wid' => 'ID', 'date' => 'Date', 'severity' => 'Severity', 'type' => 'Type', 'message' => 'Message');
  173. $table = array_reverse($table);
  174. $table_rows = drush_rows_of_key_value_to_array_table($table, $field_list, array());
  175. $tbl = drush_print_table($table_rows, TRUE);
  176. // Reuse the table object to display each line generated while in tail mode.
  177. // To make it possible some hacking is done on the object:
  178. // remove the header and reset the rows on each iteration.
  179. $tbl->_headers = NULL;
  180. // Obtain the last wid. If the table has no rows, start at 0.
  181. if (count($table_rows) > 1) {
  182. $last = array_pop($table_rows);
  183. $last_wid = $last[0];
  184. }
  185. else {
  186. $last_wid = 0;
  187. }
  188. // Adapt the where snippet.
  189. if ($where['where'] != '') {
  190. $where['where'] .= ' AND ';
  191. }
  192. $where['where'] .= 'wid > :wid';
  193. // sleep-delay
  194. $sleep_delay = drush_get_option('sleep-delay', 1);
  195. while (TRUE) {
  196. $where['args'][':wid'] = $last_wid;
  197. $table = array();
  198. // Reset table rows.
  199. $tbl->_data = array();
  200. $rsc = drush_db_select('watchdog', '*', $where['where'], $where['args'], NULL, NULL, 'wid', 'ASC');
  201. while ($result = drush_db_fetch_object($rsc)) {
  202. $row = core_watchdog_format_result($result, $extended);
  203. $table[] = array($row->wid, $row->date, $row->severity, $row->type, $row->message);
  204. #$tbl->addRow(array($row->wid, $row->date, $row->severity, $row->type, $row->message));
  205. $last_wid = $row->wid;
  206. }
  207. $tbl->addData($table);
  208. print $tbl->_buildTable();
  209. sleep($sleep_delay);
  210. }
  211. }
  212. return $table;
  213. }
  214. /**
  215. * Format a watchdog database row.
  216. *
  217. * @param $result
  218. * Array. A database result object.
  219. * @param $extended
  220. * Boolean. Return extended message details.
  221. * @return
  222. * Array. The result object with some attributes themed.
  223. */
  224. function core_watchdog_format_result($result, $extended = FALSE) {
  225. // Severity.
  226. drush_include_engine('drupal', 'environment');
  227. $severities = core_watchdog_severity_levels();
  228. $result->severity = $severities[$result->severity];
  229. // Date.
  230. $result->date = format_date($result->timestamp, 'custom', 'd/M H:i');
  231. unset($result->timestamp);
  232. // Message.
  233. $variables = $result->variables;
  234. if (is_string($variables)) {
  235. $variables = unserialize($variables);
  236. }
  237. if (is_array($variables)) {
  238. $result->message = strtr($result->message, $variables);
  239. }
  240. unset($result->variables);
  241. $message_length = 188;
  242. // Print all the data available
  243. if ($extended) {
  244. // Possible empty values.
  245. if (empty($result->link)) {
  246. unset($result->link);
  247. }
  248. if (empty($result->referer)) {
  249. unset($result->referer);
  250. }
  251. // Username.
  252. if ($account = user_load($result->uid)) {
  253. $result->username = $account->name;
  254. }
  255. else {
  256. $result->username = dt('Anonymous');
  257. }
  258. unset($result->uid);
  259. $message_length = PHP_INT_MAX;
  260. }
  261. $result->message = truncate_utf8(strip_tags(decode_entities($result->message)), $message_length, FALSE, FALSE);
  262. return $result;
  263. }
  264. /**
  265. * Command callback.
  266. *
  267. * @param $arg
  268. * The id of the message to delete or 'all'.
  269. */
  270. function drush_core_watchdog_delete($arg = NULL) {
  271. if ($arg == 'all') {
  272. drush_print(dt('All watchdog messages will be deleted.'));
  273. if (!drush_confirm(dt('Do you really want to continue?'))) {
  274. return drush_user_abort();
  275. }
  276. drush_db_delete('watchdog');
  277. drush_log(dt('All watchdog messages have been deleted.'), 'ok');
  278. }
  279. else if (is_numeric($arg)) {
  280. drush_print(dt('Watchdog message #!wid will be deleted.', array('!wid' => $arg)));
  281. if(!drush_confirm(dt('Do you really want to continue?'))) {
  282. return drush_user_abort();
  283. }
  284. $affected_rows = drush_db_delete('watchdog', 'wid=:wid', array(':wid' => $arg));
  285. if ($affected_rows == 1) {
  286. drush_log(dt('Watchdog message #!wid has been deleted.', array('!wid' => $arg)), 'ok');
  287. }
  288. else {
  289. return drush_set_error(dt('Watchdog message #!wid does not exist.', array('!wid' => $arg)));
  290. }
  291. }
  292. else {
  293. $type = drush_get_option('type');
  294. $severity = drush_get_option('severity');
  295. if ((!isset($arg))&&(!isset($type))&&(!isset($severity))) {
  296. return drush_set_error(dt('No options provided.'));
  297. }
  298. $where = core_watchdog_query($type, $severity, $arg, 'OR');
  299. if ($where === FALSE) {
  300. // Drush set error was already called by core_watchdog_query
  301. return FALSE;
  302. }
  303. drush_print(dt('All messages with !where will be deleted.', array('!where' => preg_replace("/message LIKE %$arg%/", "message body containing '$arg'" , strtr($where['where'], $where['args'])))));
  304. if(!drush_confirm(dt('Do you really want to continue?'))) {
  305. return drush_user_abort();
  306. }
  307. $affected_rows = drush_db_delete('watchdog', $where['where'], $where['args']);
  308. drush_log(dt('!affected_rows watchdog messages have been deleted.', array('!affected_rows' => $affected_rows)), 'ok');
  309. }
  310. }
  311. /**
  312. * Build a WHERE snippet based on given parameters.
  313. *
  314. * @param $type
  315. * String. Valid watchdog type.
  316. * @param $severity
  317. * Int or String for a valid watchdog severity message.
  318. * @param $filter
  319. * String. Value to filter watchdog messages by.
  320. * @param $criteria
  321. * ('AND', 'OR'). Criteria for the WHERE snippet.
  322. * @return
  323. * False or array with structure ('where' => string, 'args' => array())
  324. */
  325. function core_watchdog_query($type = NULL, $severity = NULL, $filter = NULL, $criteria = 'AND') {
  326. $args = array();
  327. $conditions = array();
  328. if ($type) {
  329. $types = core_watchdog_message_types();
  330. if (array_search($type, $types) === FALSE) {
  331. $msg = "Unrecognized message type: !type.\nRecognized types are: !types.";
  332. return drush_set_error('WATCHDOG_UNRECOGNIZED_TYPE', dt($msg, array('!type' => $type, '!types' => implode(', ', $types))));
  333. }
  334. $conditions[] = "type = :type";
  335. $args[':type'] = $type;
  336. }
  337. if (isset($severity)) {
  338. drush_include_engine('drupal', 'environment');
  339. $severities = core_watchdog_severity_levels();
  340. if (isset($severities[$severity])) {
  341. $level = $severity;
  342. }
  343. elseif (($key = array_search($severity, $severities)) !== FALSE) {
  344. $level = $key;
  345. }
  346. else {
  347. $level = FALSE;
  348. }
  349. if ($level === FALSE) {
  350. foreach ($severities as $key => $value) {
  351. $levels[] = "$value($key)";
  352. }
  353. $msg = "Unknown severity level: !severity.\nValid severity levels are: !levels.";
  354. return drush_set_error(dt($msg, array('!severity' => $severity, '!levels' => implode(', ', $levels))));
  355. }
  356. $conditions[] = 'severity = :severity';
  357. $args[':severity'] = $level;
  358. }
  359. if ($filter) {
  360. $conditions[] = "message LIKE :filter";
  361. $args[':filter'] = '%'.$filter.'%';
  362. }
  363. $where = implode(" $criteria ", $conditions);
  364. return array('where' => $where, 'args' => $args);
  365. }
  366. /**
  367. * Helper function to obtain the message types based on drupal version.
  368. *
  369. * @return
  370. * Array of watchdog message types.
  371. */
  372. function core_watchdog_message_types() {
  373. return _dblog_get_message_types();
  374. }