v13.39.0. Zie Logging voor de basisbediening en Packageontwikkeling voor het voorbereiden van de provider.
Kies het juiste uitbreidingspunt
Als het met een bestaande driver kan, hoef je geen eigen driver toe te voegen.
De klassen voor
via en tap worden via de container geresolved, dus je kunt ook constructor-injectie gebruiken. tap is een aanpassing bij het aanmaken van het channel, geen hook die bij elke geschreven logregel wordt uitgevoerd.
De
audit in logging.channels.audit is de channelnaam. De driver daarin is de naam van de aanmaakmethode. Met Log::channel('audit') kies je de channelnaam, zodat de aanroepende kant dezelfde naam kan blijven gebruiken, ook als je later de driver wijzigt.Publiceer eerst een factory met custom en via
In het fictieve packageAcme\Audit bieden we een factory voor bestandsoutput aan. Plaats die in src/Logging/CreateAuditLogger.php, zodat hij via PSR-4 kan worden geladen.
channels-array in config/logging.php. Laat bestaande instellingen zoals default en stack staan.
LogManager::createCustomDriver() haalt de via-klasse uit de container en roept die aan met de configuratie-array van het channel als enige argument. Met alleen deze aanpak heb je geen provider nodig om een driver te registreren.
level expliciet door aan de StreamHandler. LogManager past de level uit de configuratie niet automatisch toe op de logger die een custom-factory teruggeeft. Ook als je eigen configuratie-opties toevoegt, verwerk je die in de factory.
Gebruik extend om een eigen drivernaam aan te bieden
Als je de gebruikende kant een instelling alsdriver: acme-audit wilt bieden, registreer je een driver die dezelfde factory gebruikt. Breid in boot() van src/AuditServiceProvider.php de log-service van Laravel uit.
channels.audit door de volgende configuratie in plaats van de vorige. via is dan niet meer nodig.
- De
LogServiceProvidervan Laravel registreertlogals singleton.callAfterResolving()wacht als de service nog niet is geresolved, en past de registratie ook toe op de instantie als die al is geresolved. Zie Hooks na het resolven van services voor details. extend()registreert alleen de closure die de logger aanmaakt. Bij het registreren van deze callback wordt er nog geen channel aangemaakt of log geschreven.callCustomCreator()geeft$appen de configuratie-array van het channel door aan de closure. Dat zijn andere argumenten dan die aan devia-factory worden doorgegeven.- Een driver met dezelfde naam opnieuw registreren overschrijft de aanmaakclosure. Gebruik geen ingebouwde namen zoals
singleof namen die met andere packages botsen.
logging.default of de volledige bestaande logging.channels niet overschrijft.
Channels worden per naam vastgehouden
LogManager::get() slaat geresolvede channels op in $channels. Als je een channel met dezelfde naam opnieuw ophaalt, wordt de configuratie-array niet opnieuw gelezen, maar krijg je het vastgehouden object terug.
Dit staat los van de configuratiecache die in een bestand wordt opgeslagen: het gaat om het vasthouden van objecten binnen de huidige LogManager. Alleen config() wijzigen of extend() opnieuw registreren vervangt reeds aangemaakte Handlers niet.
$same hetzelfde object als $before. Zodra forgetChannel('audit') het vasthouden in de Manager opheft, wordt bij de volgende aanroep $after aangemaakt op basis van de nieuwe configuratie.
forgetChannel werkt bestaande referenties niet bij
forgetChannel() verwijdert alleen de entry in de Manager.
- Services die
$beforevasthouden, kunnen daarna de oude logger blijven gebruiken. Het is geen bewerking die bestaande referenties vervangt door het nieuwe object. - Een stack die al is aangemaakt, bijvoorbeeld met
Log::channel('stack'), heeft een eigen Monolog-instantie waarin de Handlers en Processors van de onderliggende channels zijn verzameld. Als je alleen een onderliggend channel metforgetChannel()vergeet, verandert de opbouw van de bestaande stack niet. Hef zo nodig ook het vasthouden voor de channelnaam van die stack op en haal hem opnieuw op. forgetChannel()roept zelf geenclose()aan op de Handler. Het is geen API die het afsluiten van verbindingen of buffers garandeert.
Voor gebruik in een stack zijn ook Monolog-compatibele methoden nodig
Een eigen driver kan een implementatie vanPsr\Log\LoggerInterface teruggeven, maar createStackDriver() van Laravel roept getHandlers() en getProcessors() aan op de onderliggende channels. Die maken geen deel uit van de PSR-interface.
Een willekeurige PSR-logger teruggeven betekent dus niet automatisch dat hij ook in een stack werkt. Packages die ook gebruik in een stack ondersteunen, geven zoals in het voorbeeld een Monolog-instantie terug, of documenteren en testen expliciet het ondersteunde gebruik.
Verifieer niet alleen met mocks, maar ook de echte channelresolutie
Met alleenLog::shouldReceive('channel') kun je de registratie van de provider, de keuze van de factory en het toepassen van de configuratie niet controleren. Het volgende voorbeeld laat in de testomgeving voor packages de echte Manager en factory doorlopen.
Gebruik php://memory als bestemming voor de testoutput. Hier verifiëren we de opbouw van het channel en de instellingen van de Handler, zonder daadwerkelijk logs te schrijven.
Extra verificaties voor langdurig onderhoud
Geraadpleegde primaire bronnen
- Officiële Laravel-documentatie: Logging
- Framework v13.39.0: aanmaken, uitbreiden en vergeten van channels in LogManager
- Framework v13.39.0: inpakken en doorsturen van methoden in Logger
- Framework v13.39.0: singletonregistratie in LogServiceProvider
- Framework v13.39.0: ServiceProvider::callAfterResolving
- Framework v13.39.0: RebindsCallbacksToSelf
- Officiële Laravel-tests: LogManagerTest