Skip to content

Latest commit

 

History

History
675 lines (434 loc) · 19.5 KB

README-en.md

File metadata and controls

675 lines (434 loc) · 19.5 KB

Log Reader for Laravel Applications

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads


English 🔹 Português


Daily log file reader for Laravel applications.

In addition to the primary function, this package offers pagination for both, content and log files, as well a transparent line-by-line reading, making it possible to work with large files without loading them entirely into memory.

use Fcno\LogReader\Facades\RecordReader;

RecordReader::from(disk: 'file_system_name')
            ->infoAbout(log_file: 'filename.log')
            ->get();

 


Table of contents

  1. Notes

  2. Requirements

  3. Installation

  4. How it works

    1. LogReader

    2. RecordReader

    3. SummaryReader

  5. Testing and Continuous Integration

  6. Changelog

  7. Contribution

  8. Code of Conduct

  9. Security Vulnerabilities

  10. Support and Updates

  11. Credits

  12. Thanks

  13. License


Notes

⭐ This package is intended for reading daily log files generated by Laravel applications. Using it for reading other types can (and will) give erroneous results.

⭐ This package does not provide views, as it is a feature that would, in practice, be little used, given the personal preferences of each one. Therefore, the implementation of views is up to the application developer.

⬆️ Back

 

Requirements

PHP ^8.0

For a full requirements check:

  1. Via Composer

    composer require fcno/log-reader
    composer check-platform-reqs
  2. Via GitHub Dependencies

⬆️ Back

 

Installation

  1. Set up a custom channel to define fields and delimiters for records in a daily log file

    // config/logging.php
    
    'channels' => [
        ...
        'custom' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => env('LOG_LEVEL', 'debug'), // according to your need
            'days' => 30,                         // according to your need
            'formatter' => Monolog\Formatter\LineFormatter::class,
            'formatter_with' => [
                'format' => "#@#%datetime%|||%channel%|||%level_name%|||%message%|||%context%|||%extra%@#@\n",
                'dateFormat' => 'd-m-Y H:i:s',
            ],
        ],
    ],

     

  2. Set the LOG_CHANNEL env variable to use the channel created

    // .env
    LOG_CHANNEL=custom

     

  3. Define and set up the disk where log files are stored

    // config/filesystems.php
    
    'disks' => [
        // ...
        'disk_name' => [
            'driver' => 'local',
            'root' => storage_path('logs'), // according to your need
        ],
    ],

     

  4. Install package via composer:

    composer require fcno/log-reader

⬆️ Back

 

How it works

