Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
58.93% |
33 / 56 |
|
20.00% |
1 / 5 |
CRAP | |
0.00% |
0 / 1 |
| DailyFileLogsChannel | |
58.93% |
33 / 56 |
|
20.00% |
1 / 5 |
14.61 | |
0.00% |
0 / 1 |
| getRetentionDays | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| getLogFileForDateTime | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| getDateTimeForFilePath | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
| getLineLocationForDateTime | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
1 | |||
| getLogFileBefore | |
88.89% |
8 / 9 |
|
0.00% |
0 / 1 |
2.01 | |||
| getLogFileAfter | |
88.89% |
8 / 9 |
|
0.00% |
0 / 1 |
2.01 | |||
| cleanUpOldFiles | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
| optimizeHybridFiles | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Olz\Apps\Logs\Utils; |
| 4 | |
| 5 | abstract class DailyFileLogsChannel extends BaseLogsChannel { |
| 6 | abstract protected function getRetentionDays(): ?int; |
| 7 | |
| 8 | abstract protected function getLogFileForDateTime(\DateTime $date_time): LogFileInterface; |
| 9 | |
| 10 | abstract protected function getDateTimeForFilePath(string $file_path): \DateTime; |
| 11 | |
| 12 | protected function getLineLocationForDateTime( |
| 13 | \DateTime $date_time, |
| 14 | ): LineLocation { |
| 15 | $log_file = $this->getLogFileForDateTime($date_time); |
| 16 | $file_index = $this->getOrCreateIndex($log_file); |
| 17 | $number_of_lines = count($file_index['lines']); |
| 18 | $fp = $log_file->open('r'); |
| 19 | |
| 20 | [$line_number, $cmp] = $this->generalUtils()->binarySearch( |
| 21 | function ($line_number) use ($log_file, $fp, $file_index, $date_time) { |
| 22 | $index = $file_index['lines'][$line_number]; |
| 23 | $log_file->seek($fp, $index); |
| 24 | $line = $log_file->gets($fp); |
| 25 | $date_time_at_index = $this->parseDateTimeOfLine($line ?? ''); |
| 26 | return $date_time <=> $date_time_at_index; |
| 27 | }, |
| 28 | 0, |
| 29 | $number_of_lines - 1, |
| 30 | ); |
| 31 | |
| 32 | $log_file->close($fp); |
| 33 | return new LineLocation($log_file, $line_number, $cmp); |
| 34 | } |
| 35 | |
| 36 | protected function getLogFileBefore(LogFileInterface $log_file): LogFileInterface { |
| 37 | $path = $log_file->getPath(); |
| 38 | $date_time = $this->getDateTimeForFilePath($path); |
| 39 | $minus_one_day = \DateInterval::createFromDateString("-1 days"); |
| 40 | $iso_noon = $date_time->format('Y-m-d').' 12:00:00'; |
| 41 | $day_before = (new \DateTime($iso_noon))->add($minus_one_day); |
| 42 | $new_log_file = $this->getLogFileForDateTime($day_before); |
| 43 | if (!$new_log_file->exists()) { |
| 44 | throw new \Exception("No such file: {$new_log_file->getPath()}"); |
| 45 | } |
| 46 | return $new_log_file; |
| 47 | } |
| 48 | |
| 49 | protected function getLogFileAfter(LogFileInterface $log_file): LogFileInterface { |
| 50 | $path = $log_file->getPath(); |
| 51 | $date_time = $this->getDateTimeForFilePath($path); |
| 52 | $plus_one_day = \DateInterval::createFromDateString("+1 days"); |
| 53 | $iso_noon = $date_time->format('Y-m-d').' 12:00:00'; |
| 54 | $day_after = (new \DateTime($iso_noon))->add($plus_one_day); |
| 55 | $new_log_file = $this->getLogFileForDateTime($day_after); |
| 56 | if (!$new_log_file->exists()) { |
| 57 | throw new \Exception("No such file: {$new_log_file->getPath()}"); |
| 58 | } |
| 59 | return $new_log_file; |
| 60 | } |
| 61 | |
| 62 | public function cleanUpOldFiles(?int $num_days = 30): void { |
| 63 | $now = new \DateTime($this->dateUtils()->getIsoNow()); |
| 64 | $interval = "-{$this->getRetentionDays()} days"; |
| 65 | $minus_retention = \DateInterval::createFromDateString($interval); |
| 66 | $this->generalUtils()->checkNotFalse($minus_retention, "Invalid date interval {$interval}"); |
| 67 | $before_retention = $now->add($minus_retention); |
| 68 | |
| 69 | $day = $before_retention; |
| 70 | $minus_one_day = \DateInterval::createFromDateString("-1 days"); |
| 71 | $this->log()->info("Clean up {$num_days} log files before {$day->format('Y-m-d')} in channel {$this->getName()} ({$this->getId()})..."); |
| 72 | for ($i = 0; $i < $num_days; $i++) { |
| 73 | $day = $day->add($minus_one_day); |
| 74 | $log_file = $this->getLogFileForDateTime($day); |
| 75 | $log_file->purge(); |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | public function optimizeHybridFiles(): void { |
| 80 | $now = new \DateTime($this->dateUtils()->getIsoNow()); |
| 81 | $retention_days = $this->getRetentionDays(); |
| 82 | |
| 83 | $this->log()->info("Optimizing last {$retention_days} hybrid log files in channel {$this->getName()} ({$this->getId()})..."); |
| 84 | $day = $now; |
| 85 | $minus_one_day = \DateInterval::createFromDateString("-1 days"); |
| 86 | for ($i = 0; $i <= $retention_days; $i++) { |
| 87 | $log_file = $this->getLogFileForDateTime($day); |
| 88 | $log_file->optimize(); |
| 89 | $day = $day->add($minus_one_day); |
| 90 | } |
| 91 | } |
| 92 | } |