tos / logger
Convenție de logare
Requires
- php: ~7.0
- laravel/framework: 4.2.*
- symfony/stopwatch: ^3.4
- tos/support: 4.2.*
This package is auto-updated.
Last update: 2025-01-14 02:58:07 UTC
README
Instalare
Se instalează cu Composer
composer require tos/logger:~4.2
În fișierul app/config/app.php
:
- se comentează
Illuminate\Log\LogServiceProvider
- se adaugă
\TravelOS\Support\Logger\ServiceProvider::class
- sau un service provider propriu care-l extinde pe acesta
În final va fi de forma:
'Illuminate\Filesystem\FilesystemServiceProvider',
'Illuminate\Hashing\HashServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
- 'Illuminate\Log\LogServiceProvider',
+ // 'Illuminate\Log\LogServiceProvider',
+ \TravelOS\Support\Logger\ServiceProvider::class,
'Illuminate\Mail\MailServiceProvider',
'Illuminate\Database\MigrationServiceProvider',
'Illuminate\Pagination\PaginationServiceProvider',
În fișierul app/start/global.php
se comentează Log::useFiles(storage_path()
.'/logs/laravel.log');
, în final va fi de forma:
*
|--------------------------------------------------------------------------
| Application Error Logger
|--------------------------------------------------------------------------
|
| Here we will configure the error logger setup for the application which
| is built on top of the wonderful Monolog library. By default we will
| build a basic log file setup which creates a single file for logs.
|
*/
// Log::useFiles(storage_path().'/logs/laravel.log');
Configurare
Implicit va loga în app/storage/logs/laravel.log
doar dacă request-ul
întâmpină un WARNING
.
O linie de log va fi de forma
[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n
Dacă level
-ul, message
-ul și context
-ul sunt furnizate la folosire, în
extra
vor apărea informațiile generate de procesatoare.
Folosire
Se folosește trait-ul \TravelOS\Support\Logger\Traits\LoggerAware
în orice
clasă încărcată prin IoC.
Exemplu:
class LogTester
{
use \TravelOS\Support\Logger\Traits\LoggerAware;
Acum vom avea acces la metodele:
$this->debug($message, array $context = array())
$this->info($message, array $context = array())
$this->notice($message, array $context = array())
$this->warning($message, array $context = array())
$this->error($message, array $context = array())
- s.a.m.d.
Documentație
Handler-e
Se pot folosi oricare Handler-ele de Monolog
singurul extins este \TravelOS\Support\Logger\Handlers\Stream
care e adaptat
pentru StopWatcher.
Procesatoare
Este implicit încărcat cu 4 procesatoare care adaugă informație în spațiul
extra
.
Acestea sunt:
Environment
[2024-07-12 23:44:40] production.DEBUG : message [] {"env":"production"}
Adaugă env
-ul aplicației în linia fiecărui log. Util când se configurează mai
multe canale și channel
-ul nu mai corespunde cu env-ul.
Fingerprint
[2024-07-12 23:44:40] production.DEBUG : message [] {"fingerprint":1720827880.645}
Adaugă o semnătură unică a request-ului care a generat log-ul. Util când la un trafic mai mare în care log-urile sunt amestecate vrei să filtrezi doar liniile unui singur request.
StopWatch
Folosește Stopwatch Component pentru a putea parsa logurile și a injecta timpii de execuție ai unui proces.
Convenția de bază este sa se logheze o linie cu sufix-ul - start
, urmată de
altă logare cu sufix-ul - stop
, iar cea din urmă va genera un extra
cu timpul
și memoria folosite în acel interval.
Exemplu:
$this->debug('mesaj unic - start');
sleep(5);
$this->info('mesaj unic - stop');
Va genera următorul log:
[2024-07-13 00:26:05] production.DEBUG : mesaj unic - start [] []
[2024-07-13 00:26:10] production.INFO : mesaj unic - stop [] {"stopwatch":"5s - 8 MB"}
Threshold-ul
Pentru că doar linia de - stop
are informație utilă, am convenit ca ea să
aibă level INFO
pentru a o putea izola în Handler-e dacă dorim.
Dacă folosim sufix-ul - stop!
și procesul durează mai mult de 60s de când a
fost logat - start
-ul level-ul va fi transformat în WARNING
.
Exemplu:
$this->debug('mesaj unic - start');
sleep(61);
$this->info('mesaj unic - stop!');
Va genera următorul log:
[2024-07-13 00:33:45] production.DEBUG : mesaj unic - start [] []
[2024-07-13 00:34:46] production.WARNING: mesaj unic - stop! [] {"stopwatch":"1m 1s!!! - 8MB"}
Putem ajusta threshold-ul in secunde folosind sufix-ul - stop!30
Prefixările
Pentru a face logurile mai lizibile putem prefixa ierarhic liniile asemena unui backtrace.
Exemplu:
Avem un request în care se cer niște rapoarte pe baza informațiilor date.
Se vor petrece următoarele secvențe:
- validare date
- interogare DB
- generare raport
- trimitere email
- randare răspuns
Codul ar putea arăta așa:
public function generateReport()
{
try {
$this->getLogger()->lineBreak()->setPrefix('GenReport');
// $this->debug('test');
try {
$this->getLogger()->setPrefix('Validator');
$validator = \Validator::make([], []);
if($validator->fails()) {
$this->info('validare eșuată');
return Redirect::to('reportGenerator')->withErrors($validator);
}
$this->debug('date valide');
} finally {
$this->getLogger()->popPrefix();
}
$data = $this->getData();
$pdf = $this->generatePdf($data);
$this->sendEmail($pdf);
return $this->download($pdf);
} finally {
$this->getLogger()->popPrefix();
}
}
private function getData(): array
{
try {
$this->getLogger()->setPrefix('Repo');
$this->debug('aduc date user', [ 'user_id' => '10' ]);
sleep(1);
$data = [ 'data' ];
$this->debug('date aduse', [ 'count' => count($data) ]);
return $data;
} finally {
$this->getLogger()->popPrefix();
}
}
private function generatePdf( array $data ): string
{
try {
$this->getLogger()->setPrefix('PdfMaker');
$this->debug('generez raport', [ 'rows' => count($data) ]);
sleep(1);
$pdfPath = storage_path('report.pdf');
$this->debug('raport generat');
return $pdfPath;
} finally {
$this->getLogger()->popPrefix();
}
}
private function sendEmail( string $pdf )
{
try {
$this->getLogger()->setPrefix('Email');
$this->debug('trimit raport');
Mail::send('emails.report', [ 'key' => 'value' ],
function ( $message ) use ( $pdf ) {
$message->to('foo@example.com', 'John Smith')->subject('Welcome!')
->attach($pdf);
});
$this->debug('raport trimis');
} finally {
$this->getLogger()->popPrefix();
}
}
private function download( string $pdf )
{
try {
$this->debug('generez răspuns - start');
return Response::download($pdf);
} finally {
$this->debug('generez răspuns - stop');
}
}
Iar logul generat așa:
[2024-07-13 23:01:32] production.INFO : ________________________________________________________________________________ [] []
[2024-07-13 23:01:32] production.DEBUG : GenReport|Validator :: date valide [] []
[2024-07-13 23:01:32] production.INFO : GenReport :: Validator - done! [] {"stopwatch":"0ms - 2 MB"}
[2024-07-13 23:01:32] production.DEBUG : GenReport|Repo :: aduc date user {"user_id":"10"} []
[2024-07-13 23:01:33] production.DEBUG : GenReport|Repo :: date aduse {"count":1} []
[2024-07-13 23:01:33] production.INFO : GenReport :: Repo - done! [] {"stopwatch":"1s - 2 MB"}
[2024-07-13 23:01:33] production.DEBUG : GenReport|PdfMaker :: generez raport {"rows":1} []
[2024-07-13 23:01:34] production.DEBUG : GenReport|PdfMaker :: raport generat [] []
[2024-07-13 23:01:34] production.INFO : GenReport :: PdfMaker - done! [] {"stopwatch":"1s - 2 MB"}
[2024-07-13 23:01:34] production.DEBUG : GenReport|Email :: trimit raport [] []
[2024-07-13 23:01:34] production.INFO : GenReport|Email :: Pretending to mail message to: foo@example.com [] []
[2024-07-13 23:01:34] production.DEBUG : GenReport|Email :: raport trimis [] []
[2024-07-13 23:01:34] production.INFO : GenReport :: Email - done! [] {"stopwatch":"61ms - 4 MB"}
[2024-07-13 23:01:34] production.DEBUG : GenReport :: generez răspuns - start [] []
[2024-07-13 23:01:34] production.DEBUG : GenReport :: generez răspuns - stop [] {"stopwatch":"2ms - 4 MB"}
[2024-07-13 23:01:34] production.INFO : GenReport - done! [] {"stopwatch":"2s - 4 MB"}
Formatoare
Am extins LineFormatter
, acum aliniază level
-urile dintr-un log pentru a le
putea urmări mai ușor.