feat: charts
This commit is contained in:
parent
1ae6106782
commit
1d0a1ab16a
@ -15,7 +15,7 @@ class StartSentinel
|
|||||||
instant_remote_process(['docker rm -f coolify-sentinel'], $server, false);
|
instant_remote_process(['docker rm -f coolify-sentinel'], $server, false);
|
||||||
}
|
}
|
||||||
instant_remote_process([
|
instant_remote_process([
|
||||||
"docker run --rm --pull always -d -e \"SCHEDULER=true\" --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/metrics:/app/metrics -v /data/coolify/logs:/app/logs --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version",
|
"docker run --rm --pull always -d -e \"SCHEDULER=true\" -e \"METRICS_HISTORY=10\" -e \"REFRESH_RATE=5\" --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/metrics:/app/metrics -v /data/coolify/logs:/app/logs --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version",
|
||||||
'chown -R 9999:root /data/coolify/metrics /data/coolify/logs',
|
'chown -R 9999:root /data/coolify/metrics /data/coolify/logs',
|
||||||
'chmod -R 700 /data/coolify/metrics /data/coolify/logs',
|
'chmod -R 700 /data/coolify/metrics /data/coolify/logs',
|
||||||
], $server, false);
|
], $server, false);
|
||||||
|
@ -36,7 +36,10 @@ class PullSentinelImageJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$version = get_latest_sentinel_version();
|
$version = get_latest_sentinel_version();
|
||||||
if (! $version) {
|
if (isDev()) {
|
||||||
|
$version = "0.0.5";
|
||||||
|
}
|
||||||
|
if (!$version) {
|
||||||
ray('Failed to get latest Sentinel version');
|
ray('Failed to get latest Sentinel version');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -52,7 +55,7 @@ class PullSentinelImageJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
}
|
}
|
||||||
ray('Sentinel image is up to date');
|
ray('Sentinel image is up to date');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
send_internal_notification('PullSentinelImageJob failed with: '.$e->getMessage());
|
send_internal_notification('PullSentinelImageJob failed with: ' . $e->getMessage());
|
||||||
ray($e->getMessage());
|
ray($e->getMessage());
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
33
app/Livewire/Charts/Server.php
Normal file
33
app/Livewire/Charts/Server.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Charts;
|
||||||
|
|
||||||
|
use App\Models\Server as ModelsServer;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Server extends Component
|
||||||
|
{
|
||||||
|
public ModelsServer $server;
|
||||||
|
public $chartId = 'server';
|
||||||
|
public $data;
|
||||||
|
public $categories;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.charts.server');
|
||||||
|
}
|
||||||
|
public function mount()
|
||||||
|
{
|
||||||
|
$this->loadData();
|
||||||
|
}
|
||||||
|
public function loadData()
|
||||||
|
{
|
||||||
|
$metrics = $this->server->getMetrics();
|
||||||
|
$metrics = collect($metrics)->map(function ($metric) {
|
||||||
|
return [$metric[0], $metric[1]];
|
||||||
|
});
|
||||||
|
$this->dispatch("refreshChartData-{$this->chartId}", [
|
||||||
|
'seriesData' => $metrics,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -487,7 +487,6 @@ $schema://$host {
|
|||||||
$parsedCollection = collect($cpu)->flatMap(function ($item) {
|
$parsedCollection = collect($cpu)->flatMap(function ($item) {
|
||||||
return collect(explode("\n", trim($item)))->map(function ($line) {
|
return collect(explode("\n", trim($item)))->map(function ($line) {
|
||||||
[$time, $value] = explode(',', trim($line));
|
[$time, $value] = explode(',', trim($line));
|
||||||
|
|
||||||
return [(int) $time, (float) $value];
|
return [(int) $time, (float) $value];
|
||||||
});
|
});
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
30
app/View/Components/ApexCharts.php
Normal file
30
app/View/Components/ApexCharts.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class ApexCharts extends Component
|
||||||
|
{
|
||||||
|
public string $chartId;
|
||||||
|
public $seriesData;
|
||||||
|
public $categories;
|
||||||
|
public $seriesName;
|
||||||
|
public function __construct($chartId, $seriesData, $categories, $seriesName = '')
|
||||||
|
{
|
||||||
|
$this->chartId = $chartId;
|
||||||
|
$this->seriesData = $seriesData;
|
||||||
|
$this->categories = $categories;
|
||||||
|
$this->seriesName = $seriesName ?? 'Series';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*/
|
||||||
|
public function render(): View|Closure|string
|
||||||
|
{
|
||||||
|
return view('components.apex-charts');
|
||||||
|
}
|
||||||
|
}
|
78
resources/views/components/apex-charts.blade.php
Normal file
78
resources/views/components/apex-charts.blade.php
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<div wire:ignore id="{!! $chartId !!}"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const options = {
|
||||||
|
chart: {
|
||||||
|
height: '150px',
|
||||||
|
id: '{!! $chartId !!}',
|
||||||
|
type: 'area',
|
||||||
|
stroke: {
|
||||||
|
curve: 'straight',
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
show: false,
|
||||||
|
tools: {
|
||||||
|
download: true,
|
||||||
|
selection: false,
|
||||||
|
zoom: false,
|
||||||
|
zoomin: false,
|
||||||
|
zoomout: false,
|
||||||
|
pan: false,
|
||||||
|
reset: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
animations: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
grid: {
|
||||||
|
show: true,
|
||||||
|
borderColor: '',
|
||||||
|
},
|
||||||
|
colors: ['red'],
|
||||||
|
xaxis: {
|
||||||
|
type: 'datetime',
|
||||||
|
labels: {
|
||||||
|
show: true,
|
||||||
|
style: {
|
||||||
|
colors: '#ffffff',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
show: true,
|
||||||
|
labels: {
|
||||||
|
show: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [{
|
||||||
|
name: '{!! $seriesName !!}',
|
||||||
|
data: '{!! $seriesData !!}'
|
||||||
|
}],
|
||||||
|
noData: {
|
||||||
|
text: 'Loading...'
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const chart = new ApexCharts(document.getElementById(`{!! $chartId !!}`), options);
|
||||||
|
chart.render();
|
||||||
|
document.addEventListener('livewire:init', () => {
|
||||||
|
Livewire.on('refreshChartData-{!! $chartId !!}', (chartData) => {
|
||||||
|
chart.updateOptions({
|
||||||
|
series: [{
|
||||||
|
data: chartData[0].seriesData,
|
||||||
|
}],
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
@ -38,6 +38,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/8.3.0/pusher.min.js"
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/8.3.0/pusher.min.js"
|
||||||
integrity="sha512-tXL5mrkSoP49uQf2jO0LbvzMyFgki//znmq0wYXGq94gVF6TU0QlrSbwGuPpKTeN1mIjReeqKZ4/NJPjHN1d2Q=="
|
integrity="sha512-tXL5mrkSoP49uQf2jO0LbvzMyFgki//znmq0wYXGq94gVF6TU0QlrSbwGuPpKTeN1mIjReeqKZ4/NJPjHN1d2Q=="
|
||||||
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||||
@endauth
|
@endauth
|
||||||
</head>
|
</head>
|
||||||
@section('body')
|
@section('body')
|
||||||
|
4
resources/views/livewire/charts/server.blade.php
Normal file
4
resources/views/livewire/charts/server.blade.php
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<div wire:poll.5000ms='loadData'>
|
||||||
|
<h1>CPU Usage</h1>
|
||||||
|
<x-apex-charts :chart-id="$chartId" :series-data="$data" :categories="$categories" series-name="Total distance this year"/>
|
||||||
|
</div>
|
@ -39,9 +39,9 @@
|
|||||||
Add Resource</span>
|
Add Resource</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="hover:underline"
|
<a class="hover:underline"
|
||||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||||
Settings
|
Settings
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -161,7 +161,6 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function gotoProject(uuid, environment = 'production') {
|
function gotoProject(uuid, environment = 'production') {
|
||||||
window.location.href = '/project/' + uuid + '/' + environment;
|
window.location.href = '/project/' + uuid + '/' + environment;
|
||||||
|
@ -5,4 +5,9 @@
|
|||||||
<x-server.navbar :server="$server" :parameters="$parameters" />
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
<livewire:server.form :server="$server" />
|
<livewire:server.form :server="$server" />
|
||||||
<livewire:server.delete :server="$server" />
|
<livewire:server.delete :server="$server" />
|
||||||
|
@if (isDev())
|
||||||
|
<div class="pt-10">
|
||||||
|
<livewire:charts.server :server="$server" />
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user