This package exposes three ways to interact with log files, each through a Facade with specific goals:

 

  1. Fcno\LogReader\Facades\LogReader

    Responsible for manipulating the files (in the pattern laravel-yyyy-mm-dd.log), without reading their content.

    ✏️ from

    Signature and usage: tells package which disk the application stores log files on

    use Fcno\LogReader\Facades\LogReader;
    
    /**
     * @param string $disk File System log disk name
     * 
     * @return static
     */
    LogReader::from(disk: 'disk_name');

     

    Return: Instance of class LogReader

     

    ✏️ get

    Signature and Usage: All log files on disk

    use Fcno\LogReader\Facades\LogReader;
    
    /**
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return \Illuminate\Support\Collection
     */
    LogReader::from(disk: 'disk_name')
                ->get();

     

    Return: Collection with all log files on disk informed sorted from newest to oldest

    // \Illuminate\Support\Collection;
    [
        0 => "laravel-2021-12-27.log",
        1 => "laravel-2021-12-26.log",
        2 => "laravel-2021-12-25.log",
        3 => "laravel-2021-12-24.log",
        4 => "laravel-2021-12-23.log",
        5 => "laravel-2021-12-22.log",
        6 => "laravel-2021-12-21.log",
        7 => "laravel-2021-12-20.log",
        8 => "laravel-2021-12-19.log",
        9 => "laravel-2021-12-18.log",
        // ...
    ]

     

    ✏️ paginate

    Signature and usage: 5 log files from page 2, ie 6th to 10th files

    use Fcno\LogReader\Facades\LogReader;
    
    /**
     * @param int  $page page number
     * @param int  $per_page items per page
     * 
     * @throws \Fcno\LogReader\Exceptions\InvalidPaginationException
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return \Illuminate\Support\Collection
     */
    LogReader::from(disk: 'disk_name')
                ->paginate(page: 2, per_page: 5);

     

    Return: Collection paged with data in the same format as the get method

    It will return an empty Collection or with a smaller number of items than expected, if the list of files has already reached its end.

     

    🚨 Exceptions:

    • Method get throws:

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System
    • Method paginate throws:

      • \Fcno\LogReader\Exceptions\InvalidPaginationException if $page or $per_page are less than 1

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System

    ⬆️ Back

     


     

  2. Fcno\LogReader\Facades\RecordReader

    Responsible for reading the contents (records) from the log file.

    The record is the name given to the set of information that was added to the log in order to record data about an event of interest.

    A log file can contain one or more records and, given its infinity, can be paged at the discretion of the application developer.

    ✏️ from

    Signature and usage: tells package which disk the application stores log files on

    use Fcno\LogReader\Facades\RecordReader;
    
    /**
     * @param string $disk File System log disk name
     * 
     * @return static
     */
    RecordReader::from(disk: 'disk_name');

     

    Return: Instance of class RecordReader

     

    ✏️ infoAbout

    Signature and usage: tells package which log file should be worked on

    use Fcno\LogReader\Facades\RecordReader;
    
    /**
     * @param string  $log_file name of the log file that will be worked on
     * 
     * @throws \Fcno\LogReader\Exceptions\FileNotFoundException
     * @throws \Fcno\LogReader\Exceptions\NotDailyLogException
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return static
     */
    RecordReader::from(disk: 'disk_name')
                ->infoAbout(log_file: 'filename.log');

     

    Return: Instance of class RecordReader

     

    ✏️ get

    Signature and Usage: All log file records

    use Fcno\LogReader\Facades\RecordReader;
    
    /**
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return \Illuminate\Support\Collection
     */
    RecordReader::from(disk: 'disk_name')
                ->infoAbout(log_file: 'filename.log')
                ->get();

     

    Return: Collection with all log file records

    // \Illuminate\Support\Collection;
    [
        "date" => "2021-12-27",
        "time" => "03:05:08",
        "env" => "production",
        "level" => "emergency",
        "message" => "Lorem ipsum dolor sit amet.",
        "context" => "Donec ultrices ex libero, ut euismod dui vulputate et. Quisque et vestibulum eros, quis dapibus ipsum.",
        "extra" => ""
    ],
    [
        "date" => "2021-12-27",
        "time" => "04:05:08",
        "env" => "local",
        "level" => "info",
        "message" => "Donec imperdiet dapibus facilisis.",
        "context" => "Integer sollicitudin, mauris sit amet luctus finibus, arcu lorem fringilla velit, eget scelerisque ex metus in ante.",
        "extra" => "velit"
    ]

     

    ✏️ paginate

    Signature and usage: 5 records from page 2 of the log file, ie 6th to 10th

    use Fcno\LogReader\Facades\RecordReader;
    
    /**
     * @param int  $page page number
     * @param int  $per_page items per page
     * 
     * @throws \Fcno\LogReader\Exceptions\InvalidPaginationException
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return \Illuminate\Support\Collection
     */
    RecordReader::from(disk: 'disk_name')
                ->infoAbout(log_file: 'filename.log')
                ->paginate(page: 2, per_page: 5);

     

    Return: Collection paged with data in the same format as the get method

    It will return an empty Collection or with a smaller number of items than expected, if the list of files has already reached its end.

    The records are displayed in the order they are written to the file. There is no sorting done by this package.

     

    🚨 Exceptions:

    • Method infoAbout throws:

      • Fcno\LogReader\Exceptions\FileNotFoundException if the file is not found;

      • Fcno\LogReader\Exceptions\NotDailyLogException if the file is not in the pattern laravel-yyy-mm-dd.log.

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System

    • Method get throws:

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System
    • Method paginate throws:

      • \Fcno\LogReader\Exceptions\InvalidPaginationException if $page or $per_page are less than 1

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System

    ⬆️ Back

     


     

  3. Fcno\LogReader\Facades\SummaryReader

    Responsible for reading the content (records) from the log file and generating a summary.

    The summary is the name given to the count of records by level, ie, the amount of records of the type debug, info, notice etc.

     

    ✏️ from

    Signature and usage: tells package which disk the application stores log files on

    use Fcno\LogReader\Facades\SummaryReader;
    
    /**
     * @param string $disk File System log disk name
     * 
     * @return static
     */
    SummaryReader::from(disk: 'disk_name');

     

    Return: Instance of class SummaryReader

     

    ✏️ infoAbout

    Signature and usage: tells package which log file should be worked on

    use Fcno\LogReader\Facades\SummaryReader;
    
    /**
     * @param string  $log_file name of the log file that will be worked on
     * 
     * @throws \Fcno\LogReader\Exceptions\FileNotFoundException
     * @throws \Fcno\LogReader\Exceptions\NotDailyLogException
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return static
     */
    SummaryReader::from(disk: 'disk_name')
                    ->infoAbout(log_file: 'filename.log');

     

    ✏️ get

    Signature and Usage: Summary of all log file records as well as their date

    use Fcno\LogReader\Facades\SummaryReader;
    
    /**
     * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException
     * 
     * @return \Illuminate\Support\Collection
     */
    SummaryReader::from(disk: 'disk_name')
                    ->infoAbout(log_file: 'filename.log')
                    ->get();

     

    Return: Collection with the summary of all records of the log file informed as well as their date, that is, the amount of occurrences of the various log levels present in the file, as well as the date of their occurrences

    // \Illuminate\Support\Collection;
    [
        "alert" => 5,
        "debug" => 10,
        "date" => "2021-12-27"
    ],
    [
        "emergency" => 1,
        "info" => 5,
        "warning" => 10,
        "date" => "2021-12-26"
    ]

     

    This package does not have embedded in its code the need for the application's log levels to adhere to PSR-3. However, it is considered good practice to implement this type of pattern in the application.

    Levels that do not have records will not be returned (counted) in the Collection.

    The date, in the pattern yyyy-mm-dd, returned is the one present in the first record. It is assumed that all logs in the file were generated on the same day as this package is for daily logs.

     

    🚨 Exceptions:

    • Method infoAbout throws:

      • Fcno\LogReader\Exceptions\FileNotFoundException if the file is not found;

      • Fcno\LogReader\Exceptions\NotDailyLogException if the file is not in the pattern laravel-yyy-mm-dd.log.

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System

    • Method get throws:

      • \Fcno\LogReader\Exceptions\FileSystemNotDefinedException if the method is called without previously set the disk of the File System

    ⬆️ Back

     

Testing and Continuous Integration

composer analyse
composer test
composer test-coverage

⬆️ Back

 

Changelog

Please see the CHANGELOG for more information on what has changed in each release.

⬆️ Back

 

Contribution

Please see CONTRIBUTING for details.

⬆️ Back

 

Code of Conduct

In order to ensure that everyone is welcome to this open-source project, please review and abide by the Code of Conduct.

⬆️ Back

 

Security Vulnerabilities

Please see our security policy on how to report security vulnerabilities.

⬆️ Back

 

Support and Updates

The latest version will be supported and updated as needed. The others will only receive updates to fix security vulnerabilities for up to 06 months after it has been replaced by a new version.

🐛 Found a bug?!?! Open a issue.

✨ Any new ideas?!?! Start a discussion.

⬆️ Back

 

Credits

⬆️ Back

 

Thanks

👋 Thanks to the people and organizations below for taking the time to build open-source projects that were used in this package.

💸 Some of these people or organizations have some products/services that can be purchased. If you can help them by purchasing one of them or becoming a sponsor, even for a short period, it will help the entire open-source community to continue developing solutions for everyone.

⬆️ Back

 

License

The MIT License (MIT). Please see License File for more information.

⬆️ Back