Daily archives: 20th April 2019


User interface for display of Laravel Logfiles

I was having a lot of problems displaying log files in the admin area of my application.  The Logfiles were being written to following each transaction, and a typical daily log file would be 10MB.

The best available packages would crash and burn with this size of logfile.

I tried both rap2hpoutre/laravel-log-viewer and arcanedev/log-viewer

Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use SplFileInfo;
use File;

class LogsController extends Controller
{
    public $perPage = 500;

    public function index()
    { 

        $files = $this->getLogfiles();

        return view('logs.index')->withFiles($files)->withLog([]);
    }

    public function show(Request $request, $index)
    {
        
        $files = $this->getLogfiles();
        
        $log = collect(file($files[$index]->getPathname(), FILE_IGNORE_NEW_LINES));
        
        $page = intval($request->get('page',1));
        
        $paginator['page'] = $page;
        $paginator['total'] = intval(floor($log->count() / $this->perPage))+1;

        $log=$log->slice(($page-1) * $this->perPage, $this->perPage);

        return view('logs.index')
            ->withFiles($files)
            ->withLog($log)
            ->withP($paginator)
            ->withIndex($index);
        
    }

    protected function getLogFiles()
    {
        $directory = storage_path('logs');

        $logFiles = collect(File::allFiles($directory))
            ->sortByDesc(function (SplFileInfo $file) {
                return $file->getMTime();
            });

        return $logFiles;
    }

}

View (Bootstrap 4 flavour)

@extends('layouts.app')

@section('content')
<div class="container-fluid">

    <h5 class="pt-3">Logs</h5 class="pt-3">

    <div class='row'>
        <div class='col-md-2'>
            <ul class='list-group'>
                @foreach($files as $key => $file)
                    <li class='list-group-item'><a href="{{ route('logs.show',$key) }}">{{ $file->getFilename() }}</a></li>
                @endforeach
            </ul>
        </div>
        <div class='col-md-10'>
            @if(isset($p))
            <ul class="pagination">
                <li class="page-item @if($p['page']==1) active @endif"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>1]) }}">First</a></li>

                @if($p['page']-4 > 1) <li class="page-item disabled"><a class="page-link"  href="#">&hellip;</a></li>@endif
                @if($p['page']-3 > 1) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']-3]) }}">{{ $p['page']-3 }}</a></li>@endif
                @if($p['page']-2 > 1) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']-2]) }}">{{ $p['page']-2 }}</a></li>@endif
                @if($p['page']-1 > 1) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']-1]) }}">{{ $p['page']-1 }}</a></li>@endif
                
                @if($p['page'] != 1 && $p['page'] != $p['total'] )
                    <li class="page-item active"><span class="page-link">{{ $p['page'] }}</span></li>
                @endif

                @if($p['page']+1 < $p['total']) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']+1]) }}">{{ $p['page']+1 }}</a></li>@endif
                @if($p['page']+2 < $p['total']) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']+2]) }}">{{ $p['page']+2 }}</a></li>@endif
                @if($p['page']+3 < $p['total']) <li class="page-item"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['page']+3]) }}">{{ $p['page']+3 }}</a></li>@endif
                @if($p['page']+4 < $p['total']) <li class="page-item disabled"><a class="page-link"  href="#">&hellip;</a></li>@endif

                @if($p['total']!=1)
                    <li class="page-item @if($p['page'] == $p['total']) active @endif"><a class="page-link" href="{{ route('logs.show',['index'=>$index, 'page'=>$p['total']]) }}">Last</a></li>
                @endif
            </ul>

            @endif

            <ul class='list-group list-group'>
                @foreach($log as $logline)
                        <li class='list-group-item small 
                            @if(Illuminate\Support\Str::contains($logline, '.CRITICAL:')) list-group-item-danger @endif
                            @if(Illuminate\Support\Str::contains($logline, '.ERROR:')) list-group-item-warning @endif
                            'style="padding: 0.25rem 1.25rem;">{{ $logline }}</li>
                @endforeach
            </ul>
        </div>
    </div>

</div>

@endsection

Routes

Route::get('/logs', 'LogsController@index')->name('logs');
Route::get('/logs/{index}', 'LogsController@show')->name('logs.show');

Preferably wrapped in Auth Middleware

Thats it.  Just add /logs to your navigation