Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions LibreNMS/Enum/AlertLogState.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace LibreNMS\Enum;

enum AlertLogState: int
{
case Clear = 0;
case Active = 1;
case Acknowledged = 2;
case Worse = 3;
case Better = 4;
case Changed = 5;
case Recovered = 6;

public function isActive(): bool
{
return match ($this) {
self::Active, self::Worse, self::Better, self::Changed => true,
default => false,
};
}

public function asSeverity(): Severity
{
return match ($this) {
self::Clear, self::Recovered => Severity::Ok,
self::Active => Severity::Error,
self::Acknowledged => Severity::Info,
self::Worse, self::Changed => Severity::Warning,
self::Better => Severity::Notice,
};
}
}
8 changes: 6 additions & 2 deletions LibreNMS/Util/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public static function powerStateLabel($state): array
};
}

public static function severityToLabel(Severity $severity, string $text): string
public static function severityToLabel(Severity $severity, string $text = '', string $title = '', string $class = 'label'): string
{
$state_label = match ($severity) {
Severity::Ok => 'label-success',
Expand All @@ -197,6 +197,10 @@ public static function severityToLabel(Severity $severity, string $text): string
default => 'label-default',
};

return "<span class=\"label $state_label\">$text</span>";
if ($title) {
$title = " title=\"$title\"";
}

return "<span class=\"$class $state_label\"$title>$text</span>";
}
}
5 changes: 5 additions & 0 deletions LibreNMS/Util/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ public static function forExternalGraph($args): string
return LaravelUrl::signedRoute('graph', $args);
}

public static function graphPageUrl(string $type, array $args = []): string
{
return url('graphs', ['type' => $type, ...$args]);
}

/**
* @param array $args
* @return string
Expand Down
16 changes: 13 additions & 3 deletions app/Http/Controllers/PaginatedAjaxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,19 @@ public function formatItem($model)
protected function search($search, $query, $fields)
{
if ($search) {
$query->where(function ($query) use ($fields, $search): void {
foreach ($fields as $field) {
$query->orWhere($field, 'like', '%' . $search . '%');
$query->where(function (Builder $query) use ($fields, $search): void {
foreach ($fields as $index => $field) {
if (! is_numeric($index)) {
$query->orWhereHas($index, function ($query) use ($field, $search): void {
$query->where(function ($query) use ($field, $search): void {
foreach ($field as $relatedField) {
$query->orWhere($relatedField, 'like', '%' . $search . '%');
}
});
});
} else {
$query->orWhere($field, 'like', '%' . $search . '%');
}
}
});
}
Expand Down
135 changes: 135 additions & 0 deletions app/Http/Controllers/Table/AlertLogController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace App\Http\Controllers\Table;

use App\Http\Formatters\AlertLogDetailFormatter;
use App\Models\AlertLog;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use LibreNMS\Util\Html;
use LibreNMS\Util\Url;

class AlertLogController extends TableController
{
protected $default_sort = ['time_logged' => 'asc'];

public function __construct(
private readonly AlertLogDetailFormatter $formatter
) {
}

protected function rules()
{
return [
'severity' => 'array|nullable',
'severity.*' => 'integer',
'device_id' => 'integer|nullable',

];
}

protected function sortFields($request)
{
return [
'time_logged',
'status' => 'state',
'alert_rule' => 'name',
'severity',
'hostname',
];
}

protected function searchFields(Request $request)
{
return [
'device' => ['hostname', 'sysname'],
'rule' => ['name'],
// 'time_logged', // how would this be useful? removed
];
}

protected function filterFields(Request $request)
{
return [
'alert_log.device_id' => 'device_id',
'severity' => function (Builder $q, ?array $severity): void {
if ($severity) {
$q->whereHas('rule', fn ($q) => $q->whereIn('severity', array_map(intval(...), $severity)));
}
},
'state',
];
}

/**
* @inheritDoc
*/
protected function baseQuery(Request $request)
{
$query = AlertLog::query()
->select('alert_log.*')
->with(['device', 'rule'])
->hasAccess($request->user());

$sort = $request->get('sort');
if (isset($sort['severity']) || isset($sort['alert_rule'])) {
$query->leftJoin('alert_rules', 'alert_log.rule_id', '=', 'alert_rules.id');
}
if (isset($sort['hostname'])) {
$query->leftJoin('devices', 'alert_log.device_id', '=', 'devices.device_id');
}

return $query;
}

/**
* @param AlertLog $model
* @return array
*/
public function formatItem($model): array
{
$fault_detail = $this->formatter->format($model->details);

Check failure on line 91 in app/Http/Controllers/Table/AlertLogController.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Access to an undefined property App\Models\AlertLog::$details.
$status = Html::severityToLabel($model->state->asSeverity(), title: $model->state->name, class: 'alert-status');

return [
'id' => $model->id,
'time_logged' => $model->time_logged,
'details' => '<a class="fa fa-plus incident-toggle" style="display:none" data-toggle="collapse" data-target="#incident' . $model->id . '" data-parent="#alerts"></a>',
'verbose_details' => "<button type='button' class='btn btn-alert-details verbose-alert-details' style='display:none' aria-label='Details' id='alert-details' data-alert_log_id='$model->id'><i class='fa-solid fa-circle-info'></i></button>",
'hostname' => '<div class="incident">' . Url::modernDeviceLink($model->device) . '<div id="incident' . $model->id . '" class="collapse">' . $fault_detail . '</div></div>',
'alert_rule' => $model->rule?->name,
'status' => $status,
'severity' => $model->rule?->severity,
];
}

protected function getExportHeaders(): array
{
return [
'id',
'state',
'time_logged',
'device_id',
'device',
'rule_id',
'rule_name',
'rule_severity',
'details',
];
}

protected function formatExportRow($item): array
{
return [
$item->id,
strtolower((string) $item->state->name),
$item->time_logged->toIso8601ZuluString(),
$item->device_id,
$item->device?->displayName(),
$item->rule_id,
$item->rule?->name,
$item->rule?->severity,
json_encode($item->details),
];
}
}
Loading
Loading