diff --git a/app/ApiClients/GraylogApi.php b/app/ApiClients/GraylogApi.php index cc337260f123..3f9d55fcd4c6 100644 --- a/app/ApiClients/GraylogApi.php +++ b/app/ApiClients/GraylogApi.php @@ -66,10 +66,16 @@ public function getStreams(): array } /** - * Query the Graylog server + * Query the Graylog server relative time */ - public function query(string $query = '*', int $range = 0, int $limit = 0, int $offset = 0, ?string $sort = null, ?string $filter = null): array - { + public function queryRelative( + string $query = '*', + int $range = 0, + int $limit = 0, + int $offset = 0, + ?string $sort = null, + ?string $filter = null + ): array { if (! $this->isConfigured()) { return []; } @@ -93,6 +99,39 @@ public function query(string $query = '*', int $range = 0, int $limit = 0, int $ return $response->json() ?: []; } + /** + * Query the Graylog server absolute time + */ + public function queryAbsolute( + string $query = '*', + string $from = '', + string $to = '', + int $limit = 0, + int $offset = 0, + ?string $sort = null, + ?string $filter = null + ): array { + if (! $this->isConfigured()) { + return []; + } + + $uri = $this->api_prefix . '/search/universal/absolute'; + + $data = [ + 'query' => $query, + 'from' => $from, + 'to' => $to, + 'limit' => $limit, + 'offset' => $offset, + 'sort' => $sort, + 'filter' => $filter, + ]; + + $response = $this->client->get($uri, $data)->throw(); + + return $response->json() ?: []; + } + /** * Build a simple query string that searches the messages field and/or filters by device */ diff --git a/app/Http/Controllers/Device/Tabs/EventlogController.php b/app/Http/Controllers/Device/Tabs/EventlogController.php index ed95f681df9e..ac5f5464b3a7 100644 --- a/app/Http/Controllers/Device/Tabs/EventlogController.php +++ b/app/Http/Controllers/Device/Tabs/EventlogController.php @@ -26,9 +26,11 @@ namespace App\Http\Controllers\Device\Tabs; +use App\Facades\LibrenmsConfig; use App\Http\Controllers\Controller; use App\Models\Device; use Illuminate\Http\Request; +use Illuminate\Support\Carbon; use Illuminate\View\View; class EventlogController extends Controller @@ -37,12 +39,33 @@ public function __invoke(Device $device, Request $request): View { $request->validate([ 'eventtype' => 'nullable|string', + 'device' => 'nullable|int', + 'from' => 'nullable|string', + 'to' => 'nullable|string', ]); + $eventlog_filter = [ + 'field' => 'type', + 'device' => $device->device_id, + ]; + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(7); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } return view('device.tabs.logs.eventlog', [ - 'device' => $device, - 'filter_device' => false, + 'now' => $now->format($format), + 'default_date' => $defaultFrom->format($format), 'eventtype' => $request->input('eventtype', ''), + 'from' => $fromInput, + 'to' => $toInput, + 'device' => $device, + 'eventlog_filter' => $eventlog_filter, ]); } } diff --git a/app/Http/Controllers/Device/Tabs/GraylogController.php b/app/Http/Controllers/Device/Tabs/GraylogController.php index 3a79d3556c50..0c5d485b85c7 100644 --- a/app/Http/Controllers/Device/Tabs/GraylogController.php +++ b/app/Http/Controllers/Device/Tabs/GraylogController.php @@ -29,6 +29,7 @@ use App\Facades\LibrenmsConfig; use App\Http\Controllers\Controller; use App\Models\Device; +use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\View\View; @@ -40,7 +41,24 @@ public function __invoke(Device $device, Request $request): View 'stream' => 'nullable|string', 'range' => 'nullable|int', 'loglevel' => 'nullable|int', + 'to' => 'nullable|string', + 'level' => 'nullable|string', ]); + $graylog_filter = [ + 'field' => 'stream', + 'device' => $device->device_id, + ]; + + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(7); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } return view('device.tabs.logs.graylog', [ 'device' => $device, @@ -50,6 +68,11 @@ public function __invoke(Device $device, Request $request): View 'stream' => $request->input('stream', ''), 'range' => $request->input('range', '0'), 'loglevel' => $request->input('loglevel', ''), + 'from' => $fromInput, + 'to' => $toInput, + 'default_date' => $defaultFrom->format($format), + 'now' => $now->format($format), + 'graylog_filter' => $graylog_filter, ]); } } diff --git a/app/Http/Controllers/Device/Tabs/SyslogController.php b/app/Http/Controllers/Device/Tabs/SyslogController.php index fa2751f42e4f..998a87a8189d 100644 --- a/app/Http/Controllers/Device/Tabs/SyslogController.php +++ b/app/Http/Controllers/Device/Tabs/SyslogController.php @@ -40,19 +40,41 @@ public function __invoke(Device $device, Request $request): View $request->validate([ 'program' => 'nullable|string', 'priority' => 'nullable|string', + 'device' => 'nullable|int', 'from' => 'nullable|string', 'to' => 'nullable|string', + 'level' => 'nullable|string', ]); + $syslog_program_filter = [ + 'field' => 'program', + 'device' => $device->device_id, + ]; + $syslog_priority_filter = [ + 'field' => 'priority', + 'device' => $device->device_id, + ]; + + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(7); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } return view('device.tabs.logs.syslog', [ 'device' => $device, - 'filter_device' => false, - 'now' => Carbon::now()->format(LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i')), - 'default_date' => Carbon::now()->subDay()->format(LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i')), + 'now' => $now->format($format), + 'default_date' => $defaultFrom->format($format), 'program' => $request->input('program', ''), 'priority' => $request->input('priority', ''), - 'from' => $request->input('from', ''), - 'to' => $request->input('to', ''), + 'from' => $fromInput, + 'to' => $toInput, + 'syslog_program_filter' => $syslog_program_filter, + 'syslog_priority_filter' => $syslog_priority_filter, ]); } } diff --git a/app/Http/Controllers/EventlogController.php b/app/Http/Controllers/EventlogController.php new file mode 100644 index 000000000000..87139770e2c6 --- /dev/null +++ b/app/Http/Controllers/EventlogController.php @@ -0,0 +1,57 @@ +validate($request, [ + 'eventtype' => 'nullable|string', + 'device' => 'nullable|int', + 'from' => 'nullable|string', + 'to' => 'nullable|string', + ]); + + $device = \App\Models\Device::hasAccess($request->user()) + ->select(['device_id', 'hostname', 'ip', 'sysName', 'display']) + ->firstWhere('device_id', $request->input('device')); + + $eventlog_filter = ['field' => 'type']; + $device_selected = ''; + if ($device) { + $device_selected = ['id' => $device->device_id, 'text' => $device->displayName()]; + $eventlog_filter['device'] = $device->device_id; + } + + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(1); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } + return view('eventlog', [ + 'device' => $device_selected, + 'filter' => [ + 'now' => $now->format($format), + 'default_date' => $defaultFrom->format($format), + 'eventtype' => $request->input('eventtype', ''), + 'from' => $fromInput, + 'to' => $toInput, + 'device' => $device?->device_id, + ], + 'eventlog_filter' => $eventlog_filter, + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/GraylogController.php b/app/Http/Controllers/GraylogController.php new file mode 100644 index 000000000000..8ebbaaee563d --- /dev/null +++ b/app/Http/Controllers/GraylogController.php @@ -0,0 +1,64 @@ +validate([ + 'stream' => 'nullable|string', + 'device' => 'nullable|int', + 'range' => 'nullable|int', + 'loglevel' => 'nullable|int', + 'to' => 'nullable|string', + 'level' => 'nullable|string', + ]); + + $device = \App\Models\Device::hasAccess($request->user()) + ->select(['device_id', 'hostname', 'ip', 'sysName', 'display']) + ->firstWhere('device_id', $request->input('device')); + + $graylog_filter = ['field' => 'stream',]; + $device_selected = ''; + if ($device) { + $device_selected = ['id' => $device->device_id, 'text' => $device->displayName()]; + $graylog_filter['device'] = $device->device_id; + } + + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(1); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } + + return view('graylog', [ + 'device' => $device_selected, + 'filter' => [ + 'timezone' => LibrenmsConfig::has('graylog.timezone'), + 'filter_device' => true, + 'show_form' => true, + 'stream' => $request->input('stream', ''), + 'range' => $request->input('range', '0'), + 'loglevel' => $request->input('loglevel', ''), + 'from' => $fromInput, + 'to' => $toInput, + 'default_date' => $defaultFrom->format($format), + 'now' => $now->format($format), + ], + 'graylog_filter' => $graylog_filter, + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/SyslogController.php b/app/Http/Controllers/SyslogController.php new file mode 100644 index 000000000000..cfbdacbda702 --- /dev/null +++ b/app/Http/Controllers/SyslogController.php @@ -0,0 +1,65 @@ +validate([ + 'program' => 'nullable|string', + 'priority' => 'nullable|string', + 'device' => 'nullable|int', + 'from' => 'nullable|string', + 'to' => 'nullable|string', + 'level' => 'nullable|string', + ]); + + $device = \App\Models\Device::hasAccess($request->user()) + ->select(['device_id', 'hostname', 'ip', 'sysName', 'display']) + ->firstWhere('device_id', $request->input('device')); + + $syslog_program_filter = ['field' => 'program']; + $syslog_priority_filter = ['field' => 'priority']; + $device_selected = ''; + if ($device) { + $device_selected = ['id' => $device->device_id, 'text' => $device->displayName()]; + $syslog_program_filter['device'] = $device->device_id; + $syslog_priority_filter['device'] = $device->device_id; + } + + $format = LibrenmsConfig::get('dateformat.byminute', 'Y-m-d H:i'); + $now = Carbon::now(); + $defaultFrom = (clone $now)->subDays(1); + $fromInput = $request->input('from'); + $toInput = $request->input('to'); + + if (empty($fromInput) && empty($toInput)) { + $fromInput = $defaultFrom->format($format); + $toInput = $now->format($format); + } + + return view('syslog', [ + 'device' => $device_selected, + 'filter' => [ + 'device' => $device, + 'filter_device' => false, + 'now' => $now->format($format), + 'default_date' => $defaultFrom->format($format), + 'program' => $request->input('program', ''), + 'priority' => $request->input('priority', ''), + 'from' => $fromInput, + 'to' => $toInput, + ], + 'syslog_program_filter' => $syslog_program_filter, + 'syslog_priority_filter' => $syslog_priority_filter, + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Table/EventlogController.php b/app/Http/Controllers/Table/EventlogController.php index 2b57f995110f..f98de3626601 100644 --- a/app/Http/Controllers/Table/EventlogController.php +++ b/app/Http/Controllers/Table/EventlogController.php @@ -41,12 +41,14 @@ public function rules() 'device' => 'nullable|int', 'device_group' => 'nullable|int', 'eventtype' => 'nullable|string', + 'to' => 'nullable|date', + 'from' => 'nullable|date', ]; } public function searchFields($request) { - return ['message']; + return ['type', 'message', 'username']; } protected function filterFields($request) @@ -59,7 +61,7 @@ protected function filterFields($request) protected function sortFields($request) { - return ['datetime', 'type', 'device_id', 'message', 'username']; + return ['label', 'datetime', 'type', 'device_id', 'message', 'username']; } /** @@ -74,6 +76,12 @@ public function baseQuery($request) ->with('device') ->when($request->device_group, function ($query) use ($request): void { $query->inDeviceGroup($request->device_group); + }) + ->when($request->from, function ($query, $from): void { + $query->where('datetime', '>=', $from); + }) + ->when($request->to, function ($query, $to): void { + $query->where('datetime', '<=', $to); }); } @@ -83,7 +91,10 @@ public function baseQuery($request) public function formatItem($eventlog) { return [ - 'datetime' => $this->formatDatetime($eventlog), + 'label' => $this->setLabel($eventlog), + 'datetime' => (new Carbon($eventlog->datetime)) + ->setTimezone(session('preferences.timezone')) + ->format(LibrenmsConfig::get('dateformat.compact')), 'device_id' => Blade::render('', ['device' => $eventlog->device]), 'type' => $this->formatType($eventlog), 'message' => htmlspecialchars((string) $eventlog->message), @@ -114,12 +125,12 @@ private function formatType($eventlog) return htmlspecialchars((string) $eventlog->type); } - private function formatDatetime($eventlog) + private function setLabel($eventlog) { $output = ""; - $output .= (new Carbon($eventlog->datetime))->setTimezone(session('preferences.timezone'))->format(LibrenmsConfig::get('dateformat.compact')); + $output .= "'>"; + $output .= ''; return $output; } @@ -139,4 +150,36 @@ private function severityLabel($eventlog_severity) default => 'label-default', // Unknown }; } -} + + /** + * Get headers for CSV export + * + * @return array + */ + protected function getExportHeaders() + { + return [ + 'Timestamp', + 'Device', + 'Type', + 'Message', + 'User', + ]; + } + /** + * Format a row for CSV export + * + * @param EventLog $eventlog + * @return array + */ + protected function formatExportRow($eventlog) + { + return [ + Carbon::createFromTimestamp($eventlog->datetime)->toISOString(), + $eventlog->device ? $eventlog->device->displayName() : '', + $eventlog->type, + (string) $eventlog->message, + $eventlog->username ?: 'System', + ]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Table/GraylogController.php b/app/Http/Controllers/Table/GraylogController.php index aca7007910f0..f54e82053bc7 100644 --- a/app/Http/Controllers/Table/GraylogController.php +++ b/app/Http/Controllers/Table/GraylogController.php @@ -28,9 +28,8 @@ use App\ApiClients\GraylogApi; use App\Facades\LibrenmsConfig; +use Carbon\Carbon; use App\Models\Device; -use DateInterval; -use DateTime; use DateTimeZone; use Illuminate\Http\Request; use Illuminate\Support\Facades\Blade; @@ -59,6 +58,8 @@ public function __invoke(Request $request, GraylogApi $api) 'device' => 'nullable|int', 'range' => 'nullable|int', 'loglevel' => 'nullable|int|min:0|max:7', + 'from' => 'nullable|date_format:Y-m-d H:i', + 'to' => 'nullable|date_format:Y-m-d H:i', ]); $search = $request->get('searchPhrase'); @@ -70,8 +71,20 @@ public function __invoke(Request $request, GraylogApi $api) $offset = (int) (($page - 1) * $limit); $loglevel = $request->get('loglevel') ?? LibrenmsConfig::get('graylog.loglevel'); + $from = null; + $to = null; + $fromInput = $request->get('from'); + $toInput = $request->get('to'); + $userTz = $this->timezone ? $this->timezone->getName() : (session('preferences.timezone') ?: config('app.timezone')); + + + if ($range === 0 && $fromInput && $toInput) { + $from = Carbon::createFromFormat('Y-m-d H:i', (string) $fromInput, $userTz); + $to = Carbon::createFromFormat('Y-m-d H:i', (string) $toInput, $userTz); + } + $query = $api->buildSimpleQuery($search, $device) . - ($loglevel !== null ? ' AND level: <=' . $loglevel : ''); + ($loglevel !== null ? ' AND level:[0 TO ' . (int) $loglevel . ']' : ''); $sort = null; foreach ($request->get('sort', []) as $field => $direction) { @@ -82,7 +95,22 @@ public function __invoke(Request $request, GraylogApi $api) $filter = $stream ? "streams:$stream" : null; try { - $data = $api->query($query, $range, $limit, $offset, $sort, $filter); + if ($from && $to) { + $fromUtc = $from->clone()->setTimezone('UTC')->format('Y-m-d\TH:i:s.v\Z'); + $toUtc = $to->clone()->setTimezone('UTC')->format('Y-m-d\TH:i:s.v\Z'); + + $data = $api->queryAbsolute( + $query, + $fromUtc, + $toUtc, + $limit, + $offset, + $sort, + $filter + ); + } else { + $data = $api->queryRelative($query, $range, $limit, $offset, $sort, $filter); + } $messages = $data['messages'] ?? []; return $this->formatResponse( @@ -102,16 +130,11 @@ public function __invoke(Request $request, GraylogApi $api) private function formatMessage($message) { - if ($this->timezone) { - $graylogTime = new DateTime($message['message']['timestamp']); - $offset = $this->timezone->getOffset($graylogTime); - - $timeInterval = DateInterval::createFromDateString((string) $offset . 'seconds'); - $graylogTime->add($timeInterval); - $displayTime = $graylogTime->format('Y-m-d H:i:s'); - } else { - $displayTime = $message['message']['timestamp']; - } + $displayTz = $this->timezone ? $this->timezone->getName() : (session('preferences.timezone') ?: config('app.timezone')); + + $displayTime = Carbon::parse($message['message']['timestamp']) + ->setTimezone($displayTz) + ->format(LibrenmsConfig::get('dateformat.compact')); $level = $message['message']['level'] ?? ''; $facility = $message['message']['facility'] ?? ''; diff --git a/app/Http/Controllers/Table/SyslogController.php b/app/Http/Controllers/Table/SyslogController.php index a1134a0bbf40..bbf4958106ee 100644 --- a/app/Http/Controllers/Table/SyslogController.php +++ b/app/Http/Controllers/Table/SyslogController.php @@ -26,7 +26,9 @@ namespace App\Http\Controllers\Table; +use App\Facades\LibrenmsConfig; use App\Models\Syslog; +use Carbon\Carbon; use Illuminate\Support\Facades\Blade; use LibreNMS\Enum\SyslogSeverity; @@ -36,7 +38,6 @@ public function rules() { return [ 'device' => 'nullable|int', - 'device_group' => 'nullable|int', 'program' => 'nullable|string', 'priority' => 'nullable|string', 'to' => 'nullable|date', @@ -47,7 +48,7 @@ public function rules() public function searchFields($request) { - return ['msg']; + return ['program', 'msg']; } public function filterFields($request) @@ -100,7 +101,9 @@ public function formatItem($syslog) { return [ 'label' => $this->setLabel($syslog), - 'timestamp' => $syslog->timestamp, + 'timestamp' => (new Carbon($syslog->timestamp)) + ->setTimezone(session('preferences.timezone')) + ->format(LibrenmsConfig::get('dateformat.compact')), 'level' => htmlentities((string) $syslog->level), 'device_id' => Blade::render('', ['device' => $syslog->device]), 'program' => htmlentities((string) $syslog->program), @@ -137,6 +140,30 @@ private function priorityLabel($syslog_priority) default => '', }; } - - // end syslog_priority + protected function getExportHeaders() + { + return [ + 'Timestamp', + 'Level', + 'Device', + 'Program', + 'Message', + ]; + } + /** + * Format a row for CSV export + * + * @param Syslog $syslog + * @return array + */ + protected function formatExportRow($syslog) + { + return [ + Carbon::createFromTimestamp($syslog->timestamp)->toISOString(), + $syslog->priority, + $syslog->device ? $syslog->device->displayName() : '', + (string) $syslog->program, + (string) $syslog->msg, + ]; + } } diff --git a/html/js/librenms.js b/html/js/librenms.js index 2bfd1b66006a..f8c45ef1e52f 100644 --- a/html/js/librenms.js +++ b/html/js/librenms.js @@ -244,6 +244,11 @@ $(document).on('initialized.rs.jquery.bootgrid', function (e, b) { var grid = $(e.target); var tableId = grid.attr('id'); + // Allow per-table opt-out via data-export="false" + if (grid.data('export') === false) { + return; + } + if ($('#' + tableId + '-export-button').length === 0) { var ajaxUrl = grid.data('url'); var params = grid.data('params'); diff --git a/includes/html/common/eventlog.inc.php b/includes/html/common/eventlog.inc.php deleted file mode 100644 index 60814334b928..000000000000 --- a/includes/html/common/eventlog.inc.php +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - -
TimestampTypeHostnameMessageUser
- - -'; diff --git a/includes/html/common/graylog.inc.php b/includes/html/common/graylog.inc.php deleted file mode 100644 index 611daa1f9ba3..000000000000 --- a/includes/html/common/graylog.inc.php +++ /dev/null @@ -1,153 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. Please see LICENSE.txt at the top level of - * the source code distribution for details. - * - * @package LibreNMS - * @subpackage webui - * @link https://www.librenms.org - * @copyright 2017 LibreNMS - * @author LibreNMS Contributors -*/ - -use App\Models\Device; - -if (empty($results_limit)) { - $results_limit = 25; -} -$tmp_output = ' - -
- - - - - - - - - - - - -
OriginTimestampLevelSourceMessageFacility
-
- - - -'; - -$common_output[] = $tmp_output; diff --git a/includes/html/common/syslog.inc.php b/includes/html/common/syslog.inc.php deleted file mode 100644 index c8e21f9d5150..000000000000 --- a/includes/html/common/syslog.inc.php +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - -
TimestampLevelHostnameProgramMessagePriority
- - -'; diff --git a/includes/html/pages/eventlog.inc.php b/includes/html/pages/eventlog.inc.php deleted file mode 100644 index 3797d9453a15..000000000000 --- a/includes/html/pages/eventlog.inc.php +++ /dev/null @@ -1,111 +0,0 @@ - - -
-
- Eventlog -
- - -
- - diff --git a/includes/html/pages/graylog.inc.php b/includes/html/pages/graylog.inc.php deleted file mode 100644 index 7eac9ef9d889..000000000000 --- a/includes/html/pages/graylog.inc.php +++ /dev/null @@ -1,29 +0,0 @@ - -
- Graylog entries -
'; - -require_once 'includes/html/common/graylog.inc.php'; -echo implode('', $common_output); - -echo ''; diff --git a/includes/html/pages/syslog.inc.php b/includes/html/pages/syslog.inc.php deleted file mode 100644 index ca7ef5c4f143..000000000000 --- a/includes/html/pages/syslog.inc.php +++ /dev/null @@ -1,196 +0,0 @@ -hasGlobalAdmin()) { - \App\Models\Syslog::truncate(); - print_message('syslog truncated'); -} - -$pagetitle[] = 'Syslog'; -?> -
-
- Syslog -
- - -
- - diff --git a/includes/html/table/eventlog.inc.php b/includes/html/table/eventlog.inc.php deleted file mode 100644 index fc9a5bfed19a..000000000000 --- a/includes/html/table/eventlog.inc.php +++ /dev/null @@ -1,105 +0,0 @@ -hasGlobalRead()) { - $sql = " FROM `eventlog` AS E LEFT JOIN `devices` AS `D` ON `E`.`device_id`=`D`.`device_id` WHERE $where"; -} else { - $sql = " FROM `eventlog` AS E, devices_perms AS P WHERE $where AND E.device_id = P.device_id AND P.user_id = ?"; - $param[] = Auth::id(); -} - -if (isset($searchPhrase) && ! empty($searchPhrase)) { - $sql .= ' AND (`D`.`hostname` LIKE ? OR `D`.`sysName` LIKE ? OR `E`.`datetime` LIKE ? OR `E`.`message` LIKE ? OR `E`.`type` LIKE ? OR `E`.`username` LIKE ?)'; - $param[] = "%$searchPhrase%"; - $param[] = "%$searchPhrase%"; - $param[] = "%$searchPhrase%"; - $param[] = "%$searchPhrase%"; - $param[] = "%$searchPhrase%"; - $param[] = "%$searchPhrase%"; -} - -$count_sql = "SELECT COUNT(event_id) $sql"; -$total = dbFetchCell($count_sql, $param); -if (empty($total)) { - $total = 0; -} - -if (! isset($sort) || empty($sort)) { - $sort = 'datetime DESC'; -} - -$sql .= " ORDER BY $sort"; - -if (isset($current)) { - $limit_low = (($current * $rowCount) - $rowCount); - $limit_high = $rowCount; -} - -if ($rowCount != -1) { - $sql .= " LIMIT $limit_low,$limit_high"; -} - -$sql = "SELECT `E`.*,DATE_FORMAT(datetime, '" . \App\Facades\LibrenmsConfig::get('dateformat.mysql.compact') . "') as humandate,severity $sql"; - -foreach (dbFetchRows($sql, $param) as $eventlog) { - $dev = device_by_id_cache($eventlog['device_id']); - if ($eventlog['type'] == 'interface') { - $this_if = cleanPort(get_port_by_id($eventlog['reference'])); - $type = '' . generate_port_link($this_if, Rewrite::shortenIfName(strtolower((string) $this_if['label']))) . ''; - } else { - $type = $eventlog['type']; - } - $severity_colour = $eventlog['severity']; - - if ($eventlog['username'] == '') { - $eventlog['username'] = 'System'; - } - - $response[] = [ - 'datetime' => "" . $eventlog['humandate'], - 'hostname' => generate_device_link($dev, shorthost($dev['hostname'])), - 'type' => $type, - 'message' => htmlspecialchars((string) $eventlog['message']), - 'username' => $eventlog['username'], - ]; -} - -$output = [ - 'current' => $current, - 'rowCount' => $rowCount, - 'rows' => $response, - 'total' => $total, -]; -echo json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); diff --git a/resources/views/device/tabs/logs/eventlog.blade.php b/resources/views/device/tabs/logs/eventlog.blade.php index 7583e21c4e99..63d4579c179d 100644 --- a/resources/views/device/tabs/logs/eventlog.blade.php +++ b/resources/views/device/tabs/logs/eventlog.blade.php @@ -6,73 +6,142 @@
- +
- - - - - + + + + +
TimestampTypeHostnameMessageUser@lang('Timestamp')@lang('Type')@lang('Message')@lang('User')
- - @if(! $filter_device) - - @endif
@endsection -@section('scripts') +@push('scripts') -@endsection +@endpush + +@push('styles') + +@endpush \ No newline at end of file diff --git a/resources/views/device/tabs/logs/graylog.blade.php b/resources/views/device/tabs/logs/graylog.blade.php index 94aac28acb3e..29f2da75fc33 100644 --- a/resources/views/device/tabs/logs/graylog.blade.php +++ b/resources/views/device/tabs/logs/graylog.blade.php @@ -6,111 +6,185 @@
- +
- - - - - - - + + + + + +
OriginTimestampLevelSourceMessageFacility@lang('Timestamp')@lang('Level')@lang('Source')@lang('Message')@lang('Facility')
- - @if(! $filter_device) - - @endif
@endsection -@section('scripts') - +@endpush - init_select2("#stream", "graylog-streams", {}, @json($stream), 'All Streams'); - init_select2("select#device", "device", {limit: 100}, "{{ $device->device_id }}", 'All Devices'); - -@endsection +@push('styles') + +@endpush diff --git a/resources/views/device/tabs/logs/syslog.blade.php b/resources/views/device/tabs/logs/syslog.blade.php index 1f49a1194df2..3fb065945a7f 100644 --- a/resources/views/device/tabs/logs/syslog.blade.php +++ b/resources/views/device/tabs/logs/syslog.blade.php @@ -6,91 +6,68 @@
- +
- - - - - - - + + + + + +
TimestampLevelHostnameProgramMessagePriority@lang('Timestamp')@lang('Level')@lang('Program')@lang('Message')@lang('Priority')
- - @if(! $filter_device) - - @endif
@endsection -@section('scripts') +@push('scripts') +@endpush + +@push('styles') + +@endpush \ No newline at end of file diff --git a/resources/views/eventlog.blade.php b/resources/views/eventlog.blade.php new file mode 100644 index 000000000000..d00be7b9c69a --- /dev/null +++ b/resources/views/eventlog.blade.php @@ -0,0 +1,155 @@ +@extends('layouts.librenmsv1') + +@section('title', __('Eventlog')) + +@section('content') +
+ + +

@lang('Eventlog')

+
+
+ + + + + + + + + + + +
@lang('Timestamp')@lang('Device')@lang('Type')@lang('Message')@lang('User')
+
+
+
+@endsection + +@push('scripts') + +@endpush + +@push('styles') + +@endpush \ No newline at end of file diff --git a/resources/views/graylog.blade.php b/resources/views/graylog.blade.php new file mode 100644 index 000000000000..cc9cf1315449 --- /dev/null +++ b/resources/views/graylog.blade.php @@ -0,0 +1,200 @@ +@extends('layouts.librenmsv1') + +@section('title', __('Graylog')) + +@section('content') +
+ + +

@lang('Graylog')

+
+
+ + + + + + + + + + + + +
@lang('Timestamp')@lang('Level')@lang('Origin')@lang('Source')@lang('Message')@lang('Facility')
+
+
+
+@endsection + +@push('scripts') + +@endpush + +@push('styles') + +@endpush \ No newline at end of file diff --git a/resources/views/layouts/menu.blade.php b/resources/views/layouts/menu.blade.php index 71c32d319d4f..a818b9852d02 100644 --- a/resources/views/layouts/menu.blade.php +++ b/resources/views/layouts/menu.blade.php @@ -82,14 +82,14 @@ class="tw:md:hidden tw:2xl:inline-block">{{ __('Overview') }} -
  • {{ __('Eventlog') }}
  • @config('enable_syslog') -
  • {{ __('syslog.title') }}
  • @endconfig @config('graylog.server') -
  • {{ __('Graylog') }}
  • @endconfig diff --git a/resources/views/syslog.blade.php b/resources/views/syslog.blade.php new file mode 100644 index 000000000000..4fd458dc036b --- /dev/null +++ b/resources/views/syslog.blade.php @@ -0,0 +1,162 @@ +@extends('layouts.librenmsv1') + +@section('title', __('Syslog')) + +@section('content') +
    + + +

    @lang('Syslog')

    +
    +
    + + + + + + + + + + + + +
    @lang('Timestamp')@lang('Level')@lang('Device')@lang('Program')@lang('Message')@lang('Priority')
    +
    +
    +
    +@endsection + +@push('scripts') + +@endpush +@push('styles') + +@endpush \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 73fbf1f6af4a..f27efa3e1b81 100644 --- a/routes/web.php +++ b/routes/web.php @@ -83,6 +83,9 @@ // pages Route::post('alert/{alert}/ack', [AlertController::class, 'ack'])->name('alert.ack'); Route::resource('device-groups', DeviceGroupController::class); + Route::any('eventlog', App\Http\Controllers\EventlogController::class)->name('eventlog'); + Route::any('syslog', App\Http\Controllers\SyslogController::class)->name('syslog'); + Route::any('graylog', App\Http\Controllers\GraylogController::class)->name('graylog'); Route::any('inventory', App\Http\Controllers\InventoryController::class)->name('inventory'); Route::get('inventory/purge', [App\Http\Controllers\InventoryController::class, 'purge'])->name('inventory.purge'); Route::get('outages', [OutagesController::class, 'index'])->name('outages'); @@ -293,6 +296,7 @@ Route::get('device/export', [Table\DeviceController::class, 'export']); Route::post('edit-ports', Table\EditPortsController::class); Route::post('eventlog', Table\EventlogController::class)->name('table.eventlog'); + Route::get('eventlog/export', [Table\EventlogController::class, 'export']); Route::post('fdb-tables', Table\FdbTablesController::class); Route::post('graylog', Table\GraylogController::class)->name('table.graylog'); Route::post('inventory', Table\InventoryController::class)->name('table.inventory'); @@ -315,6 +319,7 @@ Route::post('storages', Table\StoragesController::class)->name('table.storages'); Route::get('storages/export', [Table\StoragesController::class, 'export']); Route::post('syslog', Table\SyslogController::class)->name('table.syslog'); + Route::get('syslog/export', [Table\SyslogController::class, 'export']); Route::post('printer-supply', Table\PrinterSupplyController::class)->name('table.printer-supply'); Route::post('tnmsne', Table\TnmsneController::class)->name('table.tnmsne'); Route::post('wireless', Table\WirelessSensorController::class)->name('table.wireless');