Merge pull request #4512 from philipheinser/logs-for-tasks

Logs for tasks
This commit is contained in:
Andras Bacsai
2024-12-09 11:37:32 +01:00
committed by GitHub
2 changed files with 107 additions and 3 deletions

View File

@@ -24,6 +24,14 @@ class Executions extends Component
#[Locked]
public ?string $serverTimezone = null;
public $currentPage = 1;
public $logsPerPage = 100;
public $selectedExecution = null;
public $isPollingActive = false;
public function getListeners()
{
$teamId = Auth::user()->currentTeam()->id;
@@ -54,16 +62,79 @@ class Executions extends Component
public function refreshExecutions(): void
{
$this->executions = $this->task->executions()->take(20)->get();
if ($this->selectedKey) {
$this->selectedExecution = $this->task->executions()->find($this->selectedKey);
if ($this->selectedExecution && $this->selectedExecution->status !== 'running') {
$this->isPollingActive = false;
}
}
}
public function selectTask($key): void
{
if ($key == $this->selectedKey) {
$this->selectedKey = null;
$this->selectedExecution = null;
$this->currentPage = 1;
$this->isPollingActive = false;
return;
}
$this->selectedKey = $key;
$this->selectedExecution = $this->task->executions()->find($key);
$this->currentPage = 1;
// Start polling if task is running
if ($this->selectedExecution && $this->selectedExecution->status === 'running') {
$this->isPollingActive = true;
}
}
public function polling()
{
if ($this->selectedExecution && $this->isPollingActive) {
$this->selectedExecution->refresh();
if ($this->selectedExecution->status !== 'running') {
$this->isPollingActive = false;
}
}
}
public function loadMoreLogs()
{
$this->currentPage++;
}
public function getLogLinesProperty()
{
if (! $this->selectedExecution) {
return collect();
}
if (! $this->selectedExecution->message) {
return collect(['Waiting for task output...']);
}
$lines = collect(explode("\n", $this->selectedExecution->message));
return $lines->take($this->currentPage * $this->logsPerPage);
}
public function downloadLogs()
{
return response()->streamDownload(function () {
echo $this->selectedExecution->message;
}, 'task-execution-'.$this->selectedExecution->id.'.log');
}
public function hasMoreLogs()
{
if (! $this->selectedExecution || ! $this->selectedExecution->message) {
return false;
}
$lines = collect(explode("\n", $this->selectedExecution->message));
return $lines->count() > ($this->currentPage * $this->logsPerPage);
}
public function formatDateInServerTimezone($date)

View File

@@ -1,4 +1,17 @@
<div class="flex flex-col gap-4">
<div class="flex flex-col gap-4" x-data="{
init() {
let interval;
$wire.$watch('isPollingActive', value => {
if (value) {
interval = setInterval(() => {
$wire.polling();
}, 1000);
} else {
if (interval) clearInterval(interval);
}
});
}
}">
@forelse($executions as $execution)
<a wire:click="selectTask({{ data_get($execution, 'id') }})" @class([
'flex flex-col border-l-2 transition-colors p-4 cursor-pointer',
@@ -23,9 +36,29 @@
</a>
@if (data_get($execution, 'id') == $selectedKey)
<div class="p-4 mb-2 bg-gray-100 dark:bg-coolgray-200 rounded">
@if (data_get($execution, 'message'))
@if (data_get($execution, 'status') === 'running')
<div class="flex items-center gap-2 mb-2">
<span>Task is running...</span>
<x-loading class="w-4 h-4" />
</div>
@endif
@if ($this->logLines->isNotEmpty())
<div>
<pre class="whitespace-pre-wrap">{{ data_get($execution, 'message') }}</pre>
<pre class="whitespace-pre-wrap">
@foreach ($this->logLines as $line)
{{ $line }}
@endforeach
</pre>
<div class="flex gap-2">
@if ($this->hasMoreLogs())
<x-forms.button wire:click.prevent="loadMoreLogs" isHighlighted>
Load More
</x-forms.button>
@endif
<x-forms.button wire:click.prevent="downloadLogs" isHighlighted>
Download
</x-forms.button>
</div>
</div>
@else
<div>No output was recorded for this execution.</div>