Leitor de arquivos de log diários para aplicações Laravel.
Além da função primária, este package oferece paginação do conteúdo e dos arquivos de log, bem como leitura linha a linha de maneira transparente, possibilitando trabalhos com arquivos grandes sem carregá-los inteiramente em memória.
use Fcno\LogReader\Facades\RecordReader;
RecordReader::from(disk: 'file_system_name')
->infoAbout(log_file: 'filename.log')
->get();
⭐ Este package é destinado a leitura de arquivos de log diários gerados por aplicações Laravel. Utilizá-lo para leitura de outros tipos pode (e irá) trazer resultados equivocados.
⭐ Este package não provê views, visto que se trata de funcionalidade que seria, na prática, pouco aproveitada, dada as preferências pessoais de cada um. Portanto, a implementação das views fica a cargo do desenvolvedor da aplicação.
⬆️ Voltar
PHP ^8.0
Para uma checagem completa dos pré-requisitos:
-
Via Composer
composer require fcno/log-reader composer check-platform-reqs
⬆️ Voltar
-
Configurar um custom channel para definir os campos e os delimitadores dos registros de um arquivo de log diário
// config/logging.php 'channels' => [ ... 'custom' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), // de acordo com sua necessidade 'days' => 30, // de acordo com sua necessidade 'formatter' => Monolog\Formatter\LineFormatter::class, 'formatter_with' => [ 'format' => "#@#%datetime%|||%channel%|||%level_name%|||%message%|||%context%|||%extra%@#@\n", 'dateFormat' => 'd-m-Y H:i:s', ], ], ],
-
Definir a variável env LOG_CHANNEL para usar o channel criado
// .env LOG_CHANNEL=custom
-
Definir e configurar o disco em que os arquivos de log estão armazenados
// config/filesystems.php 'disks' => [ // ... 'disk_name' => [ 'driver' => 'local', 'root' => storage_path('logs'), // de acordo com sua necessidade ], ],
-
Instalar o package via composer:
composer require fcno/log-reader
⬆️ Voltar
Este package expôe três maneiras de interagir com os arquivos de log, cada uma por meio de uma Facade com objetivos específicos:
-
Responsável por manipular os arquivos (no padrão laravel-yyyy-mm-dd.log), sem contudo ler o seu conteúdo.
✏️ from
Assinatura e uso: informa ao package em que disco a aplicação armazena os arquivos de log
use Fcno\LogReader\Facades\LogReader; /** * @param string $disk nome do disco de log do File System * * @return static */ LogReader::from(disk: 'disk_name');
Retorno: Instância da classe LogReader
✏️ get
Assinatura e uso: Todos os arquivos de log do disco
use Fcno\LogReader\Facades\LogReader; /** * @throws \Fcno\LogReader\Exceptions\FileSystemNotDefinedException * * @return \Illuminate\Support\Collection */ LogReader::from(disk: 'disk_name') ->get();
Retorno: Collection com todos os arquivos de log do disco informado ordenados do mais recente para o mais antigo
// \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
Assinatura e uso: 5 arquivos de log da página 2, ou seja, do 6º ao 10º arquivos
use Fcno\LogReader\Facades\LogReader; /** * @param int $page número da página * @param int $per_page itens por página * * @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);
Retorno: Collection paginada com dados no mesmo formato do método get
Retornará uma Collection vazia ou com quantidade de itens menor que a esperada, caso a listagem dos arquivos já tenha chegado ao seu fim.
🚨 Exceptions:
-
O método get lança:
- \Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
O método paginate lança:
-
\Fcno\LogReader\Exceptions\InvalidPaginationException caso $page ou $per_page sejam menores que 1
-
\Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
⬆️ Voltar
-
-
Responsável por ler o conteúdo (registros / records) do arquivo de log.
O registro (record) é o nome dado ao conjunto de informações que foram adicionadas ao log para registrar dados sobre um evento de interesse.
Um arquivo de log pode conter um ou mais registros e, dada a sua infinidade, podem ser paginados a critério do desenvolvedor da aplicação.
✏️ from
Assinatura e uso: informa ao package em que disco a aplicação armazena os arquivos de log
use Fcno\LogReader\Facades\RecordReader; /** * @param string $disk nome do disco de log do File System * * @return static */ RecordReader::from(disk: 'disk_name');
Retorno: Instância da classe RecordReader
✏️ infoAbout
Assinatura e uso: informa ao package qual arquivo de log deve ser trabalhado
use Fcno\LogReader\Facades\RecordReader; /** * @param string $log_file nome do arquivo de log que que será trabalhado * * @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');
Retorno: Instância da classe RecordReader
✏️ get
Assinatura e uso: Todos os registros do arquivo de log
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();
Retorno: Collection com todos os registros do arquivo de log
// \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
Assinatura e uso: 5 registros da página 2 do arquivo de log, ou seja, do 6º ao 10º
use Fcno\LogReader\Facades\RecordReader; /** * @param int $page número da página * @param int $per_page itens por página * * @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);
Retorno: Collection paginada com dados no mesmo formato do método get
Retornará uma Collection vazia ou com quantidade de itens menor que a esperada, caso os registros já tenham chegado ao seu fim.
Os registros são exibidos na ordem em que estão gravados no arquivo. Não existe ordenação alguma feita por este package.
🚨 Exceptions:
-
O método infoAbout lança:
-
Fcno\LogReader\Exceptions\FileNotFoundException caso o arquivo não seja encontrado;
-
Fcno\LogReader\Exceptions\NotDailyLogException caso o aquivo não seja no padrão laravel-yyy-mm-dd.log.
-
\Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
-
O método get lança:
- \Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
O método paginate lança:
-
\Fcno\LogReader\Exceptions\InvalidPaginationException caso $page ou $per_page sejam menores que 1
-
\Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
⬆️ Voltar
-
-
Responsável por ler o conteúdo (registros / records) do arquivo de log e gerar um sumário.
O sumário (summary) é o nome dado a contabilização dos registros (records) por nível, isto é, a quantidade de registros do tipo debug, info, notice etc.
✏️ from
Assinatura: informa ao package em que disco a aplicação armazena os arquivos de log
use Fcno\LogReader\Facades\SummaryReader; /** * @param string $disk nome do disco de log do File System * * @return static */ SummaryReader::from(disk: 'disk_name');
Retorno: Instância da classe SummaryReader
✏️ infoAbout
Assinatura e uso: informa ao package qual arquivo de log deve ser trabalhado
use Fcno\LogReader\Facades\SummaryReader; /** * @param string $log_file nome do arquivo de log que que será trabalhado * * @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
Assinatura e uso: Sumário de todos os registros do arquivo de log, bem como a sua data
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();
Retorno: Collection com o sumário de todos os registros do arquivo de log informado bem como a sua data, isto é, a quantidade de ocorrências dos diversos níveis de log presentes no arquivo, bem como a data de suas ocorrências
// \Illuminate\Support\Collection; [ "alert" => 5, "debug" => 10, "date" => "2021-12-27" ], [ "emergency" => 1, "info" => 5, "warning" => 10, "date" => "2021-12-26" ]
Este package não possui cravado em seu código a necessidade de os níveis de log da aplicação serem aderentes à PSR-3. Contudo, é considerado boa prática implementar esse tipo de padrão na aplicação.
Níveis que não possuírem registros, não serão retornados (contabilizados) na Coleção.
A data, no padrão yyyy-mm-dd, retornada é a presente no primeiro registro. Parte-se do princípio que todos os registros do arquivo foram gerados no mesmo dia, visto que este package destina-se aos logs diários.
🚨 Exceptions:
-
O método infoAbout lança:
-
Fcno\LogReader\Exceptions\FileNotFoundException caso o arquivo não seja encontrado;
-
Fcno\LogReader\Exceptions\NotDailyLogException caso o aquivo não seja no padrão laravel-yyy-mm-dd.log.
-
\Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
-
-
O método get lança:
- \Fcno\LogReader\Exceptions\FileSystemNotDefinedException caso o método seja acionado sem previamente se definir o disco do File System
⬆️ Voltar
-
composer analyse
composer test
composer test-coverage
⬆️ Voltar
Por favor, veja o CHANGELOG para maiores informações sobre o que mudou em cada versão.
⬆️ Voltar
Por favor, veja CONTRIBUTING para maiores detalhes.
⬆️ Voltar
Para garantir que todos são bem vindos a contribuir com esse projeto open-source, por favor leia e cumpra o Código de Conduta.
⬆️ Back
Por favor, veja na política de segurança como reportar vulnerabilidades ou falha de segurança.
⬆️ Voltar
A versão mais recente receberá suporte e atualizações sempre que houver necessidade. As demais receberão apenas atualizações para corrigir vulnerabilidades de segurança por até 06 meses após ela ter sido substituída por uma nova versão.
🐛 Encontrou um bug?!?! Abra um issue.
✨ Alguma ideia nova?!?! Inicie uma discussão.
⬆️ Voltar
⬆️ Voltar
👋 Agradeço às pessoas e organizações abaixo por terem doado seu tempo na construção de projetos open-source que foram usados neste package.
-
❤️ Laravel pelos packages:
-
❤️ Spatie pelos packages:
-
❤️ Orchestra Platform pelo package orchestral/testbench
-
❤️ Nuno Maduro pelos packages:
-
❤️ PEST pelos packages:
-
❤️ Benjamin Cremer pelo package bcremer/LineReader
-
❤️ Jordi Boggiano pelo package Seldaek/monolog
-
❤️ Sebastian Bergmann pelo package sebastianbergmann/phpunit
-
❤️ FakerPHP pelo package FakerPHP/Faker
-
❤️ PHPStan pelos packages:
💸 Algumas dessas pessoas ou organizações possuem alguns produtos/serviços que podem ser comprados. Se você puder ajudá-los comprando algum deles ou se tornando um patrocinador, mesmo que por curto período, ajudará toda a comunidade open-source a continuar desenvolvendo soluções para todos.
⬆️ Voltar
The MIT License (MIT). Por favor, veja o License File para maiores informações.
⬆️ Voltar