TestSizeRotatingLog.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Log\Logger;
  5. use Illuminate\Support\Facades\Log;
  6. /**
  7. * 测试文件大小限制的日志驱动
  8. */
  9. class TestSizeRotatingLog extends Command
  10. {
  11. /**
  12. * 命令签名
  13. *
  14. * @var string
  15. */
  16. protected $signature = 'log:test-size-rotating {--count=100 : 写入日志的数量} {--size=1K : 每条日志的大小} {--max-file-size=10K : 最大文件大小}';
  17. /**
  18. * 命令描述
  19. *
  20. * @var string
  21. */
  22. protected $description = '测试支持文件大小限制的日志驱动功能';
  23. /**
  24. * 执行命令
  25. *
  26. * @return int
  27. */
  28. public function handle()
  29. {
  30. $count = (int) $this->option('count');
  31. $sizeStr = $this->option('size');
  32. $maxFileSizeStr = $this->option('max-file-size');
  33. $size = $this->parseSize($sizeStr);
  34. $maxFileSize = $this->parseSize($maxFileSizeStr);
  35. $this->info("开始测试日志驱动...");
  36. $this->info("将写入 {$count} 条日志,每条大小约 {$sizeStr}");
  37. $this->info("最大文件大小: {$maxFileSizeStr}");
  38. /**
  39. * 获取测试日志实例
  40. * @var Logger $testLogger
  41. */
  42. $testLogger= Log::channel('size_rotating_daily');
  43. // 生成指定大小的日志内容
  44. $content = str_repeat('A', $size - 100); // 减去100字节用于时间戳等信息
  45. $progressBar = $this->output->createProgressBar($count);
  46. $progressBar->start();
  47. for ($i = 1; $i <= $count; $i++) {
  48. $message = "测试日志 #{$i} - " . $content;
  49. // 随机使用不同的日志级别
  50. $level = $this->getRandomLogLevel();
  51. // 使用测试日志实例
  52. $testLogger->$level($message);
  53. $progressBar->advance();
  54. // 每10条日志暂停一下,避免过快写入
  55. if ($i % 10 === 0) {
  56. usleep(1000); // 1ms
  57. }
  58. }
  59. $progressBar->finish();
  60. $this->newLine();
  61. // 显示生成的日志文件
  62. $this->showTestLogFiles();
  63. $this->info("测试完成!");
  64. return 0;
  65. }
  66. /**
  67. * 解析大小字符串
  68. *
  69. * @param string $sizeStr
  70. * @return int
  71. */
  72. private function parseSize(string $sizeStr): int
  73. {
  74. $sizeStr = trim($sizeStr);
  75. $unit = strtoupper(substr($sizeStr, -1));
  76. $value = (int) substr($sizeStr, 0, -1);
  77. return match ($unit) {
  78. 'K' => $value * 1024,
  79. 'M' => $value * 1024 * 1024,
  80. 'G' => $value * 1024 * 1024 * 1024,
  81. default => (int) $sizeStr,
  82. };
  83. }
  84. /**
  85. * 获取随机日志级别
  86. *
  87. * @return string
  88. */
  89. private function getRandomLogLevel(): string
  90. {
  91. $levels = ['debug', 'info', 'notice', 'warning', 'error'];
  92. return $levels[array_rand($levels)];
  93. }
  94. /**
  95. * 显示生成的测试日志文件
  96. *
  97. * @return void
  98. */
  99. private function showTestLogFiles(): void
  100. {
  101. $logPath = storage_path('logs');
  102. $pattern = $logPath . '/laravel-' . date('Y-m-d') . '*.log';
  103. $files = glob($pattern);
  104. if (empty($files)) {
  105. $this->warn("没有找到今天的测试日志文件");
  106. return;
  107. }
  108. $this->newLine();
  109. $this->info("生成的测试日志文件:");
  110. $tableData = [];
  111. foreach ($files as $file) {
  112. $filename = basename($file);
  113. $size = filesize($file);
  114. $sizeFormatted = $this->formatFileSize($size);
  115. $tableData[] = [$filename, $sizeFormatted, $size];
  116. }
  117. // 按文件名排序
  118. usort($tableData, function ($a, $b) {
  119. return strcmp($a[0], $b[0]);
  120. });
  121. $this->table(['文件名', '大小', '字节数'], $tableData);
  122. }
  123. /**
  124. * 格式化文件大小
  125. *
  126. * @param int $bytes
  127. * @return string
  128. */
  129. private function formatFileSize(int $bytes): string
  130. {
  131. if ($bytes >= 1024 * 1024 * 1024) {
  132. return round($bytes / (1024 * 1024 * 1024), 2) . ' GB';
  133. } elseif ($bytes >= 1024 * 1024) {
  134. return round($bytes / (1024 * 1024), 2) . ' MB';
  135. } elseif ($bytes >= 1024) {
  136. return round($bytes / 1024, 2) . ' KB';
  137. } else {
  138. return $bytes . ' B';
  139. }
  140. }
  141. }