Skip to content

Commit

Permalink
add: stats, local dates, bootstrap 5
Browse files Browse the repository at this point in the history
  • Loading branch information
ulcuber committed Dec 1, 2024
1 parent a86d41a commit e3514c6
Show file tree
Hide file tree
Showing 19 changed files with 571 additions and 772 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,17 @@ Feel free to check out the [releases](https://github.com/ulcuber/LogViewer/relea
- Logs menu/tree generator.
- Grouped logs by dates and levels.
- Customized log levels icons (bootstrap icons by default).
- Works great with big logs
- Works great with big logs.
- Well documented package (IDE Friendly).
- Well tested
- Any date format
- Custom regex to parse extra params
- Well optimized
- Could be balanced between Memory/CPU consumption
- Filters for any parsed params
- Search for similar log entries
- Well tested.
- Any date format.
- Local dates displayed (in browser timezone).
- Custom regex to parse extra params.
- Well optimized.
- Could be balanced between Memory/CPU consumption.
- Filters for any parsed params.
- Search for [similar](https://www.php.net/manual/en/function.similar-text.php) log entries.
- Logs context stats.

## Table of contents

Expand Down
4 changes: 2 additions & 2 deletions config/log-viewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@
| Theme
| -----------------------------------------------------------------
| Supported themes :
| 'bootstrap-4'
| 'bootstrap-5'
| Make your own theme by adding a folder to the views directory and specifying it here.
*/

'theme' => 'bootstrap-4',
'theme' => 'bootstrap-5',

/* -----------------------------------------------------------------
| Route settings
Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'header' => 'Header',
'download' => 'Download',
'delete' => 'Delete',
'stats' => 'Stats',
'info-actions' => 'Info/Actions',
'levels' => 'Levels',
'log-info' => 'Log info:',
Expand Down
1 change: 1 addition & 0 deletions resources/lang/ru/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'header' => 'Заголовок',
'download' => 'Скачать',
'delete' => 'Удалить',
'stats' => 'Статистика',
'info-actions' => 'Инфо/Действия',
'levels' => 'Уровни',
'log-info' => 'Информация о журнале:',
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<meta name="author" content="ARCANEDEV">
<title>LogViewer - Created by ARCANEDEV</title>
{{-- Styles --}}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" integrity="sha384-b6lVK+yci+bfDmaY1u0zE8YYJt0TZxLEAFyYSLHId4xoVvsrQu3INevFKo+Xir8e" crossorigin="anonymous">
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700|Source+Sans+Pro:400,600' rel='stylesheet' type='text/css'>
@include('log-viewer::bootstrap-4._styles')
@include('log-viewer::bootstrap-5._styles')
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark sticky-top bg-dark p-0">
Expand Down Expand Up @@ -56,7 +56,10 @@
<footer class="main-footer">
<div class="container-fluid d-flex flex-wrap justify-content-between">
<p class="text-muted">
LogViewer - <span class="badge badge-info">version {{ log_viewer()->version() }}</span>
<a href="https://github.com/ulcuber/LogViewer/tree/v9.x">
<i class="bi bi-github"></i>
LogViewer
</a> - <span class="badge text-bg-info">version {{ log_viewer()->version() }}</span>
</p>
<p class="text-muted">
{{ log_viewer()->memoryString() }}
Expand All @@ -69,10 +72,38 @@

{{-- Scripts --}}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
{{-- with popper --}}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>

<script>
$(() => {
const locale = undefined;
const dateTimeFormat = new Intl.DateTimeFormat(locale, {
dateStyle: 'short',
timeStyle: 'short',
});
const timeFormat = new Intl.DateTimeFormat(locale, {
timeStyle: 'short',
});
function local(selector, formatter) {
const elements = document.querySelectorAll(selector);
const dates = Array.from(elements);
el = dates.pop();
while (el) {
el.textContent = formatter.format(
new Date(el.getAttribute('datetime'))
);
el = dates.pop();
}
}
local('time.datetime', dateTimeFormat);
local('time.time', timeFormat);
});
</script>

@yield('modals')
@yield('scripts')
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,62 +134,62 @@
* Colors: Badge & Infobox
*/
.badge.badge-env,
.badge.badge-level-all,
.badge.badge-level-emergency,
.badge.badge-level-alert,
.badge.badge-level-critical,
.badge.badge-level-error,
.badge.badge-level-warning,
.badge.badge-level-notice,
.badge.badge-level-info,
.badge.badge-level-debug,
.badge.text-bg-env,
.badge.text-bg-level-all,
.badge.text-bg-level-emergency,
.badge.text-bg-level-alert,
.badge.text-bg-level-critical,
.badge.text-bg-level-error,
.badge.text-bg-level-warning,
.badge.text-bg-level-notice,
.badge.text-bg-level-info,
.badge.text-bg-level-debug,
.badge.empty {
color: #FFF;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);
}
.badge.badge-level-all,
.badge.text-bg-level-all,
.box.level-all {
background-color: {{ log_styler()->color('all') }};
}
.badge.badge-level-emergency,
.badge.text-bg-level-emergency,
.box.level-emergency {
background-color: {{ log_styler()->color('emergency') }};
}
.badge.badge-level-alert,
.badge.text-bg-level-alert,
.box.level-alert {
background-color: {{ log_styler()->color('alert') }};
}
.badge.badge-level-critical,
.badge.text-bg-level-critical,
.box.level-critical {
background-color: {{ log_styler()->color('critical') }};
}
.badge.badge-level-error,
.badge.text-bg-level-error,
.box.level-error {
background-color: {{ log_styler()->color('error') }};
}
.badge.badge-level-warning,
.badge.text-bg-level-warning,
.box.level-warning {
background-color: {{ log_styler()->color('warning') }};
}
.badge.badge-level-notice,
.badge.text-bg-level-notice,
.box.level-notice {
background-color: {{ log_styler()->color('notice') }};
}
.badge.badge-level-info,
.badge.text-bg-level-info,
.box.level-info {
background-color: {{ log_styler()->color('info') }};
}
.badge.badge-level-debug,
.badge.text-bg-level-debug,
.box.level-debug {
background-color: {{ log_styler()->color('debug') }};
}
Expand All @@ -203,11 +203,11 @@
background-color: {{ log_styler()->color('empty') }};
}
.badge.badge-env {
.badge.text-bg-env {
background-color: #6A1B9A;
}
@foreach (log_styler()->extraColors() as $key => $color)
.badge.badge-extra-{{ $key }} {
.badge.text-bg-extra-{{ $key }} {
background-color: {{ $color }};
}
@endforeach
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@extends('log-viewer::bootstrap-4._master')
@extends('log-viewer::bootstrap-5._master')

@section('content')
<div class="page-header mb-4">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
@extends('log-viewer::bootstrap-4._master')

<?php /** @var Illuminate\Pagination\LengthAwarePaginator $rows */ ?>
@extends('log-viewer::bootstrap-5._master')

@section('content')
<div class="page-header mb-4">
Expand All @@ -14,9 +12,9 @@
@foreach($headers as $key => $header)
<th scope="col" class="text-center">
@if ($key == 'date' || $key == 'prefix')
<span class="badge badge-info">{{ $header }}</span>
<span class="badge text-bg-info">{{ $header }}</span>
@else
<span class="badge badge-level-{{ $key }}">
<span class="badge text-bg-level-{{ $key }}">
{{ log_styler()->icon($key) }}
</span>
@endif
Expand All @@ -32,21 +30,21 @@
@foreach($row as $key => $value)
<td class="text-center">
@if ($key == 'date')
<a href="{{ route('log-viewer::logs.list', compact('date')) }}"><span class="badge badge-primary">{{ $value }}</span></a>
<a href="{{ route('log-viewer::logs.list', compact('date')) }}"><span class="badge text-bg-primary">{{ $value }}</span></a>
@elseif ($key == 'prefix')
<a href="{{ route('log-viewer::logs.list', ['prefix' => $value]) }}"><span class="badge badge-primary">{{ $value }}</span></a>
<a href="{{ route('log-viewer::logs.list', ['prefix' => $value]) }}"><span class="badge text-bg-primary">{{ $value }}</span></a>
@elseif ($value == 0)
<span class="badge empty">{{ $value }}</span>
@else
<a href="{{ route('log-viewer::logs.show', ['prefix' => $prefix, 'date' => $date, 'level' => $key]) }}">
<span class="badge badge-level-{{ $key }}">{{ $value }}</span>
<a href="{{ route('log-viewer::logs.show', ['prefix' => $prefix, 'date' => $date, 'level' => $key === 'all' ? null : $key]) }}">
<span class="badge text-bg-level-{{ $key }}">{{ $value }}</span>
</a>
@endif
</td>
@endforeach
<td class="text-right">
<a href="{{ route('log-viewer::logs.show', [$prefix, $date]) }}" class="btn btn-sm btn-info">
<i class="bi bi-search"></i>
<i class="bi bi-eye"></i>
</a>
<a href="{{ route('log-viewer::logs.download', [$prefix, $date]) }}" class="btn btn-sm btn-success">
<i class="bi bi-download"></i>
Expand All @@ -60,7 +58,7 @@
@empty
<tr>
<td colspan="11" class="text-center">
<span class="badge badge-secondary">{{ trans('log-viewer::general.empty-logs') }}</span>
<span class="badge text-bg-secondary">{{ trans('log-viewer::general.empty-logs') }}</span>
</td>
</tr>
@endforelse
Expand Down Expand Up @@ -114,7 +112,7 @@
deleteLogForm.find('input[name=prefix]').val(prefix);
deleteLogForm.find('input[name=date]').val(date);
deleteLogModal.find('.modal-body p').html(
'Are you sure you want to <span class="badge badge-danger">DELETE</span> this log file <span class="badge badge-secondary">' + prefix + '</span> <span class="badge badge-primary">' + date + '</span> ?'
'Are you sure you want to <span class="badge text-bg-danger">DELETE</span> this log file <span class="badge text-bg-secondary">' + prefix + '</span> <span class="badge text-bg-primary">' + date + '</span> ?'
);
deleteLogModal.modal('show');
Expand Down
98 changes: 98 additions & 0 deletions resources/views/bootstrap-5/show.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
@extends('log-viewer::bootstrap-5._log')

@section('section')
<div class="card mb-4">
@if ($entries->hasPages())
<div class="card-header">
<span class="badge text-bg-info float-right">
{{ trans('log-viewer::general.page') }} {{ $entries->currentPage() }} {{ trans('log-viewer::general.of') }} {{ method_exists($entries, 'lastPage') ? $entries->lastPage() : 'N' }}
</span>
</div>
@endif

<div class="table-responsive">
<table id="entries" class="table mb-0">
<thead>
<tr>
<th>{{ trans('log-viewer::general.info-actions') }}</th>
<th>{{ trans('log-viewer::general.header') }}</th>
</tr>
</thead>
<tbody>
@forelse($entries as $key => $entry)
<tr>
<td>
@foreach ($entry->extra as $propName => $extra)
<a class="badge text-bg-env text-bg-extra-{{ $propName }}" href="{{ route('log-viewer::logs.show', array_merge(request()->input(), ['prefix' => $log->prefix, 'date' => $log->date, $propName => $extra])) }}">
{{ $extra }}
</a>
@endforeach
<span class="badge text-bg-env">{{ $entry->env }}</span>
<span class="badge text-bg-level-{{ $entry->level }}">
{!! $entry->level() !!}
</span>
<span class="badge text-bg-secondary">
<time
class="time"
datetime="{{ $entry->getDatetime()->format('Y-m-d\TH:i:s') . ".000Z" }}"
>{{ $entry->getDatetime()->toTimeString() }}</time>
</span>

<br/>

<div class="btn-group">
<a class="btn btn-sm btn-light" href="{{ route('log-viewer::logs.show', ['prefix' => $log->prefix, 'date' => $log->date, 'level' => $entry->level, 'search' => $entry->header, 'fuzzy' => true]) }}">{{ trans('log-viewer::general.similar') }}</a>
@if (!request('search'))
<a class="btn btn-sm btn-light" href="{{ route($route, array_merge($filters, ['exclude_similar' => array_merge($filters['exclude_similar'] ?? [], [$entry->header])])) }}">{{ trans('log-viewer::general.exclude-similar') }}</a>
@endif
</div>

@if ($entry->hasContext())
<a class="btn btn-sm btn-light" role="button" data-bs-toggle="collapse"
href="#log-context-{{ $key }}" aria-expanded="false" aria-controls="log-context-{{ $key }}">
<i class="bi bi-toggle-on"></i> Context
</a>
@endif

@if ($entry->hasStack())
<a class="btn btn-sm btn-light" role="button" data-bs-toggle="collapse"
href="#log-stack-{{ $key }}" aria-expanded="false" aria-controls="log-stack-{{ $key }}">
<i class="bi bi-toggle-on"></i> Stack
</a>
@endif
</td>
<td>
{{ $entry->header }}
</td>
</tr>
@if ($entry->hasStack() || $entry->hasContext())
<tr>
<td colspan="5" class="stack py-0">
@if ($entry->hasContext())
<div class="stack-content collapse" id="log-context-{{ $key }}">
<pre>{{ $entry->context() }}</pre>
</div>
@endif

@if ($entry->hasStack())
<div class="stack-content collapse" id="log-stack-{{ $key }}">
{!! $entry->stack() !!}
</div>
@endif
</td>
</tr>
@endif
@empty
<tr>
<td colspan="5" class="text-center">
<span class="badge text-bg-secondary">{{ trans('log-viewer::general.empty-logs') }}</span>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>

{!! $entries->appends(compact('search'))->render(method_exists($entries, 'total') ? 'pagination::bootstrap-5' : 'pagination::simple-bootstrap-5') !!}
@endsection
Loading

0 comments on commit e3514c6

Please sign in to comment.