Příručka:Strukturované protokolování
| Verze MediaWiki: | ≥ 1.25 |
Strukturované logování je provozní (ladicí) logování, které obsahuje strukturovaná data pro snazší následné zpracování. Liší se od Příručka:Přihlášení do Special:Log, který slouží k logování pro editory wiki. Strukturované logování je pro vývojáře.
Od verze MediaWiki 1.25 je pro jádro a rozšíření MediaWiki k dispozici [standard protokolování http://www.php-fig.org/psr/psr-3/ PSR-3], který nahrazuje zastaralá volání protokolování ladění wfDebug a wfDebugLog.
Standard PSR-3 umožňuje připojit pole kontextových dat ke každé zprávě protokolu, čímž vznikají strukturované páry klíč-hodnota.
Získejte logger z LoggerFactory
use MediaWiki\Logger\LoggerFactory;
$logger = LoggerFactory::getInstance( 'MyCoolLoggingChannel' );
Parametr předaný proměnné LoggerFactory::getInstance (zde MyCoolLoggingChannel) je název kanálu protokolu.
Způsob použití názvu kanálu závisí na konfiguraci protokolování (viz níže), ale obvykle lze samostatné kanály protokolování směrovat do samostatných souborů nebo podobně.
Jako název kanálu byste měli použít něco jedinečného (obvykle název vaší linky), aby se snáze oddělily nesouvisející položky protokolu.
Odesílat zprávy protokolu
Jakmile máte objekt loggeru, můžete k protokolování zpráv použít jeho metodu odpovídající úrovním závažnosti PSR-3:
$logger->debug( 'Entered ' . __METHOD__ )- Jde o zprávy, které jsou užitečné pro lokální vývoj a obecně jsou příliš "spamové" na to, aby se zobrazovaly na produkční wiki. To by obvykle zahrnovalo cokoli, co se aktuálně zaznamenává přes
wfDebug. $logger->info( 'Restoring page' )- Cenné informace o změně stavu. Tato úroveň je skvělým místem pro zaznamenávání informací, které by byly užitečné v produkčním prostředí při trasování cesty požadavku, u kterého nakonec došlo k chybě. Toto je v současné době úroveň automaticky spojená s voláními
wfDebugLogpři mapování na PSR-3. $logger->warning( 'Page is protected' )- Měkká chyba, jako je například opravitelná chyba nebo jiná podmínka, která by obvykle neměla nastat, ale nezastavuje probíhající operaci.
$logger->error( 'Page not found' )- Závažná chyba, například zachycená výjimka bez cesty k obnově.
Standard PSR-3 zahrnuje i další úrovně závažnosti, nicméně jejich použití v MediaWiki se nedoporučuje.
Přidat strukturovaná data do kontextu protokolování
Všechny metody protokolování berou volitelné kontextové pole, například:
$logger->warning( 'page not found', [ 'user' => $user->getName(), 'title' => $page->getPrefixedText() ] );
Do zpráv protokolu v tomto kontextovém objektu byste měli přidat užitečné strukturované informace, které ostatní mohou použít k nalezení souvisejících zpráv nebo relevantních záznamů v databázi a k vysledování příčiny chyby.
Toto je obzvláště důležité a užitečné pro zprávy úrovně warning a error, kde operátor wiki nemusí být obeznámen s cestou kódu a potřebuje být schopen podat kvalitní hlášení o chybě.
- Pokud v parametru context předáte objekt
Exception, MUSÍ být v klíčiexception(např.$logger->error( 'got exception', [ 'exception' => $e ] )). [1]- Objekt výjimky můžete také vygenerovat za běhu, což je dobrý způsob, jak připojit trasování zásobníku, např. při protokolování chyby v utilitní funkci, která je vyvolána na mnoha místech:
$logger->warning( 'called with a user which does not exist', [ 'user' => $user->getName(), 'exception' => new RuntimeException() ] )
- Objekt výjimky můžete také vygenerovat za běhu, což je dobrý způsob, jak připojit trasování zásobníku, např. při protokolování chyby v utilitní funkci, která je vyvolána na mnoha místech:
- Připojte k zprávám parametry nebo jiný zajímavý stav. Nejlepší je ujistit se, že položky v kontextovém poli jsou řetězce. (Mohou být povoleny i jiné typy v závislosti na logovací službě, kterou wiki používá, ale chování pro neřetězcové hodnoty je často neintuitivní.) Mnoho základních tříd MediaWiki má metodu
__toString, která generuje popis objektu vhodný pro ladění, takže stačí použít například(string)$titleValue.- Pokud předáváte hodnoty, které nejsou řetězcové, zkuste použít přiměřeně jedinečné názvy polí. Toto je potřeba hlavně pro produkci Wikimedie, která odesílá kontextová data do Logstashu, což vyžaduje, aby všechna kontextová data používající stejný klíč byla stejného typu (všeobecně, napříč všemi kanály protokolu).
- Standardní parametry (název wiki, název serveru atd.) budou přidány automaticky. Podrobnosti závisí na tom, jakou logovací službu používáte, ale pravděpodobně nakonec použijete MediaWiki\Logger\Monolog\WikiProcessor.
- Nahraďte falešné struktury, jako jsou položky oddělené tabulací, páry label=value/label:value nebo serializace JSON.
Mnoho agregátorů protokolů se snaží deduplikovat protokoly podle zprávy, proto se snažte vyloučit proměnlivé detaily ze zprávy a přesunout je do kontextu. Logger nahradí všechny tokeny uvnitř složených závorek odpovídající hodnotou z kontextu. Například kód
$logger->error( 'Caught exception while trying to create user {user}: {exception}', [
'user' => $user->getName(),
'exception' => $e,
] );
bude mít za následek něco jako
Caught exception while trying to create user Foo: exception DatabaseException with message 'Unique constraint violation' in /srv/mediawiki/includes/Database.php:123
#0 /srv/mediawiki/includes/Database.php(456): Database::query()
...
Pro maximální kompatibilitu s různými backendy pro protokolování nepoužívejte tyto klíče v kontextových datech:
messagechannelhostleveltype@timestamp@version
Používejte objekty kompatibilní s PSR-3
Vyvolávejte výjimky, které implementují třídu INormalizedException (nebo pokud nepotřebujete vlastní třídu výjimek, použijte třídu NormalizedException), aby bylo možné související zprávy o výjimkách seskupit v protokolech.
Objekty Status a StatusValue můžete převést do protokolování PSR-3 pomocí:
$statusFormatter = MediaWikiServices::getInstance()->getFormatterFactory()->getStatusFormatter( RequestContext::getMain() );
[ $message, $context ] = $statusFormatter->getPsr3MessageAndContext( $status );
$logger->error( $message, $context );
Tohle je snaha o maximum – status má nepřehlednou vnitřní strukturu, takže někdy to skončí jen s něčím jako [ '{message}', 'message' => '...the error message in the Status object' ]. Ale u statusů obsahujících jednu zprávu to vede k pěkným řetězcům zpráv, které se snadno seskupují.
Konfigurace wiki pro strukturované logování
Z důvodu zpětné kompatibility, pokud používáte výchozí konfiguraci MediaWiki a máte nakonfigurované základní logování, pak se informace v kontextovém objektu nezobrazí v nakonfigurovaných souborech logu, ať už dodáte kontextový objekt těmto metodám logování nebo globálním funkcím MediaWiki, jako je wfDebugLog( 'myChannel', $someMessage, 'private', $someContext ).
Měli byste implementovat lepší logger, například monolog, jako "rozhraní poskytovatele služeb" loggeru.
Podívejte se na $wgMWLoggerDefaultSpi a Manual:MonologSpi.
Související odkazy
- Requests for comment/Structured logging
- Standard protokolování PSR-3
- Příručka:Jak řešit chyby
- wikitech:logstash - Wikimediae ukládá většinu svých logů z MediaWiki do logstash, který rozumí strukturovanému logování.