File.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC\Core\Command\Log;
  8. use OCP\IConfig;
  9. use Stecman\Component\Symfony\Console\BashCompletion\Completion;
  10. use Stecman\Component\Symfony\Console\BashCompletion\Completion\ShellPathCompletion;
  11. use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
  12. use Symfony\Component\Console\Command\Command;
  13. use Symfony\Component\Console\Input\InputInterface;
  14. use Symfony\Component\Console\Input\InputOption;
  15. use Symfony\Component\Console\Output\OutputInterface;
  16. class File extends Command implements Completion\CompletionAwareInterface {
  17. public function __construct(
  18. protected IConfig $config,
  19. ) {
  20. parent::__construct();
  21. }
  22. protected function configure() {
  23. $this
  24. ->setName('log:file')
  25. ->setDescription('manipulate logging backend')
  26. ->addOption(
  27. 'enable',
  28. null,
  29. InputOption::VALUE_NONE,
  30. 'enable this logging backend'
  31. )
  32. ->addOption(
  33. 'file',
  34. null,
  35. InputOption::VALUE_REQUIRED,
  36. 'set the log file path'
  37. )
  38. ->addOption(
  39. 'rotate-size',
  40. null,
  41. InputOption::VALUE_REQUIRED,
  42. 'set the file size for log rotation, 0 = disabled'
  43. )
  44. ;
  45. }
  46. protected function execute(InputInterface $input, OutputInterface $output): int {
  47. $toBeSet = [];
  48. if ($input->getOption('enable')) {
  49. $toBeSet['log_type'] = 'file';
  50. }
  51. if ($file = $input->getOption('file')) {
  52. $toBeSet['logfile'] = $file;
  53. }
  54. if (($rotateSize = $input->getOption('rotate-size')) !== null) {
  55. $rotateSize = \OCP\Util::computerFileSize($rotateSize);
  56. $this->validateRotateSize($rotateSize);
  57. $toBeSet['log_rotate_size'] = $rotateSize;
  58. }
  59. // set config
  60. foreach ($toBeSet as $option => $value) {
  61. $this->config->setSystemValue($option, $value);
  62. }
  63. // display config
  64. // TODO: Drop backwards compatibility for config in the future
  65. $logType = $this->config->getSystemValue('log_type', 'file');
  66. if ($logType === 'file' || $logType === 'owncloud') {
  67. $enabledText = 'enabled';
  68. } else {
  69. $enabledText = 'disabled';
  70. }
  71. $output->writeln('Log backend file: ' . $enabledText);
  72. $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
  73. $defaultLogFile = rtrim($dataDir, '/') . '/nextcloud.log';
  74. $output->writeln('Log file: ' . $this->config->getSystemValue('logfile', $defaultLogFile));
  75. $rotateSize = $this->config->getSystemValue('log_rotate_size', 100 * 1024 * 1024);
  76. if ($rotateSize) {
  77. $rotateString = \OCP\Util::humanFileSize($rotateSize);
  78. } else {
  79. $rotateString = 'disabled';
  80. }
  81. $output->writeln('Rotate at: ' . $rotateString);
  82. return 0;
  83. }
  84. /**
  85. * @throws \InvalidArgumentException
  86. */
  87. protected function validateRotateSize(false|int|float $rotateSize): void {
  88. if ($rotateSize === false) {
  89. throw new \InvalidArgumentException('Error parsing log rotation file size');
  90. }
  91. if ($rotateSize < 0) {
  92. throw new \InvalidArgumentException('Log rotation file size must be non-negative');
  93. }
  94. }
  95. /**
  96. * @param string $optionName
  97. * @param CompletionContext $context
  98. * @return string[]
  99. */
  100. public function completeOptionValues($optionName, CompletionContext $context) {
  101. if ($optionName === 'file') {
  102. $helper = new ShellPathCompletion(
  103. $this->getName(),
  104. 'file',
  105. Completion::TYPE_OPTION
  106. );
  107. return $helper->run();
  108. } elseif ($optionName === 'rotate-size') {
  109. return [0];
  110. }
  111. return [];
  112. }
  113. /**
  114. * @param string $argumentName
  115. * @param CompletionContext $context
  116. * @return string[]
  117. */
  118. public function completeArgumentValues($argumentName, CompletionContext $context) {
  119. return [];
  120. }
  121. }