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