Uploaded From CV. Swandhana Server
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Commands;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogChecker as LogCheckerContract;
|
||||
|
||||
/**
|
||||
* Class CheckCommand
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class CheckCommand extends Command
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'log-viewer:check';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Check all LogViewer requirements.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'log-viewer:check';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getter & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the Log Checker instance.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Contracts\Utilities\LogChecker
|
||||
*/
|
||||
protected function getChecker()
|
||||
{
|
||||
return $this->laravel[LogCheckerContract::class];
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->displayLogViewer();
|
||||
$this->displayRequirements();
|
||||
$this->displayMessages();
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display LogViewer requirements.
|
||||
*/
|
||||
private function displayRequirements()
|
||||
{
|
||||
$requirements = $this->getChecker()->requirements();
|
||||
|
||||
$this->frame('Application requirements');
|
||||
|
||||
$this->table([
|
||||
'Status', 'Message'
|
||||
], [
|
||||
[$requirements['status'], $requirements['message']]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display LogViewer messages.
|
||||
*/
|
||||
private function displayMessages()
|
||||
{
|
||||
$messages = $this->getChecker()->messages();
|
||||
|
||||
$rows = [];
|
||||
foreach ($messages['files'] as $file => $message) {
|
||||
$rows[] = [$file, $message];
|
||||
}
|
||||
|
||||
if ( ! empty($rows)) {
|
||||
$this->frame('LogViewer messages');
|
||||
$this->table(['File', 'Message'], $rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Commands;
|
||||
|
||||
/**
|
||||
* Class ClearCommand
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class ClearCommand extends Command
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'log-viewer:clear';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clear all generated log files';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
if ($this->confirm('This will delete all the log files, Do you wish to continue?')) {
|
||||
$this->logViewer->clear();
|
||||
$this->info('Successfully cleared the logs!');
|
||||
}
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Commands;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\LogViewer as LogViewerContract;
|
||||
use Arcanedev\Support\Console\Command as BaseCommand;
|
||||
|
||||
/**
|
||||
* Class Command
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
abstract class Command extends BaseCommand
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @var \Arcanedev\LogViewer\Contracts\LogViewer */
|
||||
protected $logViewer;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create the command instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\LogViewer $logViewer
|
||||
*/
|
||||
public function __construct(LogViewerContract $logViewer)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->logViewer = $logViewer;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display LogViewer Logo and Copyrights.
|
||||
*/
|
||||
protected function displayLogViewer()
|
||||
{
|
||||
// LOGO
|
||||
$this->comment(' __ _ ');
|
||||
$this->comment(' / / ___ __ _/\ /(_) _____ _____ _ __ ');
|
||||
$this->comment(' / / / _ \ / _` \ \ / / |/ _ \ \ /\ / / _ \ \'__|');
|
||||
$this->comment('/ /__| (_) | (_| |\ V /| | __/\ V V / __/ | ');
|
||||
$this->comment('\____/\___/ \__, | \_/ |_|\___| \_/\_/ \___|_| ');
|
||||
$this->comment(' |___/ ');
|
||||
$this->line('');
|
||||
|
||||
// Copyright
|
||||
$this->comment('Version '.$this->logViewer->version().' - Created by ARCANEDEV'.chr(169));
|
||||
$this->line('');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Commands;
|
||||
|
||||
use Arcanedev\LogViewer\LogViewerServiceProvider;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
/**
|
||||
* Class PublishCommand
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class PublishCommand extends Command
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'log-viewer:publish';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Publish all LogViewer resources and config files';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'log-viewer:publish
|
||||
{--tag= : One or many tags that have assets you want to publish.}
|
||||
{--force : Overwrite any existing files.}';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$args = [
|
||||
'--provider' => LogViewerServiceProvider::class,
|
||||
];
|
||||
|
||||
if ((bool) $this->option('force')) {
|
||||
$args['--force'] = true;
|
||||
}
|
||||
|
||||
$args['--tag'] = [$this->option('tag')];
|
||||
|
||||
$this->displayLogViewer();
|
||||
$this->call('vendor:publish', $args);
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
['tag', 't', InputOption::VALUE_OPTIONAL, 'One or many tags that have assets you want to publish.', ''],
|
||||
['force', 'f', InputOption::VALUE_OPTIONAL, 'Overwrite any existing files.', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Commands;
|
||||
|
||||
use Arcanedev\LogViewer\Tables\StatsTable;
|
||||
|
||||
/**
|
||||
* Class StatsCommand
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class StatsCommand extends Command
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'log-viewer:stats';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Display stats of all logs.';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'log-viewer:stats';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Load Data
|
||||
$stats = $this->logViewer->statsTable('en');
|
||||
|
||||
$rows = $stats->rows();
|
||||
$rows[] = $this->tableSeparator();
|
||||
$rows[] = $this->prepareFooter($stats);
|
||||
|
||||
// Display Data
|
||||
$this->displayLogViewer();
|
||||
$this->table($stats->header(), $rows);
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare footer.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Tables\StatsTable $stats
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepareFooter(StatsTable $stats)
|
||||
{
|
||||
$files = [
|
||||
'count' => count($stats->rows()).' log file(s)'
|
||||
];
|
||||
|
||||
return $files + $stats->footer();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts;
|
||||
|
||||
/**
|
||||
* Interface LogViewer
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface LogViewer extends Patternable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log levels.
|
||||
*
|
||||
* @param bool|false $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function levels($flip = false);
|
||||
|
||||
/**
|
||||
* Get the translated log levels.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function levelsNames($locale = null);
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPath($path);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all logs.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection|\Arcanedev\LogViewer\Entities\Log[]
|
||||
*/
|
||||
public function all();
|
||||
|
||||
/**
|
||||
* Paginate all logs.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 30);
|
||||
|
||||
/**
|
||||
* Get a log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function get($date);
|
||||
|
||||
/**
|
||||
* Get the log entries.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($date, $level = 'all');
|
||||
|
||||
/**
|
||||
* Download a log file.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string|null $filename
|
||||
* @param array $headers
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function download($date, $filename = null, $headers = []);
|
||||
|
||||
/**
|
||||
* Get logs statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats();
|
||||
|
||||
/**
|
||||
* Get logs statistics table.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Tables\StatsTable
|
||||
*/
|
||||
public function statsTable($locale = null);
|
||||
|
||||
/**
|
||||
* Delete the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
public function delete($date);
|
||||
|
||||
/**
|
||||
* Clear the log files.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear();
|
||||
|
||||
/**
|
||||
* List the log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function files();
|
||||
|
||||
/**
|
||||
* List the log files (only dates).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates();
|
||||
|
||||
/**
|
||||
* Get logs count.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Get entries total from all logs.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total($level = 'all');
|
||||
|
||||
/**
|
||||
* Get logs tree.
|
||||
*
|
||||
* @param bool|false $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false);
|
||||
|
||||
/**
|
||||
* Get logs menu.
|
||||
*
|
||||
* @param bool|true $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine if the log folder is empty or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty();
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the LogViewer version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function version();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem;
|
||||
|
||||
/**
|
||||
* Interface Patternable
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface Patternable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log pattern.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern();
|
||||
|
||||
/**
|
||||
* Set the log pattern.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $prefix
|
||||
* @param string $extension
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPattern(
|
||||
$prefix = Filesystem::PATTERN_PREFIX,
|
||||
$date = Filesystem::PATTERN_DATE,
|
||||
$extension = Filesystem::PATTERN_EXTENSION
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts;
|
||||
|
||||
/**
|
||||
* Interface Table
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface Table
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get table header.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function header();
|
||||
|
||||
/**
|
||||
* Get table rows.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rows();
|
||||
|
||||
/**
|
||||
* Get table footer.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function footer();
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Patternable;
|
||||
|
||||
/**
|
||||
* Interface Factory
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface Factory extends Patternable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the filesystem instance.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Contracts\Utilities\Filesystem
|
||||
*/
|
||||
public function getFilesystem();
|
||||
|
||||
/**
|
||||
* Set the filesystem instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setFilesystem(Filesystem $filesystem);
|
||||
|
||||
/**
|
||||
* Get the log levels instance.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*/
|
||||
public function getLevels();
|
||||
|
||||
/**
|
||||
* Set the log levels instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLevels(LogLevels $levels);
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $storagePath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPath($storagePath);
|
||||
|
||||
/**
|
||||
* Get all logs.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function logs();
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all logs (alias).
|
||||
*
|
||||
* @see logs
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function all();
|
||||
|
||||
/**
|
||||
* Paginate all logs.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 30);
|
||||
|
||||
/**
|
||||
* Get a log by date.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function log($date);
|
||||
|
||||
/**
|
||||
* Get a log by date (alias).
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function get($date);
|
||||
|
||||
/**
|
||||
* Get log entries.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($date, $level = 'all');
|
||||
|
||||
/**
|
||||
* List the log files (dates).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates();
|
||||
|
||||
/**
|
||||
* Get logs count.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Get total log entries.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total($level = 'all');
|
||||
|
||||
/**
|
||||
* Get tree menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false);
|
||||
|
||||
/**
|
||||
* Get tree menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true);
|
||||
|
||||
/**
|
||||
* Get logs statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats();
|
||||
|
||||
/**
|
||||
* Get logs statistics table.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Tables\StatsTable
|
||||
*/
|
||||
public function statsTable($locale = null);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine if the log folder is empty or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty();
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Patternable;
|
||||
|
||||
/**
|
||||
* Interface Filesystem
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface Filesystem extends Patternable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Constants
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const PATTERN_PREFIX = 'laravel-';
|
||||
const PATTERN_DATE = '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]';
|
||||
const PATTERN_EXTENSION = '.log';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the files instance.
|
||||
*
|
||||
* @return \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
public function getInstance();
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $storagePath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPath($storagePath);
|
||||
|
||||
/**
|
||||
* Set the log date pattern.
|
||||
*
|
||||
* @param string $datePattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDatePattern($datePattern);
|
||||
|
||||
/**
|
||||
* Set the log prefix pattern.
|
||||
*
|
||||
* @param string $prefixPattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrefixPattern($prefixPattern);
|
||||
|
||||
/**
|
||||
* Set the log extension.
|
||||
*
|
||||
* @param string $extension
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExtension($extension);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all();
|
||||
|
||||
/**
|
||||
* Get all valid log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function logs();
|
||||
|
||||
/**
|
||||
* List the log files (Only dates).
|
||||
*
|
||||
* @param bool $withPaths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates($withPaths = false);
|
||||
|
||||
/**
|
||||
* Read the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
public function read($date);
|
||||
|
||||
/**
|
||||
* Delete the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
public function delete(string $date);
|
||||
|
||||
/**
|
||||
* Clear the log files.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear();
|
||||
|
||||
/**
|
||||
* Get the log file path.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function path($date);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
|
||||
/**
|
||||
* Interface LogChecker
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface LogChecker
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Constants
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* @link http://laravel.com/docs/5.4/errors#configuration
|
||||
* @link https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md#log-to-files-and-syslog
|
||||
*/
|
||||
const HANDLER_DAILY = 'daily';
|
||||
const HANDLER_SINGLE = 'single';
|
||||
const HANDLER_SYSLOG = 'syslog';
|
||||
const HANDLER_ERRORLOG = 'errorlog';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the config instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(ConfigContract $config);
|
||||
|
||||
/**
|
||||
* Set the Filesystem instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setFilesystem(Filesystem $filesystem);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get messages.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages();
|
||||
|
||||
/**
|
||||
* Check passes ??
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function passes();
|
||||
|
||||
/**
|
||||
* Check fails ??
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function fails();
|
||||
|
||||
/**
|
||||
* Get the requirements
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function requirements();
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
use Illuminate\Translation\Translator;
|
||||
|
||||
/**
|
||||
* Interface LogLevels
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface LogLevels
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the Translator instance.
|
||||
*
|
||||
* @param \Illuminate\Translation\Translator $translator
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setTranslator(Translator $translator);
|
||||
|
||||
/**
|
||||
* Get the selected locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale();
|
||||
|
||||
/**
|
||||
* Set the selected locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLocale($locale);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log levels.
|
||||
*
|
||||
* @param bool $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function lists($flip = false);
|
||||
|
||||
/**
|
||||
* Get translated levels.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function names($locale = null);
|
||||
|
||||
/**
|
||||
* Get PSR log levels.
|
||||
*
|
||||
* @param bool $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function all($flip = false);
|
||||
|
||||
/**
|
||||
* Get the translated level.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get($key, $locale = null);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Entities\Log;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
|
||||
/**
|
||||
* Interface LogMenu
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface LogMenu
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the config instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(ConfigContract $config);
|
||||
|
||||
/**
|
||||
* Set the log styler instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogStyler $styler
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLogStyler(LogStyler $styler);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make log menu.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Entities\Log $log
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function make(Log $log, $trans = true);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Contracts\Utilities;
|
||||
|
||||
/**
|
||||
* Interface LogStyler
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
interface LogStyler
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make level icon.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return \Illuminate\Support\HtmlString
|
||||
*/
|
||||
public function icon($level, $default = null);
|
||||
|
||||
/**
|
||||
* Get level color.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function color($level, $default = null);
|
||||
|
||||
/**
|
||||
* Get strings to highlight.
|
||||
*
|
||||
* @param array $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toHighlight(array $default = []);
|
||||
}
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Entities;
|
||||
|
||||
use Illuminate\Contracts\Support\{Arrayable, Jsonable};
|
||||
use Illuminate\Support\Carbon;
|
||||
use JsonSerializable;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* Class Log
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class Log implements Arrayable, Jsonable, JsonSerializable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @var string */
|
||||
public $date;
|
||||
|
||||
/** @var string */
|
||||
private $path;
|
||||
|
||||
/** @var \Arcanedev\LogViewer\Entities\LogEntryCollection */
|
||||
private $entries;
|
||||
|
||||
/** @var \SplFileInfo */
|
||||
private $file;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Log constructor.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $path
|
||||
* @param string $raw
|
||||
*/
|
||||
public function __construct($date, $path, $raw)
|
||||
{
|
||||
$this->date = $date;
|
||||
$this->path = $path;
|
||||
$this->file = new SplFileInfo($path);
|
||||
$this->entries = LogEntryCollection::load($raw);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get log path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file info.
|
||||
*
|
||||
* @return \SplFileInfo
|
||||
*/
|
||||
public function file()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file size.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function size()
|
||||
{
|
||||
return $this->formatSize($this->file->getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file creation date.
|
||||
*
|
||||
* @return \Carbon\Carbon
|
||||
*/
|
||||
public function createdAt()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->file()->getATime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file modification date.
|
||||
*
|
||||
* @return \Carbon\Carbon
|
||||
*/
|
||||
public function updatedAt()
|
||||
{
|
||||
return Carbon::createFromTimestamp($this->file()->getMTime());
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make a log object.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $path
|
||||
* @param string $raw
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function make($date, $path, $raw)
|
||||
{
|
||||
return new self($date, $path, $raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log entries.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($level = 'all')
|
||||
{
|
||||
return $level === 'all'
|
||||
? $this->entries
|
||||
: $this->getByLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered log entries by level.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function getByLevel($level)
|
||||
{
|
||||
return $this->entries->filterByLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log stats.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
return $this->entries->stats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log navigation tree.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false)
|
||||
{
|
||||
return $this->entries->tree($trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log entries menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true)
|
||||
{
|
||||
return log_menu()->make($this, $trans);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Convert Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log as a plain array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'date' => $this->date,
|
||||
'path' => $this->path,
|
||||
'entries' => $this->entries->toArray()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to its JSON representation.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson($options = 0)
|
||||
{
|
||||
return json_encode($this->toArray(), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the log object to json data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format the file size.
|
||||
*
|
||||
* @param int $bytes
|
||||
* @param int $precision
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function formatSize($bytes, $precision = 2)
|
||||
{
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
return round($bytes / pow(1024, $pow), $precision).' '.$units[$pow];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Entities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Exceptions\LogNotFoundException;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
|
||||
/**
|
||||
* Class LogCollection
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogCollection extends LazyCollection
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @var \Arcanedev\LogViewer\Contracts\Utilities\Filesystem */
|
||||
private $filesystem;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogCollection constructor.
|
||||
*
|
||||
* @param mixed $source
|
||||
*/
|
||||
public function __construct($source = null)
|
||||
{
|
||||
$this->setFilesystem(app(FilesystemContract::class));
|
||||
|
||||
if (is_null($source))
|
||||
$source = function () {
|
||||
foreach($this->filesystem->dates(true) as $date => $path) {
|
||||
yield $date => Log::make($date, $path, $this->filesystem->read($date));
|
||||
}
|
||||
};
|
||||
|
||||
parent::__construct($source);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the filesystem instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function setFilesystem(FilesystemContract $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a log.
|
||||
*
|
||||
* @param string $date
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\LogNotFoundException
|
||||
*/
|
||||
public function get($date, $default = null)
|
||||
{
|
||||
if ( ! $this->has($date))
|
||||
throw LogNotFoundException::make($date);
|
||||
|
||||
return parent::get($date, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate logs.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 30)
|
||||
{
|
||||
$page = request()->get('page', 1);
|
||||
$path = request()->url();
|
||||
|
||||
return new LengthAwarePaginator(
|
||||
$this->forPage($page, $perPage),
|
||||
$this->count(),
|
||||
$perPage,
|
||||
$page,
|
||||
compact('path')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log (alias).
|
||||
*
|
||||
* @see get()
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function log($date)
|
||||
{
|
||||
return $this->get($date);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get log entries.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($date, $level = 'all')
|
||||
{
|
||||
return $this->get($date)->entries($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
$stats = [];
|
||||
|
||||
foreach ($this->all() as $date => $log) {
|
||||
/** @var \Arcanedev\LogViewer\Entities\Log $log */
|
||||
$stats[$date] = $log->stats();
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the log files (dates).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates()
|
||||
{
|
||||
return $this->keys()->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entries total.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total($level = 'all')
|
||||
{
|
||||
return (int) $this->sum(function (Log $log) use ($level) {
|
||||
return $log->entries($level)->count();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs tree.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false)
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($this->all() as $date => $log) {
|
||||
/** @var \Arcanedev\LogViewer\Entities\Log $log */
|
||||
$tree[$date] = $log->tree($trans);
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true)
|
||||
{
|
||||
$menu = [];
|
||||
|
||||
foreach ($this->all() as $date => $log) {
|
||||
/** @var \Arcanedev\LogViewer\Entities\Log $log */
|
||||
$menu[$date] = $log->menu($trans);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Entities;
|
||||
|
||||
use Arcanedev\LogViewer\Helpers\LogParser;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Support\{Arrayable, Jsonable};
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* Class LogEntry
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogEntry implements Arrayable, Jsonable, JsonSerializable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @var string */
|
||||
public $env;
|
||||
|
||||
/** @var string */
|
||||
public $level;
|
||||
|
||||
/** @var \Carbon\Carbon */
|
||||
public $datetime;
|
||||
|
||||
/** @var string */
|
||||
public $header;
|
||||
|
||||
/** @var string */
|
||||
public $stack;
|
||||
|
||||
/** @var array */
|
||||
public $context = [];
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct the log entry instance.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string $header
|
||||
* @param string|null $stack
|
||||
*/
|
||||
public function __construct($level, $header, $stack = null)
|
||||
{
|
||||
$this->setLevel($level);
|
||||
$this->setHeader($header);
|
||||
$this->setStack($stack);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the entry level.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function setLevel($level)
|
||||
{
|
||||
$this->level = $level;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entry header.
|
||||
*
|
||||
* @param string $header
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function setHeader($header)
|
||||
{
|
||||
$this->setDatetime($this->extractDatetime($header));
|
||||
|
||||
$header = $this->cleanHeader($header);
|
||||
|
||||
$this->header = trim($header);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context.
|
||||
*
|
||||
* @param array $context
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function setContext(array $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set entry environment.
|
||||
*
|
||||
* @param string $env
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function setEnv($env)
|
||||
{
|
||||
$this->env = head(explode('.', $env));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entry date time.
|
||||
*
|
||||
* @param string $datetime
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntry
|
||||
*/
|
||||
private function setDatetime($datetime)
|
||||
{
|
||||
$this->datetime = Carbon::createFromFormat('Y-m-d H:i:s', $datetime);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entry stack.
|
||||
*
|
||||
* @param string $stack
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
private function setStack($stack)
|
||||
{
|
||||
$this->stack = $stack;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get translated level name with icon.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function level()
|
||||
{
|
||||
return $this->icon()->toHtml().' '.$this->name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get translated level name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return log_levels()->get($this->level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get level icon.
|
||||
*
|
||||
* @return \Illuminate\Support\HtmlString
|
||||
*/
|
||||
public function icon()
|
||||
{
|
||||
return log_styler()->icon($this->level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entry stack.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function stack()
|
||||
{
|
||||
return trim(htmlentities($this->stack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entry context as json pretty print.
|
||||
*/
|
||||
public function context(int $options = JSON_PRETTY_PRINT): string
|
||||
{
|
||||
return json_encode($this->context, $options);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if same log level.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSameLevel($level)
|
||||
{
|
||||
return $this->level === $level;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Convert Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log entry as an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'level' => $this->level,
|
||||
'datetime' => $this->datetime->format('Y-m-d H:i:s'),
|
||||
'header' => $this->header,
|
||||
'stack' => $this->stack
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the log entry to its JSON representation.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson($options = 0)
|
||||
{
|
||||
return json_encode($this->toArray(), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the log entry object to json data.
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the entry has a stack.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasStack()
|
||||
{
|
||||
return $this->stack !== "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the entry has a context.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasContext()
|
||||
{
|
||||
return ! empty($this->context);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Clean the entry header.
|
||||
*
|
||||
* @param string $header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function cleanHeader($header)
|
||||
{
|
||||
// REMOVE THE DATE
|
||||
$header = preg_replace('/\['.LogParser::REGEX_DATETIME_PATTERN.'\][ ]/', '', $header);
|
||||
|
||||
// EXTRACT ENV
|
||||
if (preg_match('/^[a-z]+.[A-Z]+:/', $header, $out)) {
|
||||
$this->setEnv($out[0]);
|
||||
$header = trim(str_replace($out[0], '', $header));
|
||||
}
|
||||
|
||||
// EXTRACT CONTEXT (Regex from https://stackoverflow.com/a/21995025)
|
||||
preg_match_all('/{(?:[^{}]|(?R))*}/x', $header, $out);
|
||||
if (isset($out[0][0]) && ! is_null($context = json_decode($out[0][0], true))) {
|
||||
$header = str_replace($out[0][0], '', $header);
|
||||
$this->setContext($context);
|
||||
}
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract datetime from the header.
|
||||
*
|
||||
* @param string $header
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function extractDatetime($header)
|
||||
{
|
||||
return preg_replace('/^\[('.LogParser::REGEX_DATETIME_PATTERN.')\].*/', '$1', $header);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Entities;
|
||||
|
||||
use Arcanedev\LogViewer\Helpers\LogParser;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
|
||||
/**
|
||||
* Class LogEntryCollection
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogEntryCollection extends LazyCollection
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load raw log entries.
|
||||
*
|
||||
* @param string $raw
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function load($raw)
|
||||
{
|
||||
return new static(function () use ($raw) {
|
||||
foreach (LogParser::parse($raw) as $entry) {
|
||||
list($level, $header, $stack) = array_values($entry);
|
||||
|
||||
yield new LogEntry($level, $header, $stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate log entries.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 20)
|
||||
{
|
||||
$page = request()->get('page', 1);
|
||||
$path = request()->url();
|
||||
|
||||
return new LengthAwarePaginator(
|
||||
$this->forPage($page, $perPage),
|
||||
$this->count(),
|
||||
$perPage,
|
||||
$page,
|
||||
compact('path')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered log entries by level.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function filterByLevel($level)
|
||||
{
|
||||
return $this->filter(function(LogEntry $entry) use ($level) {
|
||||
return $entry->isSameLevel($level);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log entries stats.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
$counters = $this->initStats();
|
||||
|
||||
foreach ($this->groupBy('level') as $level => $entries) {
|
||||
$counters[$level] = $count = count($entries);
|
||||
$counters['all'] += $count;
|
||||
}
|
||||
|
||||
return $counters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log entries navigation tree.
|
||||
*
|
||||
* @param bool|false $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false)
|
||||
{
|
||||
$tree = $this->stats();
|
||||
|
||||
array_walk($tree, function(&$count, $level) use ($trans) {
|
||||
$count = [
|
||||
'name' => $trans ? log_levels()->get($level) : $level,
|
||||
'count' => $count,
|
||||
];
|
||||
});
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Init stats counters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function initStats()
|
||||
{
|
||||
$levels = array_merge_recursive(
|
||||
['all'],
|
||||
array_keys(log_viewer()->levels(true))
|
||||
);
|
||||
|
||||
return array_map(function () {
|
||||
return 0;
|
||||
}, array_flip($levels));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Exceptions;
|
||||
|
||||
/**
|
||||
* Class FilesystemException
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class FilesystemException extends LogViewerException
|
||||
{
|
||||
public static function cannotDeleteLog()
|
||||
{
|
||||
return new static('There was an error deleting the log.');
|
||||
}
|
||||
|
||||
public static function invalidPath(string $path)
|
||||
{
|
||||
return new static("The log(s) could not be located at : $path");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Exceptions;
|
||||
|
||||
/**
|
||||
* Class LogNotFoundException
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogNotFoundException extends LogViewerException
|
||||
{
|
||||
/**
|
||||
* Make the exception.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function make(string $date)
|
||||
{
|
||||
return new static("Log not found in this date [{$date}]");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Exceptions;
|
||||
|
||||
/**
|
||||
* Class LogViewerException
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogViewerException extends \Exception {}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Helpers;
|
||||
|
||||
use Arcanedev\LogViewer\Utilities\LogLevels;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class LogParser
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogParser
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Constants
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const REGEX_DATE_PATTERN = '\d{4}(-\d{2}){2}';
|
||||
const REGEX_TIME_PATTERN = '\d{2}(:\d{2}){2}';
|
||||
const REGEX_DATETIME_PATTERN = self::REGEX_DATE_PATTERN.' '.self::REGEX_TIME_PATTERN;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parsed data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $parsed = [];
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse file content.
|
||||
*
|
||||
* @param string $raw
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parse($raw)
|
||||
{
|
||||
static::$parsed = [];
|
||||
list($headings, $data) = static::parseRawData($raw);
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
if ( ! is_array($headings)) {
|
||||
return static::$parsed;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
foreach ($headings as $heading) {
|
||||
for ($i = 0, $j = count($heading); $i < $j; $i++) {
|
||||
static::populateEntries($heading, $data, $i);
|
||||
}
|
||||
};
|
||||
|
||||
unset($headings, $data);
|
||||
|
||||
return array_reverse(static::$parsed);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extract the date.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function extractDate(string $string): string
|
||||
{
|
||||
return preg_replace('/.*('.self::REGEX_DATE_PATTERN.').*/', '$1', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse raw data.
|
||||
*
|
||||
* @param string $raw
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function parseRawData($raw)
|
||||
{
|
||||
$pattern = '/\['.self::REGEX_DATETIME_PATTERN.'\].*/';
|
||||
preg_match_all($pattern, $raw, $headings);
|
||||
$data = preg_split($pattern, $raw);
|
||||
|
||||
if ($data[0] < 1) {
|
||||
$trash = array_shift($data);
|
||||
unset($trash);
|
||||
}
|
||||
|
||||
return [$headings, $data];
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate entries.
|
||||
*
|
||||
* @param array $heading
|
||||
* @param array $data
|
||||
* @param int $key
|
||||
*/
|
||||
private static function populateEntries($heading, $data, $key)
|
||||
{
|
||||
foreach (LogLevels::all() as $level) {
|
||||
if (static::hasLogLevel($heading[$key], $level)) {
|
||||
static::$parsed[] = [
|
||||
'level' => $level,
|
||||
'header' => $heading[$key],
|
||||
'stack' => $data[$key]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if header has a log level.
|
||||
*
|
||||
* @param string $heading
|
||||
* @param string $level
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function hasLogLevel($heading, $level)
|
||||
{
|
||||
return Str::contains($heading, strtoupper(".{$level}:"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Http\Controllers;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\LogViewer as LogViewerContract;
|
||||
use Arcanedev\LogViewer\Entities\{LogEntry, LogEntryCollection};
|
||||
use Arcanedev\LogViewer\Exceptions\LogNotFoundException;
|
||||
use Arcanedev\LogViewer\Tables\StatsTable;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\{Arr, Collection, Str};
|
||||
|
||||
/**
|
||||
* Class LogViewerController
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogViewerController extends Controller
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The log viewer instance
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\LogViewer
|
||||
*/
|
||||
protected $logViewer;
|
||||
|
||||
/** @var int */
|
||||
protected $perPage = 30;
|
||||
|
||||
/** @var string */
|
||||
protected $showRoute = 'log-viewer::logs.show';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogViewerController constructor.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\LogViewer $logViewer
|
||||
*/
|
||||
public function __construct(LogViewerContract $logViewer)
|
||||
{
|
||||
$this->logViewer = $logViewer;
|
||||
$this->perPage = config('log-viewer.per-page', $this->perPage);
|
||||
$this->showRoute = config('log-viewer.route.show', $this->showRoute);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Show the dashboard.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$stats = $this->logViewer->statsTable();
|
||||
$chartData = $this->prepareChartData($stats);
|
||||
$percents = $this->calcPercentages($stats->footer(), $stats->header());
|
||||
|
||||
return $this->view('dashboard', compact('chartData', 'percents'));
|
||||
}
|
||||
|
||||
/**
|
||||
* List all logs.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function listLogs(Request $request)
|
||||
{
|
||||
$stats = $this->logViewer->statsTable();
|
||||
$headers = $stats->header();
|
||||
$rows = $this->paginate($stats->rows(), $request);
|
||||
|
||||
return $this->view('logs', compact('headers', 'rows'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the log.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(Request $request, $date)
|
||||
{
|
||||
$level = 'all';
|
||||
$log = $this->getLogOrFail($date);
|
||||
$query = $request->get('query');
|
||||
$levels = $this->logViewer->levelsNames();
|
||||
$entries = $log->entries($level)->paginate($this->perPage);
|
||||
|
||||
return $this->view('show', compact('level', 'log', 'query', 'levels', 'entries'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the log entries by level.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function showByLevel(Request $request, $date, $level)
|
||||
{
|
||||
if ($level === 'all')
|
||||
return redirect()->route($this->showRoute, [$date]);
|
||||
|
||||
$log = $this->getLogOrFail($date);
|
||||
$query = $request->get('query');
|
||||
$levels = $this->logViewer->levelsNames();
|
||||
$entries = $this->logViewer->entries($date, $level)->paginate($this->perPage);
|
||||
|
||||
return $this->view('show', compact('level', 'log', 'query', 'levels', 'entries'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the log with the search query.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function search(Request $request, $date, $level = 'all')
|
||||
{
|
||||
$query = $request->get('query');
|
||||
|
||||
if (is_null($query))
|
||||
return redirect()->route($this->showRoute, [$date]);
|
||||
|
||||
$log = $this->getLogOrFail($date);
|
||||
$levels = $this->logViewer->levelsNames();
|
||||
$needles = array_map(function ($needle) {
|
||||
return Str::lower($needle);
|
||||
}, array_filter(explode(' ', $query)));
|
||||
$entries = $log->entries($level)
|
||||
->unless(empty($needles), function (LogEntryCollection $entries) use ($needles) {
|
||||
return $entries->filter(function (LogEntry $entry) use ($needles) {
|
||||
foreach ([$entry->header, $entry->stack, $entry->context()] as $subject) {
|
||||
if (Str::containsAll(Str::lower($subject), $needles))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
})
|
||||
->paginate($this->perPage);
|
||||
|
||||
return $this->view('show', compact('level', 'log', 'query', 'levels', 'entries'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the log
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function download($date)
|
||||
{
|
||||
return $this->logViewer->download($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a log.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function delete(Request $request)
|
||||
{
|
||||
abort_unless($request->ajax(), 405, 'Method Not Allowed');
|
||||
|
||||
$date = $request->input('date');
|
||||
|
||||
return response()->json([
|
||||
'result' => $this->logViewer->delete($date) ? 'success' : 'error'
|
||||
]);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the evaluated view contents for the given view.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
protected function view($view, $data = [], $mergeData = [])
|
||||
{
|
||||
$theme = config('log-viewer.theme');
|
||||
|
||||
return view()->make("log-viewer::{$theme}.{$view}", $data, $mergeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate logs.
|
||||
*
|
||||
* @param array $data
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected function paginate(array $data, Request $request)
|
||||
{
|
||||
$data = new Collection($data);
|
||||
$page = $request->get('page', 1);
|
||||
$path = $request->url();
|
||||
|
||||
return new LengthAwarePaginator(
|
||||
$data->forPage($page, $this->perPage),
|
||||
$data->count(),
|
||||
$this->perPage,
|
||||
$page,
|
||||
compact('path')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log or fail
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log|null
|
||||
*/
|
||||
protected function getLogOrFail($date)
|
||||
{
|
||||
$log = null;
|
||||
|
||||
try {
|
||||
$log = $this->logViewer->get($date);
|
||||
}
|
||||
catch (LogNotFoundException $e) {
|
||||
abort(404, $e->getMessage());
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare chart data.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Tables\StatsTable $stats
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareChartData(StatsTable $stats)
|
||||
{
|
||||
$totals = $stats->totals()->all();
|
||||
|
||||
return json_encode([
|
||||
'labels' => Arr::pluck($totals, 'label'),
|
||||
'datasets' => [
|
||||
[
|
||||
'data' => Arr::pluck($totals, 'value'),
|
||||
'backgroundColor' => Arr::pluck($totals, 'color'),
|
||||
'hoverBackgroundColor' => Arr::pluck($totals, 'highlight'),
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the percentage.
|
||||
*
|
||||
* @param array $total
|
||||
* @param array $names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function calcPercentages(array $total, array $names)
|
||||
{
|
||||
$percents = [];
|
||||
$all = Arr::get($total, 'all');
|
||||
|
||||
foreach ($total as $level => $count) {
|
||||
$percents[$level] = [
|
||||
'name' => $names[$level],
|
||||
'count' => $count,
|
||||
'percent' => $all ? round(($count / $all) * 100, 2) : 0,
|
||||
];
|
||||
}
|
||||
|
||||
return $percents;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Http\Routes;
|
||||
|
||||
use Arcanedev\LogViewer\Http\Controllers\LogViewerController;
|
||||
use Arcanedev\Support\Routing\RouteRegistrar;
|
||||
|
||||
/**
|
||||
* Class LogViewerRoute
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogViewerRoute extends RouteRegistrar
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map all routes.
|
||||
*/
|
||||
public function map(): void
|
||||
{
|
||||
$attributes = (array) config('log-viewer.route.attributes');
|
||||
|
||||
$this->group($attributes, function() {
|
||||
$this->name('log-viewer::')->group(function () {
|
||||
$this->get('/', [LogViewerController::class, 'index'])
|
||||
->name('dashboard'); // log-viewer::dashboard
|
||||
|
||||
$this->mapLogsRoutes();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the logs routes.
|
||||
*/
|
||||
private function mapLogsRoutes(): void
|
||||
{
|
||||
$this->prefix('logs')->name('logs.')->group(function() {
|
||||
$this->get('/', [LogViewerController::class, 'listLogs'])
|
||||
->name('list'); // log-viewer::logs.list
|
||||
|
||||
$this->delete('delete', [LogViewerController::class, 'delete'])
|
||||
->name('delete'); // log-viewer::logs.delete
|
||||
|
||||
$this->prefix('{date}')->group(function() {
|
||||
$this->get('/', [LogViewerController::class, 'show'])
|
||||
->name('show'); // log-viewer::logs.show
|
||||
|
||||
$this->get('download', [LogViewerController::class, 'download'])
|
||||
->name('download'); // log-viewer::logs.download
|
||||
|
||||
$this->get('{level}', [LogViewerController::class, 'showByLevel'])
|
||||
->name('filter'); // log-viewer::logs.filter
|
||||
|
||||
$this->get('{level}/search', [LogViewerController::class, 'search'])
|
||||
->name('search'); // log-viewer::logs.search
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
+364
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Factory as FactoryContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
use Arcanedev\LogViewer\Contracts\LogViewer as LogViewerContract;
|
||||
|
||||
/**
|
||||
* Class LogViewer
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogViewer implements LogViewerContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Constants
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogViewer Version
|
||||
*/
|
||||
const VERSION = '10.1.1';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The factory instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\Factory
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\Filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* The log levels instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\LogLevels
|
||||
*/
|
||||
protected $levels;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Factory $factory
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*/
|
||||
public function __construct(
|
||||
FactoryContract $factory,
|
||||
FilesystemContract $filesystem,
|
||||
LogLevelsContract $levels
|
||||
) {
|
||||
$this->factory = $factory;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->levels = $levels;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log levels.
|
||||
*
|
||||
* @param bool $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function levels($flip = false)
|
||||
{
|
||||
return $this->levels->lists($flip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translated log levels.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function levelsNames($locale = null)
|
||||
{
|
||||
return $this->levels->names($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->factory->setPath($path);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log pattern.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->factory->getPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log pattern.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $prefix
|
||||
* @param string $extension
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPattern(
|
||||
$prefix = FilesystemContract::PATTERN_PREFIX,
|
||||
$date = FilesystemContract::PATTERN_DATE,
|
||||
$extension = FilesystemContract::PATTERN_EXTENSION
|
||||
) {
|
||||
$this->factory->setPattern($prefix, $date, $extension);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all logs.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->factory->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate all logs.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 30)
|
||||
{
|
||||
return $this->factory->paginate($perPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function get($date)
|
||||
{
|
||||
return $this->factory->log($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log entries.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($date, $level = 'all')
|
||||
{
|
||||
return $this->factory->entries($date, $level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a log file.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string|null $filename
|
||||
* @param array $headers
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||
*/
|
||||
public function download($date, $filename = null, $headers = [])
|
||||
{
|
||||
if (is_null($filename)) {
|
||||
$filename = sprintf(
|
||||
"%s{$date}.%s",
|
||||
config('log-viewer.download.prefix', 'laravel-'),
|
||||
config('log-viewer.download.extension', 'log')
|
||||
);
|
||||
}
|
||||
|
||||
$path = $this->filesystem->path($date);
|
||||
|
||||
return response()->download($path, $filename, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
return $this->factory->stats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs statistics table.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Tables\StatsTable
|
||||
*/
|
||||
public function statsTable($locale = null)
|
||||
{
|
||||
return $this->factory->statsTable($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($date)
|
||||
{
|
||||
return $this->filesystem->delete($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the log files.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->filesystem->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all valid log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function files()
|
||||
{
|
||||
return $this->filesystem->logs();
|
||||
}
|
||||
|
||||
/**
|
||||
* List the log files (only dates).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates()
|
||||
{
|
||||
return $this->factory->dates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs count.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->factory->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entries total from all logs.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total($level = 'all')
|
||||
{
|
||||
return $this->factory->total($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs tree.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false)
|
||||
{
|
||||
return $this->factory->tree($trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true)
|
||||
{
|
||||
return $this->factory->menu($trans);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine if the log folder is empty or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->factory->isEmpty();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the LogViewer version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function version()
|
||||
{
|
||||
return self::VERSION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer;
|
||||
|
||||
use Arcanedev\Support\Providers\PackageServiceProvider;
|
||||
|
||||
/**
|
||||
* Class LogViewerServiceProvider
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogViewerServiceProvider extends PackageServiceProvider
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Package name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $package = 'log-viewer';
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
parent::register();
|
||||
|
||||
$this->registerConfig();
|
||||
|
||||
$this->registerProvider(Providers\RouteServiceProvider::class);
|
||||
|
||||
$this->registerCommands([
|
||||
Commands\PublishCommand::class,
|
||||
Commands\StatsCommand::class,
|
||||
Commands\CheckCommand::class,
|
||||
Commands\ClearCommand::class,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the service provider.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->loadTranslations();
|
||||
$this->loadViews();
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->publishConfig();
|
||||
$this->publishTranslations();
|
||||
$this->publishViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Providers;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\LogViewer as LogViewerContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Factory as FactoryContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogChecker as LogCheckerContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogMenu as LogMenuContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogStyler as LogStylerContract;
|
||||
use Arcanedev\LogViewer\LogViewer;
|
||||
use Arcanedev\LogViewer\Utilities;
|
||||
use Arcanedev\Support\Providers\ServiceProvider;
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
|
||||
/**
|
||||
* Class DeferredServicesProvider
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class DeferredServicesProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->registerLogViewer();
|
||||
$this->registerLogLevels();
|
||||
$this->registerStyler();
|
||||
$this->registerLogMenu();
|
||||
$this->registerFilesystem();
|
||||
$this->registerFactory();
|
||||
$this->registerChecker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides(): array
|
||||
{
|
||||
return [
|
||||
LogViewerContract::class,
|
||||
LogLevelsContract::class,
|
||||
LogStylerContract::class,
|
||||
LogMenuContract::class,
|
||||
FilesystemContract::class,
|
||||
FactoryContract::class,
|
||||
LogCheckerContract::class,
|
||||
];
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| LogViewer Utilities
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register the log viewer service.
|
||||
*/
|
||||
private function registerLogViewer(): void
|
||||
{
|
||||
$this->singleton(LogViewerContract::class, LogViewer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log levels.
|
||||
*/
|
||||
private function registerLogLevels(): void
|
||||
{
|
||||
$this->singleton(LogLevelsContract::class, function ($app) {
|
||||
return new Utilities\LogLevels(
|
||||
$app['translator'],
|
||||
$app['config']->get('log-viewer.locale')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log styler.
|
||||
*/
|
||||
private function registerStyler(): void
|
||||
{
|
||||
$this->singleton(LogStylerContract::class, Utilities\LogStyler::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log menu builder.
|
||||
*/
|
||||
private function registerLogMenu(): void
|
||||
{
|
||||
$this->singleton(LogMenuContract::class, Utilities\LogMenu::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log filesystem.
|
||||
*/
|
||||
private function registerFilesystem(): void
|
||||
{
|
||||
$this->singleton(FilesystemContract::class, function ($app) {
|
||||
/** @var \Illuminate\Config\Repository $config */
|
||||
$config = $app['config'];
|
||||
$filesystem = new Utilities\Filesystem($app['files'], $config->get('log-viewer.storage-path'));
|
||||
|
||||
return $filesystem->setPattern(
|
||||
$config->get('log-viewer.pattern.prefix', FilesystemContract::PATTERN_PREFIX),
|
||||
$config->get('log-viewer.pattern.date', FilesystemContract::PATTERN_DATE),
|
||||
$config->get('log-viewer.pattern.extension', FilesystemContract::PATTERN_EXTENSION)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log factory class.
|
||||
*/
|
||||
private function registerFactory(): void
|
||||
{
|
||||
$this->singleton(FactoryContract::class, Utilities\Factory::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the log checker service.
|
||||
*/
|
||||
private function registerChecker(): void
|
||||
{
|
||||
$this->singleton(LogCheckerContract::class, Utilities\LogChecker::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Providers;
|
||||
|
||||
use Arcanedev\LogViewer\Http\Routes\LogViewerRoute;
|
||||
use Arcanedev\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class RouteServiceProvider
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if routes is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return (bool) $this->config('enabled', false);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Boot the service provider.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
if ($this->isEnabled()) {
|
||||
$this->routes(function () {
|
||||
static::mapRouteClasses([LogViewerRoute::class]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get config value by key
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function config($key, $default = null)
|
||||
{
|
||||
return $this->app['config']->get("log-viewer.route.$key", $default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Tables;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Table as TableContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
|
||||
/**
|
||||
* Class AbstractTable
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
abstract class AbstractTable implements TableContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @var array */
|
||||
private $header = [];
|
||||
|
||||
/** @var array */
|
||||
private $rows = [];
|
||||
|
||||
/** @var array */
|
||||
private $footer = [];
|
||||
|
||||
/** @var \Arcanedev\LogViewer\Contracts\Utilities\LogLevels */
|
||||
protected $levels;
|
||||
|
||||
/** @var string|null */
|
||||
protected $locale;
|
||||
|
||||
/** @var array */
|
||||
private $data = [];
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a table instance.
|
||||
*
|
||||
* @param array $data
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
* @param string|null $locale
|
||||
*/
|
||||
public function __construct(array $data, LogLevelsContract $levels, $locale = null)
|
||||
{
|
||||
$this->setLevels($levels);
|
||||
$this->setLocale(is_null($locale) ? config('log-viewer.locale') : $locale);
|
||||
$this->setData($data);
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set LogLevels instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setLevels(LogLevelsContract $levels)
|
||||
{
|
||||
$this->levels = $levels;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table locale.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function setLocale($locale)
|
||||
{
|
||||
if (is_null($locale) || $locale === 'auto') {
|
||||
$locale = app()->getLocale();
|
||||
}
|
||||
|
||||
$this->locale = $locale;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table header.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function header()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table rows.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rows()
|
||||
{
|
||||
return $this->rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table footer.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function footer()
|
||||
{
|
||||
return $this->footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set table data.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
private function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare the table.
|
||||
*/
|
||||
private function init()
|
||||
{
|
||||
$this->header = $this->prepareHeader($this->data);
|
||||
$this->rows = $this->prepareRows($this->data);
|
||||
$this->footer = $this->prepareFooter($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare table header.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareHeader(array $data);
|
||||
|
||||
/**
|
||||
* Prepare table rows.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareRows(array $data);
|
||||
|
||||
/**
|
||||
* Prepare table footer.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function prepareFooter(array $data);
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get log level color.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function color($level)
|
||||
{
|
||||
return log_styler()->color($level);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Tables;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
use Illuminate\Support\{Arr, Collection};
|
||||
|
||||
/**
|
||||
* Class StatsTable
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class StatsTable extends AbstractTable
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make a stats table instance.
|
||||
*
|
||||
* @param array $data
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public static function make(array $data, LogLevelsContract $levels, $locale = null)
|
||||
{
|
||||
return new static($data, $levels, $locale);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare table header.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareHeader(array $data)
|
||||
{
|
||||
return array_merge_recursive(
|
||||
[
|
||||
'date' => __('Date'),
|
||||
'all' => __('All'),
|
||||
],
|
||||
$this->levels->names($this->locale)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare table rows.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareRows(array $data)
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
foreach ($data as $date => $levels) {
|
||||
$rows[$date] = array_merge(compact('date'), $levels);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare table footer.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareFooter(array $data)
|
||||
{
|
||||
$footer = [];
|
||||
|
||||
foreach ($data as $date => $levels) {
|
||||
foreach ($levels as $level => $count) {
|
||||
if ( ! isset($footer[$level])) {
|
||||
$footer[$level] = 0;
|
||||
}
|
||||
|
||||
$footer[$level] += $count;
|
||||
}
|
||||
}
|
||||
|
||||
return $footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get totals.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function totals($locale = null)
|
||||
{
|
||||
$totals = Collection::make();
|
||||
|
||||
foreach (Arr::except($this->footer(), 'all') as $level => $count) {
|
||||
$totals->put($level, [
|
||||
'label' => log_levels()->get($level, $locale),
|
||||
'value' => $count,
|
||||
'color' => $this->color($level),
|
||||
'highlight' => $this->color($level),
|
||||
]);
|
||||
}
|
||||
|
||||
return $totals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get json totals data.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function totalsJson($locale = null)
|
||||
{
|
||||
return $this->totals($locale)->toJson(JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Factory as FactoryContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
use Arcanedev\LogViewer\Entities\LogCollection;
|
||||
use Arcanedev\LogViewer\Entities\Log;
|
||||
use Arcanedev\LogViewer\Exceptions\LogNotFoundException;
|
||||
use Arcanedev\LogViewer\Tables\StatsTable;
|
||||
|
||||
/**
|
||||
* Class Factory
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class Factory implements FactoryContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\Filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* The log levels instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\LogLevels
|
||||
*/
|
||||
private $levels;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*/
|
||||
public function __construct(FilesystemContract $filesystem, LogLevelsContract $levels) {
|
||||
$this->setFilesystem($filesystem);
|
||||
$this->setLevels($levels);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getter & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the filesystem instance.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Contracts\Utilities\Filesystem
|
||||
*/
|
||||
public function getFilesystem()
|
||||
{
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filesystem instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setFilesystem(FilesystemContract $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log levels instance.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Contracts\Utilities\LogLevels
|
||||
*/
|
||||
public function getLevels()
|
||||
{
|
||||
return $this->levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log levels instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogLevels $levels
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLevels(LogLevelsContract $levels)
|
||||
{
|
||||
$this->levels = $levels;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $storagePath
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPath($storagePath)
|
||||
{
|
||||
$this->filesystem->setPath($storagePath);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log pattern.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->filesystem->getPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log pattern.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $prefix
|
||||
* @param string $extension
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setPattern(
|
||||
$prefix = FilesystemContract::PATTERN_PREFIX,
|
||||
$date = FilesystemContract::PATTERN_DATE,
|
||||
$extension = FilesystemContract::PATTERN_EXTENSION
|
||||
) {
|
||||
$this->filesystem->setPattern($prefix, $date, $extension);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all logs.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function logs()
|
||||
{
|
||||
return (new LogCollection)->setFilesystem($this->filesystem);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all logs (alias).
|
||||
*
|
||||
* @see logs
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogCollection
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->logs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate all logs.
|
||||
*
|
||||
* @param int $perPage
|
||||
*
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate($perPage = 30)
|
||||
{
|
||||
return $this->logs()->paginate($perPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log by date.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function log($date)
|
||||
{
|
||||
$dates = $this->filesystem->dates(true);
|
||||
if (!isset($dates[$date])) {
|
||||
throw new LogNotFoundException("Log not found in this date [$date]");
|
||||
}
|
||||
|
||||
return new Log($date, $dates[$date], $this->filesystem->read($date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log by date (alias).
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\Log
|
||||
*/
|
||||
public function get($date)
|
||||
{
|
||||
return $this->log($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log entries.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $level
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Entities\LogEntryCollection
|
||||
*/
|
||||
public function entries($date, $level = 'all')
|
||||
{
|
||||
return $this->log($date)->entries($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs statistics.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function stats()
|
||||
{
|
||||
return $this->logs()->stats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs statistics table.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Tables\StatsTable
|
||||
*/
|
||||
public function statsTable($locale = null)
|
||||
{
|
||||
return StatsTable::make($this->stats(), $this->levels, $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* List the log files (dates).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates()
|
||||
{
|
||||
return $this->filesystem->dates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logs count.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->logs()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total log entries.
|
||||
*
|
||||
* @param string $level
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function total($level = 'all')
|
||||
{
|
||||
return $this->logs()->total($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tree menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tree($trans = false)
|
||||
{
|
||||
return $this->logs()->tree($trans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tree menu.
|
||||
*
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function menu($trans = true)
|
||||
{
|
||||
return $this->logs()->menu($trans);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine if the log folder is empty or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->logs()->isEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Exceptions\FilesystemException;
|
||||
use Arcanedev\LogViewer\Helpers\LogParser;
|
||||
use Exception;
|
||||
use Illuminate\Filesystem\Filesystem as IlluminateFilesystem;
|
||||
|
||||
/**
|
||||
* Class Filesystem
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class Filesystem implements FilesystemContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* The base storage path.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $storagePath;
|
||||
|
||||
/**
|
||||
* The log files prefix pattern.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefixPattern;
|
||||
|
||||
/**
|
||||
* The log files date pattern.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $datePattern;
|
||||
|
||||
/**
|
||||
* The log files extension.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filesystem constructor.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param string $storagePath
|
||||
*/
|
||||
public function __construct(IlluminateFilesystem $files, $storagePath)
|
||||
{
|
||||
$this->filesystem = $files;
|
||||
$this->setPath($storagePath);
|
||||
$this->setPattern();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the files instance.
|
||||
*
|
||||
* @return \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
public function getInstance()
|
||||
{
|
||||
return $this->filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log storage path.
|
||||
*
|
||||
* @param string $storagePath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPath($storagePath)
|
||||
{
|
||||
$this->storagePath = $storagePath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log pattern.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern(): string
|
||||
{
|
||||
return $this->prefixPattern.$this->datePattern.$this->extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log pattern.
|
||||
*
|
||||
* @param string $date
|
||||
* @param string $prefix
|
||||
* @param string $extension
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPattern(
|
||||
$prefix = self::PATTERN_PREFIX,
|
||||
$date = self::PATTERN_DATE,
|
||||
$extension = self::PATTERN_EXTENSION
|
||||
) {
|
||||
$this->setPrefixPattern($prefix);
|
||||
$this->setDatePattern($date);
|
||||
$this->setExtension($extension);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log date pattern.
|
||||
*
|
||||
* @param string $datePattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDatePattern($datePattern)
|
||||
{
|
||||
$this->datePattern = $datePattern;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log prefix pattern.
|
||||
*
|
||||
* @param string $prefixPattern
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrefixPattern($prefixPattern)
|
||||
{
|
||||
$this->prefixPattern = $prefixPattern;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log extension.
|
||||
*
|
||||
* @param string $extension
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExtension($extension)
|
||||
{
|
||||
$this->extension = $extension;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->getFiles('*'.$this->extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all valid log files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function logs()
|
||||
{
|
||||
return $this->getFiles($this->getPattern());
|
||||
}
|
||||
|
||||
/**
|
||||
* List the log files (Only dates).
|
||||
*
|
||||
* @param bool $withPaths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dates($withPaths = false)
|
||||
{
|
||||
$files = array_reverse($this->logs());
|
||||
$dates = $this->extractDates($files);
|
||||
|
||||
if ($withPaths) {
|
||||
$dates = array_combine($dates, $files); // [date => file]
|
||||
}
|
||||
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
public function read($date)
|
||||
{
|
||||
try {
|
||||
$log = $this->filesystem->get(
|
||||
$this->getLogPath($date)
|
||||
);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
throw new FilesystemException($e->getMessage());
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the log.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
public function delete(string $date)
|
||||
{
|
||||
$path = $this->getLogPath($date);
|
||||
|
||||
throw_unless($this->filesystem->delete($path), FilesystemException::cannotDeleteLog());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the log files.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
return $this->filesystem->delete($this->logs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log file path.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function path($date)
|
||||
{
|
||||
return $this->getLogPath($date);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all files.
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getFiles($pattern)
|
||||
{
|
||||
$files = $this->filesystem->glob(
|
||||
$this->storagePath.DIRECTORY_SEPARATOR.$pattern, defined('GLOB_BRACE') ? GLOB_BRACE : 0
|
||||
);
|
||||
|
||||
return array_filter(array_map('realpath', $files));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log file path.
|
||||
*
|
||||
* @param string $date
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Arcanedev\LogViewer\Exceptions\FilesystemException
|
||||
*/
|
||||
private function getLogPath(string $date)
|
||||
{
|
||||
$path = $this->storagePath.DIRECTORY_SEPARATOR.$this->prefixPattern.$date.$this->extension;
|
||||
|
||||
if ( ! $this->filesystem->exists($path)) {
|
||||
throw FilesystemException::invalidPath($path);
|
||||
}
|
||||
|
||||
return realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract dates from files.
|
||||
*
|
||||
* @param array $files
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extractDates(array $files)
|
||||
{
|
||||
return array_map(function ($file) {
|
||||
return LogParser::extractDate(basename($file));
|
||||
}, $files);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\Filesystem as FilesystemContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogChecker as LogCheckerContract;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
|
||||
/**
|
||||
* Class LogChecker
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogChecker implements LogCheckerContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The config repository instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\Filesystem
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
/**
|
||||
* Log handler mode.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $handler = '';
|
||||
|
||||
/**
|
||||
* The check status.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $status = true;
|
||||
|
||||
/**
|
||||
* The check messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $messages;
|
||||
|
||||
/**
|
||||
* Log files statuses.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $files = [];
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogChecker constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*/
|
||||
public function __construct(ConfigContract $config, FilesystemContract $filesystem)
|
||||
{
|
||||
$this->setConfig($config);
|
||||
$this->setFilesystem($filesystem);
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the config instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(ConfigContract $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Filesystem instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\Filesystem $filesystem
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setFilesystem(FilesystemContract $filesystem)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log handler mode.
|
||||
*
|
||||
* @param string $handler
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
protected function setHandler($handler)
|
||||
{
|
||||
$this->handler = strtolower($handler);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get messages.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
{
|
||||
$this->refresh();
|
||||
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the checker passes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function passes()
|
||||
{
|
||||
$this->refresh();
|
||||
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the checker fails.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function fails()
|
||||
{
|
||||
return ! $this->passes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the requirements.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function requirements()
|
||||
{
|
||||
$this->refresh();
|
||||
|
||||
return $this->isDaily() ? [
|
||||
'status' => 'success',
|
||||
'header' => 'Application requirements fulfilled.',
|
||||
'message' => 'Are you ready to rock ?',
|
||||
] : [
|
||||
'status' => 'failed',
|
||||
'header' => 'Application requirements failed.',
|
||||
'message' => $this->messages['handler']
|
||||
];
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Is a daily handler mode ?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isDaily()
|
||||
{
|
||||
return $this->isSameHandler(self::HANDLER_DAILY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the handler is the same as the application log handler.
|
||||
*
|
||||
* @param string $handler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isSameHandler($handler)
|
||||
{
|
||||
return $this->handler === $handler;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Refresh the checks.
|
||||
*
|
||||
* @return \Arcanedev\LogViewer\Utilities\LogChecker
|
||||
*/
|
||||
private function refresh()
|
||||
{
|
||||
$this->setHandler($this->config->get('logging.default', 'stack'));
|
||||
|
||||
$this->messages = [
|
||||
'handler' => '',
|
||||
'files' => [],
|
||||
];
|
||||
$this->files = [];
|
||||
|
||||
$this->checkHandler();
|
||||
$this->checkLogFiles();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the handler mode.
|
||||
*/
|
||||
private function checkHandler()
|
||||
{
|
||||
if ($this->isDaily()) return;
|
||||
|
||||
$this->messages['handler'] = 'You should set the log handler to `daily` mode. Please check the LogViewer wiki page (Requirements) for more details.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all log files.
|
||||
*/
|
||||
private function checkLogFiles()
|
||||
{
|
||||
foreach ($this->filesystem->all() as $path) {
|
||||
$this->checkLogFile($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a log file.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
private function checkLogFile($path)
|
||||
{
|
||||
$status = true;
|
||||
$filename = basename($path);
|
||||
$message = "The log file [$filename] is valid.";
|
||||
$pattern = $this->filesystem->getPattern();
|
||||
|
||||
if ($this->isSingleLogFile($filename)) {
|
||||
$this->status = $status = false;
|
||||
$this->messages['files'][$filename] = $message =
|
||||
"You have a single log file in your application, you should split the [$filename] into separate log files.";
|
||||
}
|
||||
elseif ($this->isInvalidLogPattern($filename, $pattern)) {
|
||||
$this->status = $status = false;
|
||||
$this->messages['files'][$filename] = $message =
|
||||
"The log file [$filename] has an invalid date, the format must be like {$pattern}.";
|
||||
}
|
||||
|
||||
$this->files[$filename] = compact('filename', 'status', 'message', 'path');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it's not a single log file.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isSingleLogFile($file)
|
||||
{
|
||||
return $file === 'laravel.log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the date of the log file.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isInvalidLogPattern($file, $pattern)
|
||||
{
|
||||
return ((bool) preg_match("/{$pattern}/", $file, $matches)) === false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogLevels as LogLevelsContract;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Translation\Translator;
|
||||
use Psr\Log\LogLevel;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Class LogLevels
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogLevels implements LogLevelsContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The log levels.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $levels = [];
|
||||
|
||||
/**
|
||||
* The Translator instance.
|
||||
*
|
||||
* @var \Illuminate\Translation\Translator
|
||||
*/
|
||||
private $translator;
|
||||
|
||||
/**
|
||||
* The selected locale.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $locale;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogLevels constructor.
|
||||
*
|
||||
* @param \Illuminate\Translation\Translator $translator
|
||||
* @param string $locale
|
||||
*/
|
||||
public function __construct(Translator $translator, $locale)
|
||||
{
|
||||
$this->setTranslator($translator);
|
||||
$this->setLocale($locale);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the Translator instance.
|
||||
*
|
||||
* @param \Illuminate\Translation\Translator $translator
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTranslator(Translator $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->locale === 'auto'
|
||||
? $this->translator->getLocale()
|
||||
: $this->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLocale($locale)
|
||||
{
|
||||
$this->locale = is_null($locale) ? 'auto' : $locale;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the log levels.
|
||||
*
|
||||
* @param bool $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function lists($flip = false)
|
||||
{
|
||||
return static::all($flip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get translated levels.
|
||||
*
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function names($locale = null)
|
||||
{
|
||||
$levels = static::all(true);
|
||||
|
||||
array_walk($levels, function (&$name, $level) use ($locale) {
|
||||
$name = $this->get($level, $locale);
|
||||
});
|
||||
|
||||
return $levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PSR log levels.
|
||||
*
|
||||
* @param bool $flip
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function all($flip = false)
|
||||
{
|
||||
if (empty(static::$levels)) {
|
||||
static::$levels = (new ReflectionClass(LogLevel::class))->getConstants();
|
||||
}
|
||||
|
||||
return $flip ? array_flip(static::$levels) : static::$levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translated level.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|null $locale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get($key, $locale = null)
|
||||
{
|
||||
$translations = [
|
||||
'all' => 'All',
|
||||
LogLevel::EMERGENCY => 'Emergency',
|
||||
LogLevel::ALERT => 'Alert',
|
||||
LogLevel::CRITICAL => 'Critical',
|
||||
LogLevel::ERROR => 'Error',
|
||||
LogLevel::WARNING => 'Warning',
|
||||
LogLevel::NOTICE => 'Notice',
|
||||
LogLevel::INFO => 'Info',
|
||||
LogLevel::DEBUG => 'Debug',
|
||||
];
|
||||
|
||||
return $this->translator->get(Arr::get($translations, $key, $key), [], $locale ?: $this->getLocale());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogMenu as LogMenuContract;
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogStyler as LogStylerContract;
|
||||
use Arcanedev\LogViewer\Entities\Log;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
|
||||
/**
|
||||
* Class LogMenu
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogMenu implements LogMenuContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The config repository instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* The log styler instance.
|
||||
*
|
||||
* @var \Arcanedev\LogViewer\Contracts\Utilities\LogStyler
|
||||
*/
|
||||
private $styler;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* LogMenu constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogStyler $styler
|
||||
*/
|
||||
public function __construct(ConfigContract $config, LogStylerContract $styler)
|
||||
{
|
||||
$this->setConfig($config);
|
||||
$this->setLogStyler($styler);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the config instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setConfig(ConfigContract $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the log styler instance.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Contracts\Utilities\LogStyler $styler
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setLogStyler(LogStylerContract $styler)
|
||||
{
|
||||
$this->styler = $styler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make log menu.
|
||||
*
|
||||
* @param \Arcanedev\LogViewer\Entities\Log $log
|
||||
* @param bool $trans
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function make(Log $log, $trans = true)
|
||||
{
|
||||
$items = [];
|
||||
$route = $this->config('menu.filter-route');
|
||||
|
||||
foreach($log->tree($trans) as $level => $item) {
|
||||
$items[$level] = array_merge($item, [
|
||||
'url' => route($route, [$log->date, $level]),
|
||||
'icon' => $this->isIconsEnabled() ? $this->styler->icon($level)->toHtml() : '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Check Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the icons are enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isIconsEnabled()
|
||||
{
|
||||
return (bool) $this->config('menu.icons-enabled', false);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Other Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get config.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function config($key, $default = null)
|
||||
{
|
||||
return $this->config->get("log-viewer.$key", $default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Arcanedev\LogViewer\Utilities;
|
||||
|
||||
use Arcanedev\LogViewer\Contracts\Utilities\LogStyler as LogStylerContract;
|
||||
use Illuminate\Contracts\Config\Repository as ConfigContract;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
/**
|
||||
* Class LogStyler
|
||||
*
|
||||
* @author ARCANEDEV <[email protected]>
|
||||
*/
|
||||
class LogStyler implements LogStylerContract
|
||||
{
|
||||
/* -----------------------------------------------------------------
|
||||
| Properties
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* The config repository instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Constructor
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $config
|
||||
*/
|
||||
public function __construct(ConfigContract $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Getters & Setters
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get config.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get($key, $default = null)
|
||||
{
|
||||
return $this->config->get("log-viewer.$key", $default);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
| Main Methods
|
||||
| -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make level icon.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return \Illuminate\Support\HtmlString
|
||||
*/
|
||||
public function icon($level, $default = null)
|
||||
{
|
||||
return new HtmlString(
|
||||
'<i class="'.$this->get("icons.$level", $default).'"></i>'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get level color.
|
||||
*
|
||||
* @param string $level
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function color($level, $default = null)
|
||||
{
|
||||
return $this->get("colors.levels.$level", $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get strings to highlight.
|
||||
*
|
||||
* @param array $default
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toHighlight(array $default = [])
|
||||
{
|
||||
return $this->get('highlight', $default);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user