usage.drush.inc

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

Send scrubbed usage data to drush. Omits arguments and option values in order to assure that no sensitive data is shared. See http://drupal.org/node/1246738.

Functions

Namesort descending Description
drush_usage_send Set option to send usage to Mongolab.
drush_usage_show Displays usage file.
usage_drush_command
usage_drush_exit Log and/or send usage data to Mongolab.
_drush_usage_get_file Returns path to usage file.
_drush_usage_log
_drush_usage_mongolab

File

commands/core/usage.drush.inc
View source
  1. <?php
  2. /**
  3. * @file
  4. * Send scrubbed usage data to drush. Omits arguments and option values in order
  5. * to assure that no sensitive data is shared. See http://drupal.org/node/1246738.
  6. */
  7. use Drush\Log\LogLevel;
  8. /**
  9. * To send usage data, add the following to a .drushrc.php file:
  10. * $options['drush_usage_log'] = TRUE;
  11. * $options['drush_usage_send'] = TRUE;
  12. * $options['drush_usage_size'] = 51200;
  13. */
  14. function usage_drush_command() {
  15. $disclaimer = 'Usage statistics contain the Drush command name and the Drush option names, but no arguments or option values.';
  16. $items['usage-show'] = array(
  17. 'bootstrap' => DRUSH_BOOTSTRAP_NONE,
  18. 'description' => 'Show Drush usage information that has been logged but not sent. ' . $disclaimer,
  19. 'hidden' => TRUE,
  20. 'examples' => array(
  21. 'drush usage-show' => 'Show cached usage statistics.',
  22. '$options[\'drush_usage_log\'] = TRUE;' => 'Specify in a .drushrc.php file that usage information should be logged locally in a usage statistics file.',
  23. ),
  24. 'aliases' => array('ushow'),
  25. );
  26. $items['usage-send'] = array(
  27. 'bootstrap' => DRUSH_BOOTSTRAP_NONE,
  28. 'hidden' => TRUE,
  29. 'description' => 'Send anonymous Drush usage information to statistics logging site. ' . $disclaimer,
  30. 'examples' => array(
  31. 'drush usage-send' => 'Immediately send cached usage statistics.',
  32. '$options[\'drush_usage_send\'] = TRUE;' => 'Specify in a .drushrc.php file that usage information should be sent.',
  33. '$options[\'drush_usage_size\'] = 10240;' => 'Specify the frequency (file size) that usage information should be sent.',
  34. ),
  35. 'aliases' => array('usend'),
  36. );
  37. return $items;
  38. }
  39. /**
  40. * Log and/or send usage data to Mongolab.
  41. *
  42. * An organization can implement own hook_drush_exit() to send data to a
  43. * different endpoint.
  44. */
  45. function usage_drush_exit() {
  46. // Ignore statistics for simulated commands. (n.b. in simulated mode, _drush_usage_mongolab will print rather than send statistics)
  47. if (!drush_get_context('DRUSH_SIMULATE')) {
  48. $file = _drush_usage_get_file();
  49. if (drush_get_option('drush_usage_log', FALSE)) {
  50. _drush_usage_log(drush_get_command(), $file);
  51. }
  52. if (drush_get_option('drush_usage_send', FALSE)) {
  53. _drush_usage_mongolab($file, drush_get_option('drush_usage_size', 51200));
  54. }
  55. }
  56. }
  57. /**
  58. * Set option to send usage to Mongolab.
  59. *
  60. * See usage_drush_exit() for more information.
  61. */
  62. function drush_usage_send() {
  63. $file = _drush_usage_get_file(TRUE);
  64. if ($file) {
  65. drush_set_option('drush_usage_send', TRUE);
  66. drush_set_option('drush_usage_size', 0);
  67. drush_print(dt('To automatically send anonymous usage data, add the following to a .drushrc.php file: $options[\'drush_usage_send\'] = TRUE;'));
  68. }
  69. else {
  70. return drush_set_error('DRUSH_NO_USAGE_FILE', dt('No usage file; set $options[\'drush_usage_log\'] = TRUE; in a .drushrc.php file to enable.'));
  71. }
  72. }
  73. /**
  74. * Displays usage file.
  75. */
  76. function drush_usage_show() {
  77. $file = _drush_usage_get_file(TRUE);
  78. if ($file) {
  79. $json = '[' . file_get_contents($file) . ']';
  80. $usage_data = json_decode($json);
  81. foreach ($usage_data as $item) {
  82. $cmd = $item->cmd;
  83. $options = (array) $item->opt;
  84. array_unshift($options, '');
  85. drush_print($cmd . implode(' --', $options));
  86. }
  87. }
  88. else {
  89. return drush_set_error('DRUSH_NO_USAGE_FILE', dt('No usage file; set $options[\'drush_usage_log\'] = TRUE; in a .drushrc.php file to enable.'));
  90. }
  91. }
  92. /**
  93. * Returns path to usage file.
  94. */
  95. function _drush_usage_get_file($required = FALSE) {
  96. $file = drush_directory_cache('usage') . '/usage.txt';
  97. if (!file_exists($file) && $required) {
  98. return FALSE;
  99. }
  100. return $file;
  101. }
  102. function _drush_usage_log($command, $file) {
  103. drush_merge_engine_data($command);
  104. // Start out with just the options in the current command record.
  105. $options = _drush_get_command_options($command);
  106. // If 'allow-additional-options' contains a list of command names,
  107. // then union together all of the options from all of the commands.
  108. if (is_array($command['allow-additional-options'])) {
  109. $implemented = drush_get_commands();
  110. foreach ($command['allow-additional-options'] as $subcommand_name) {
  111. if (array_key_exists($subcommand_name, $implemented)) {
  112. $options = array_merge($options, _drush_get_command_options($implemented[$subcommand_name]));
  113. }
  114. }
  115. }
  116. $used = drush_get_merged_options();
  117. $command_specific = array_intersect(array_keys($used), array_keys($options));
  118. $record = array(
  119. 'date' => $_SERVER['REQUEST_TIME'],
  120. 'cmd' => $command['command'],
  121. 'opt' => $command_specific,
  122. 'major' => DRUSH_MAJOR_VERSION,
  123. 'minor' => DRUSH_MINOR_VERSION,
  124. 'os' => php_uname('s'),
  125. 'host' => md5(php_uname('n') . get_current_user()),
  126. );
  127. $prequel = (file_exists($file)) ? ",\n" : "";
  128. if (file_put_contents($file, $prequel . json_encode($record), FILE_APPEND)) {
  129. drush_log(dt('Logged command and option names to local cache.'), LogLevel::DEBUG);
  130. }
  131. else {
  132. drush_log(dt('Failed to log command and option names to local cache.'), LogLevel::DEBUG);
  133. }
  134. }
  135. // We only send data periodically to save network traffic and delay. Files
  136. // are sent once they grow over 50KB (configurable).
  137. function _drush_usage_mongolab($file, $min_size_to_send) {
  138. $json = '[' . file_get_contents($file) . ']';
  139. if (filesize($file) > $min_size_to_send) {
  140. $base = 'https://api.mongolab.com/api/1';
  141. $apikey = '4eb95456e4b0bcd285d8135d'; // submitter account.
  142. $database = 'usage';
  143. $collection = 'usage';
  144. $action = "/databases/$database/collections/$collection";
  145. $url = $base . $action . "?apiKey=$apikey";
  146. $header = 'Content-Type: application/json';
  147. if (!drush_shell_exec("wget -q -O - --no-check-certificate --timeout=20 --header=\"$header\" --post-data %s %s", $json, $url)) {
  148. if (!drush_shell_exec("curl -s --connect-timeout 20 --header \"$header\" --data %s %s", $json, $url)) {
  149. drush_log(dt('Drush usage statistics failed to post.'), LogLevel::DEBUG);
  150. return FALSE;
  151. }
  152. }
  153. drush_log(dt('Drush usage statistics successfully posted.'), LogLevel::DEBUG);
  154. // Empty the usage.txt file.
  155. unlink($file);
  156. return TRUE;
  157. }
  158. }