Statistics.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\Core\Command\TaskProcessing;
  7. use OC\Core\Command\Base;
  8. use OCP\TaskProcessing\IManager;
  9. use OCP\TaskProcessing\Task;
  10. use Symfony\Component\Console\Input\InputInterface;
  11. use Symfony\Component\Console\Input\InputOption;
  12. use Symfony\Component\Console\Output\OutputInterface;
  13. class Statistics extends Base {
  14. public function __construct(
  15. protected IManager $taskProcessingManager,
  16. ) {
  17. parent::__construct();
  18. }
  19. protected function configure() {
  20. $this
  21. ->setName('taskprocessing:task:stats')
  22. ->setDescription('get statistics for tasks')
  23. ->addOption(
  24. 'userIdFilter',
  25. 'u',
  26. InputOption::VALUE_OPTIONAL,
  27. 'only get the tasks for one user ID'
  28. )
  29. ->addOption(
  30. 'type',
  31. 't',
  32. InputOption::VALUE_OPTIONAL,
  33. 'only get the tasks for one task type'
  34. )
  35. ->addOption(
  36. 'appId',
  37. null,
  38. InputOption::VALUE_OPTIONAL,
  39. 'only get the tasks for one app ID'
  40. )
  41. ->addOption(
  42. 'customId',
  43. null,
  44. InputOption::VALUE_OPTIONAL,
  45. 'only get the tasks for one custom ID'
  46. )
  47. ->addOption(
  48. 'status',
  49. 's',
  50. InputOption::VALUE_OPTIONAL,
  51. 'only get the tasks that have a specific status (STATUS_UNKNOWN=0, STATUS_SCHEDULED=1, STATUS_RUNNING=2, STATUS_SUCCESSFUL=3, STATUS_FAILED=4, STATUS_CANCELLED=5)'
  52. )
  53. ->addOption(
  54. 'scheduledAfter',
  55. null,
  56. InputOption::VALUE_OPTIONAL,
  57. 'only get the tasks that were scheduled after a specific date (Unix timestamp)'
  58. )
  59. ->addOption(
  60. 'endedBefore',
  61. null,
  62. InputOption::VALUE_OPTIONAL,
  63. 'only get the tasks that ended before a specific date (Unix timestamp)'
  64. );
  65. parent::configure();
  66. }
  67. protected function execute(InputInterface $input, OutputInterface $output): int {
  68. $userIdFilter = $input->getOption('userIdFilter');
  69. if ($userIdFilter === null) {
  70. $userIdFilter = '';
  71. } elseif ($userIdFilter === '') {
  72. $userIdFilter = null;
  73. }
  74. $type = $input->getOption('type');
  75. $appId = $input->getOption('appId');
  76. $customId = $input->getOption('customId');
  77. $status = $input->getOption('status');
  78. $scheduledAfter = $input->getOption('scheduledAfter');
  79. $endedBefore = $input->getOption('endedBefore');
  80. $tasks = $this->taskProcessingManager->getTasks($userIdFilter, $type, $appId, $customId, $status, $scheduledAfter, $endedBefore);
  81. $stats = ['Number of tasks' => count($tasks)];
  82. $maxRunningTime = 0;
  83. $totalRunningTime = 0;
  84. $runningTimeCount = 0;
  85. $maxQueuingTime = 0;
  86. $totalQueuingTime = 0;
  87. $queuingTimeCount = 0;
  88. $maxUserWaitingTime = 0;
  89. $totalUserWaitingTime = 0;
  90. $userWaitingTimeCount = 0;
  91. $maxInputSize = 0;
  92. $maxOutputSize = 0;
  93. $inputCount = 0;
  94. $inputSum = 0;
  95. $outputCount = 0;
  96. $outputSum = 0;
  97. foreach ($tasks as $task) {
  98. // running time
  99. if ($task->getStartedAt() !== null && $task->getEndedAt() !== null) {
  100. $taskRunningTime = $task->getEndedAt() - $task->getStartedAt();
  101. $totalRunningTime += $taskRunningTime;
  102. $runningTimeCount++;
  103. if ($taskRunningTime >= $maxRunningTime) {
  104. $maxRunningTime = $taskRunningTime;
  105. }
  106. }
  107. // queuing time
  108. if ($task->getScheduledAt() !== null && $task->getStartedAt() !== null) {
  109. $taskQueuingTime = $task->getStartedAt() - $task->getScheduledAt();
  110. $totalQueuingTime += $taskQueuingTime;
  111. $queuingTimeCount++;
  112. if ($taskQueuingTime >= $maxQueuingTime) {
  113. $maxQueuingTime = $taskQueuingTime;
  114. }
  115. }
  116. // user waiting time
  117. if ($task->getScheduledAt() !== null && $task->getEndedAt() !== null) {
  118. $taskUserWaitingTime = $task->getEndedAt() - $task->getScheduledAt();
  119. $totalUserWaitingTime += $taskUserWaitingTime;
  120. $userWaitingTimeCount++;
  121. if ($taskUserWaitingTime >= $maxUserWaitingTime) {
  122. $maxUserWaitingTime = $taskUserWaitingTime;
  123. }
  124. }
  125. // input/output sizes
  126. if ($task->getStatus() === Task::STATUS_SUCCESSFUL) {
  127. $outputString = json_encode($task->getOutput());
  128. if ($outputString !== false) {
  129. $outputCount++;
  130. $outputLength = strlen($outputString);
  131. $outputSum += $outputLength;
  132. if ($outputLength > $maxOutputSize) {
  133. $maxOutputSize = $outputLength;
  134. }
  135. }
  136. }
  137. $inputString = json_encode($task->getInput());
  138. if ($inputString !== false) {
  139. $inputCount++;
  140. $inputLength = strlen($inputString);
  141. $inputSum += $inputLength;
  142. if ($inputLength > $maxInputSize) {
  143. $maxInputSize = $inputLength;
  144. }
  145. }
  146. }
  147. if ($runningTimeCount > 0) {
  148. $stats['Max running time'] = $maxRunningTime;
  149. $averageRunningTime = $totalRunningTime / $runningTimeCount;
  150. $stats['Average running time'] = (int)$averageRunningTime;
  151. $stats['Running time count'] = $runningTimeCount;
  152. }
  153. if ($queuingTimeCount > 0) {
  154. $stats['Max queuing time'] = $maxQueuingTime;
  155. $averageQueuingTime = $totalQueuingTime / $queuingTimeCount;
  156. $stats['Average queuing time'] = (int)$averageQueuingTime;
  157. $stats['Queuing time count'] = $queuingTimeCount;
  158. }
  159. if ($userWaitingTimeCount > 0) {
  160. $stats['Max user waiting time'] = $maxUserWaitingTime;
  161. $averageUserWaitingTime = $totalUserWaitingTime / $userWaitingTimeCount;
  162. $stats['Average user waiting time'] = (int)$averageUserWaitingTime;
  163. $stats['User waiting time count'] = $userWaitingTimeCount;
  164. }
  165. if ($outputCount > 0) {
  166. $stats['Max output size (bytes)'] = $maxOutputSize;
  167. $averageOutputSize = $outputSum / $outputCount;
  168. $stats['Average output size (bytes)'] = (int)$averageOutputSize;
  169. $stats['Number of tasks with output'] = $outputCount;
  170. }
  171. if ($inputCount > 0) {
  172. $stats['Max input size (bytes)'] = $maxInputSize;
  173. $averageInputSize = $inputSum / $inputCount;
  174. $stats['Average input size (bytes)'] = (int)$averageInputSize;
  175. $stats['Number of tasks with input'] = $inputCount;
  176. }
  177. $this->writeArrayInOutputFormat($input, $output, $stats);
  178. return 0;
  179. }
  180. }