Nafies Luthfi

Life will always feel wonderful if we always think positively.

Membuat Log Viewer Laravel

Kita sering mengalami kesulitan untuk melihat error log aplikasi Laravel ketika aplikasi sudah di deploy ke production server, baik di VPS ataupun di Shared Hosting. Terutama pada saat ada laporan dari user misalkan :
“Mas, ada error ketika membuka halaman ini.” atau “Ada bug nih waktu submit form ini tetapi ininya ga diisi.”

Biasanya hal-hal seperti ini baru kita temukan pada saat aplikasi sudah digunakan oleh usernya (waktu kita bikin sih rasanya baik-baik aja, hehe).

Nah pada saat dapat laporan itu, biasanya saya login ke VPS atau cPanel Shared Hosting, lalu mengecek error log web server dan log di laravel yang ada di direktori storage/logs. Dan menelusuri file log untuk menemukan problem yang dimaksud.

Sebenarnya bagi sebagian orang ini ga terlalu merepotkan sih, tetapi bagi saya ini lumayan repot karena harus melihat catatan akun login VPS atau cPanel nya.

Lalu untuk meminimalisir ini, di aplikasi laravel, kita akan coba buat sebuah halaman untuk :

  • Menampilkan daftar file log Laravel perhari
  • Melihat isi file log
  • Men-download file log (Save As)

Nanti tampilannya lebih kurang seperti ini:

Laravel Log Viewer 01

Tahap Pengerjaan

  1. Membuat Route dan Controller untuk menampilkan daftar Log
  2. Membuat View list File Log
  3. Membuat Route dan controller untuk menampilkan Isi File Log
  4. Membuat Route dan controller untuk download File Log
  5. Mengatur Config untuk Log Harian

Oke, kita langsung buat sama-sama.

1. Route dan Controller untuk List File Log

Kita buat Route log-files pada file routes/web.php

<?php
// routes/web.php

Route::get('log-files', [
    'as' => 'log-files.index',
    'uses' => 'LogFilesController@index'
]);

Kemudian buat Controller dengan nama LogFilesController dan method index untuk membaca isi direktori storage/logs.

<?php
// app/Http/Controllers/LogFilesController.php

namespace App\Http\Controllers;

class LogFilesController extends Controller
{
    public function index()
    {
        if (!file_exists(storage_path('logs'))) {
            return [];
        }

        $logFiles = \File::allFiles(storage_path('logs'));

        // Sort files by modified time DESC
        usort($logFiles, function ($a, $b) {
            return -1 * strcmp($a->getMTime(), $b->getMTime());
        });

        return view('log-files', compact('logFiles'));
    }
}

2. View untuk List File Log

Sesuai dengan Controller diatas, kita buat view dengan nama log-files.blade.php pada direktori resources/views

3. Route dan controller Method untuk Melihat Isi File

Kita buat Route log-files/{filename} pada file routes/web.php

<?php
// routes/web.php

// Route List File
Route::get('log-files', [
    'as' => 'log-files.index', 
    'uses' => 'LogFilesController@index'
]);

// Route melihat isi File
Route::get('log-files/{filename}', [
    'as' => 'log-files.show', 
    'uses' => 'LogFilesController@show'
]);

Kita lanjutkan LogFilesController dengan script berikut :

<?php
// app/Http/Controllers/LogFilesController.php

namespace App\Http\Controllers;

class LogFilesController extends Controller
{
    // index method..

    public function show($fileName)
    {
        if (file_exists(storage_path('logs/'.$fileName))) {
            $path = storage_path('logs/'.$fileName);

            return response()->file($path, ['content-type' => 'text/plain']);
        }

        return 'Invalid file name.';
    }
}

4. Route dan controller Method untuk Download File

Untuk download filenya sebenarnya tidak terlalu penting, yang penting kita bisa lihat filenya langsung dari aplikasi.

Tapi siapa tau diperlukan, kita buat saja. Route log-files/{filename}/download pada file routes/web.php

<?php
// routes/web.php

// Route List File
Route::get('log-files', [
    'as' => 'log-files.index', 
    'uses' => 'LogFilesController@index'
]);

// Route melihat isi File
Route::get('log-files/{filename}', [
    'as' => 'log-files.show', 
    'uses' => 'LogFilesController@show'
]);

// Route Download File
Route::get('log-files/{filename}/download', [
    'as' => 'log-files.download', 
    'uses' => 'LogFilesController@download'
]);

Oke kita buatkan method untuk actionnya di LogFilesController :

<?php
// app/Http/Controllers/LogFilesController.php

namespace App\Http\Controllers;

class LogFilesController extends Controller
{
    // index method..
    
    // show method..

    public function download($fileName)
    {
        if (file_exists(storage_path('logs/'.$fileName))) {
            $path = storage_path('logs/'.$fileName);
            $downloadFileName = env('APP_ENV').'.'.$fileName;

            return response()->download($path, $downloadFileName);
        }

        return 'Invalid file name.';
    }
}

5. Mengatur Config untuk Log Harian

Oke setelah langkah di atas, seharusnya jika kita mengakses route /log-files kita akan mendapatkan tampilan seperti berikut:

Laravel Log Viewer 02

Dengan kondisi ini, kita akan repot melihat log karena log digabung dalam 1 file default bernama storage/logs/laravel.log

Untuk mempermudah troubleshoot kita atur konfigurasi log agar file log dibuat per hari. Caranya seperti ini:

Buka file config/app.php, kemudian pada bagian log ganti dengan config seperti ini :

<?php
// config/app.php

    // sekitar baris ke 123
    // 'log' => env('APP_LOG', 'single'),

    // Ganti log menjadi per hari
    'log' => 'daily',

    // Agar jumlah maksimum log untuk 30 hari
    'log_max_files' => 30,

    'log_level' => env('APP_LOG_LEVEL', 'debug'),

Setelah langkah di atas, seharusnya jika kita mengakses route /log-files kita akan mendapatkan tampilan seperti berikut :

Laravel Log Viewer 03

Oke, sampai di sini tutorial pembuatan Laravel Log Viewer, mudah-mudahan dapat membantu teman-teman yang punya kesulitan yang serupa dengan saya.

Contoh implementasi untuk Log Viewer ini sudah diterapkan pada aplikasi Grosir Obat yang saya buat. Bisa teman-teman lihat di commit ini

Terima kasih untuk waktunya.