|
69 | 69 | ->and($logs[3]->message)->toBe('App\Jobs\TestJob') |
70 | 70 | ->and($logs[3]->context['duration'])->toBe('25.14ms'); |
71 | 71 | }); |
| 72 | + |
| 73 | +it('detects Horizon logs without preamble', function () { |
| 74 | + $file = generateLogFile('horizon_no_preamble.log', content: <<<EOF |
| 75 | + 2023-07-22 16:13:33 App\Jobs\ProcessOrder ............................... RUNNING |
| 76 | + 2023-07-22 16:13:34 App\Jobs\ProcessOrder ............................... 1.2s DONE |
| 77 | + 2023-07-22 16:13:35 App\Jobs\SendInvoice ................................ RUNNING |
| 78 | + 2023-07-22 16:13:36 App\Jobs\SendInvoice ................................ 850ms DONE |
| 79 | +EOF); |
| 80 | + $file = new LogFile($file->path); |
| 81 | + |
| 82 | + expect($file->type()->value)->toBe(LogType::HORIZON); |
| 83 | + |
| 84 | + $logReader = $file->logs()->scan(); |
| 85 | + |
| 86 | + expect($logs = $logReader->get())->toHaveCount(4) |
| 87 | + ->and($logs[0]->datetime->toDateTimeString())->toBe('2023-07-22 16:13:33') |
| 88 | + ->and($logs[0]->level)->toBe('RUNNING') |
| 89 | + ->and($logs[0]->message)->toBe('App\Jobs\ProcessOrder') |
| 90 | + ->and($logs[1]->datetime->toDateTimeString())->toBe('2023-07-22 16:13:34') |
| 91 | + ->and($logs[1]->level)->toBe('DONE') |
| 92 | + ->and($logs[1]->context['duration'])->toBe('1.2s') |
| 93 | + ->and($logs[2]->level)->toBe('RUNNING') |
| 94 | + ->and($logs[3]->level)->toBe('DONE') |
| 95 | + ->and($logs[3]->context['duration'])->toBe('850ms'); |
| 96 | +}); |
| 97 | + |
| 98 | +it('handles various duration formats', function () { |
| 99 | + $file = generateLogFile('horizon_durations.log', content: <<<EOF |
| 100 | + 2022-11-11 13:50:44 App\Jobs\FirstJob ............... 40.12ms DONE |
| 101 | + 2022-11-11 13:50:44 App\Jobs\SecondJob .............. 35.42ms DONE |
| 102 | + 2022-11-11 13:50:44 App\Jobs\ThirdJob ............... 71.48ms DONE |
| 103 | + 2022-11-11 13:50:44 App\Jobs\FourthJob .............. 55.35ms DONE |
| 104 | + 2022-11-11 13:50:45 App\Jobs\FifthJob ............... 3.67ms FAIL |
| 105 | + 2022-11-11 13:50:46 App\Jobs\SixthJob ............... 2m 30s DONE |
| 106 | +EOF); |
| 107 | + $file = new LogFile($file->path); |
| 108 | + |
| 109 | + expect($file->type()->value)->toBe(LogType::HORIZON); |
| 110 | + |
| 111 | + $logReader = $file->logs()->scan(); |
| 112 | + |
| 113 | + expect($logs = $logReader->get())->toHaveCount(6) |
| 114 | + ->and($logs[0]->context['duration'])->toBe('40.12ms') |
| 115 | + ->and($logs[0]->level)->toBe('DONE') |
| 116 | + ->and($logs[1]->context['duration'])->toBe('35.42ms') |
| 117 | + ->and($logs[1]->level)->toBe('DONE') |
| 118 | + ->and($logs[2]->context['duration'])->toBe('71.48ms') |
| 119 | + ->and($logs[2]->level)->toBe('DONE') |
| 120 | + ->and($logs[3]->context['duration'])->toBe('55.35ms') |
| 121 | + ->and($logs[3]->level)->toBe('DONE') |
| 122 | + ->and($logs[4]->context['duration'])->toBe('3.67ms') |
| 123 | + ->and($logs[4]->level)->toBe('FAIL') |
| 124 | + ->and($logs[5]->context['duration'])->toBe('2m 30s') |
| 125 | + ->and($logs[5]->level)->toBe('DONE'); |
| 126 | +}); |
| 127 | + |
| 128 | +it('handles concurrent job output with garbled lines', function () { |
| 129 | + $file = generateLogFile('horizon_concurrent.log', content: <<<EOF |
| 130 | + 2022-11-11 13:50:44 App\Jobs\SlowJob ................ RUNNING |
| 131 | + 2022-11-11 13:50:44 App\Jobs\QuickJob ............... 40.12ms DONE |
| 132 | + 2022-11-11 13:50:44 App\Jobs\AnotherJob ............. 35.42ms DONE |
| 133 | + 2022-11-11 13:50:44 App\Jobs\SlowJob 2022-11-11 13:50:44 App\Notifications\SomeNotification |
| 134 | + 2022-11-11 13:50:44 App\Notifications\SomeNotification ..................... 71.48ms DONE |
| 135 | + 2022-11-11 13:50:44 App\Jobs\SlowJob ..................... 55.35ms DONE |
| 136 | +EOF); |
| 137 | + $file = new LogFile($file->path); |
| 138 | + |
| 139 | + expect($file->type()->value)->toBe(LogType::HORIZON); |
| 140 | + |
| 141 | + $logReader = $file->logs()->scan(); |
| 142 | + |
| 143 | + $logs = $logReader->get(); |
| 144 | + |
| 145 | + // File should be detected as Horizon type |
| 146 | + expect($file->type()->value)->toBe(LogType::HORIZON); |
| 147 | + |
| 148 | + // Valid lines should be parsed correctly (garbled line might be skipped or partially parsed) |
| 149 | + expect($logs)->toBeArray() |
| 150 | + ->and(count($logs))->toBeGreaterThanOrEqual(4); |
| 151 | + |
| 152 | + // Check that at least some valid logs were parsed |
| 153 | + $validLogs = array_filter($logs, fn($log) => $log->datetime !== null); |
| 154 | + expect(count($validLogs))->toBeGreaterThanOrEqual(4); |
| 155 | +}); |
0 commit comments