Door
Ozzie PHP
op 25-11-2013 11:41
gewijzigd op 25-11-2013 11:49
6.557 views
Ola,
Als er in mijn applicatie iets fout gaat, dan wil ik daar een error-level aan kunnen koppelen.
Zelf dacht ik om gebruik te gaan maken van 3 gradaties:
1) notice: een kleine fout, bijv. een user vult een getal in in plaats van een string
2) warning: een serieuze fout, bijv. een file kan niet worden opgeslagen
3) error: er gaat iets goed mis, bijv. er kan geen database-verbinding tot stand komen
Een notice zou ik dan alleen loggen in een log-bestand. Een warning zou ik zowel loggen als mailen, en bij een error zou ik loggen en mailen en de rest van de applicatie stoppen.
Zijn deze 3 gradaties toereikend volgens jullie? Of zijn er nog tussenstappen te bedenken, en zo ja welke?
>> Als je exceptions... die de verbinding gebruikte.
Oké, maar op het moment dat je applicatie door kan gaan dan is het dus een WARNING (iets wat aandacht behoeft, maar de applicatie hoeft niet te stoppen).
Niet als je OOP programmeert. De cURL-klasse weet dan niet waarvoor zij wordt gebruikt en hoort dat ook niet te weten. Die klasse kan dus geen onderscheid maken tussen een warning en een notice. Pas de andere klasse maakt daarvan een notice als deze het probleem in een catch omzeilt.
Ozzie PHP op 25/11/2013 14:27:35
Wat betreft het debuggen. Ik begrijp niet WANNEER je een debug-actie wilt loggen. Als er iets fout gaat wil je toch altijd debug informatie hebben?
Meestal wil je dat natuurlijk op je scherm zien. Maar er zijn situaties waarin loggen beter is. Straks laat je bijvoorbeeld testgebruikers los op een bèta. Je gaat dan niet zitten wachten op hun bugreports, maar logt de bugs.
Als je met twee schermen werkt, kun je sneller debuggen door de log live naast de applicatie te tonen. Dat is makkelijker dan in het onderwaterscherm van een HTML-pagina naar foutmeldingen gaan zitten zoeken.
Je moet onderscheid maken tussen error levels en log levels. Een error is slechts een fatal, error, notice of warning. Je wilt echter veel meer gegevens loggen dan alleen de errors. In een dev. omgeving wil ik bijv. graag precies weten welke acties er zijn ondergaan, welke router heeft gematched, etc.
En wat denk je van user handelingen? Ik zou graag willen loggen welke acties een moderator doet, zodat die bij gehouden kunnen worden.
Voor het loggen heb je dus nog veel meer informatie om te loggen, daarom heb je ook meer levels nodig. En dan zal ik altijd de psr standarden volgen.
>> Niet als je OOP programmeert. De cURL-klasse weet dan niet waarvoor zij wordt gebruikt en hoort dat ook niet te weten. Die klasse kan dus geen onderscheid maken tussen een warning en een notice. Pas de andere klasse maakt daarvan een notice als deze het probleem in een catch omzeilt.
Dit is ook wat ik bedoel. Ik wil een exception opvangen en afhankelijk van de aard (gradatie) van de exception wil ik die exceptnio bijv. loggen en mailen. Dit wil ik laten doen door een handler. Door de juiste error mee te geven, moet die handler dan loggen, mailen of in het uiterste geval de applicatie stoppen.
Wat betreft debuggen... ik snap dat je niet wilt dat gebruikers debug-informatie zien. Ik snap niet waarom debug een log-level is. Het is toch helemaal geen level? Ieder "level" kun je zelf voorzien van debug-informatie dus ik snap het nut niet zo goed.
@Wouter:
Ik snap wat je bedoelt met het verschil tussen error en log levels. Goed dat je dat onderscheid maakt. Mij gaat het het dus om de error levels. Jij zegt:
"Een error is slechts een fatal, error, notice of warning"
Volgens jou zijn het er dan 4? Wat is precies het verschil tussen fatal en error?
Dit is ook wat ik bedoel. Ik wil een exception opvangen en afhankelijk van de aard (gradatie) van de exception wil ik die exceptnio bijv. loggen en mailen. Dit wil ik laten doen door een handler. Door de juiste error mee te geven, moet die handler dan loggen, mailen of in het uiterste geval de applicatie stoppen.
De logger logt. Laat je de logger meer doen, dan leg je te veel verantwoordelijkheid bij de logger. De logger moet bij mijn voorbeeld weten dat het ene gebruik van de cURL-klasse mag eindigen in een notice en het andere gebruik in een warning. Daarvoor moet de logger niet alleen de cURL-klasse kennen, maar ook inzicht hebben in hoe andere klassen die klasse gebruiken. Dat wil je niet. Je logt de warning van A en als die ontaardt in een notice bij B, dan log je die opnieuw.
A weet helemaal niet dat B gaat loggen. A is zich zelfs niet bewust van het bestaan van B. En je wilt ook geen A bouwen die per se door B moet worden gebruikt omdat er anders niets wordt gelogd.
Een klasse hoeft daarom ook niet te weten wanneer de logger een mail bij een kritieke fout de deur uitdoet naar de juiste dienstdoende persoon. Dat maakt klassen dan té "logger aware". Alleen een level is ruim voldoende; daarna is het aan de logger om te bepalen hoe er wordt gelogd.
Ward, misschien praat ik soms te snel of onvolledig. Mijn excuses daarvoor. Maar mijn idee is het volgende. Ik wil een exception handler maken. Op het moment dat ik een exception/error afvang waar iets mee moet gebeuren, dan wil ik die error doorsturen naar de exception handler. Hier wil ik dan een error-level aan koppelen. Op basis van de error-level beslist de exception handler wat er moet gebeuren (loggen, mailen, applicatie killen). Je krijgt dus zeg maar zoiets:
<?php
try {
$this->cacher->cache($data, 'foo');
catch (CacherException $e) {
$this->exception_handler('Could not cache data', $e, WARNING);
}
?>
of
<?php
try {
$config = $this->database->get('website_config');
catch (DatabaseConnectionException $e) {
$this->exception_handler('No database connection', $e, ERROR);
}
?>
Een class method vangt dus ergens een exception op, en afhankelijk van de aard van die exception wordt in sommige gevallen de exception handler ingeschakeld. Aan die exception handler wil ik dan een level kunnen meegeven. Die handler weet aan de hand van het level wat er vervolgens moet gebeuren.
Op zich heb ik er niks op tegen, mits ze een meerwaarde hebben. Die zie ik nu niet. Maar aangezien ik niet alwetend ben kun jij het misschien uitleggen?
Een class method vangt dus ergens een exception op, en afhankelijk van de aard van die exception wordt in sommige gevallen de exception handler ingeschakeld. Aan die exception handler wil ik dan een level kunnen meegeven. Die handler weet aan de hand van het level wat er vervolgens moet gebeuren.
In A treedt een onverwachte fout op. Gelukkig niet zo erg: je had het ding namelijk in een if verpakt die bij false een exception gooit. Aangekomen bij B blijkt de fout toch minder onschuldig te zijn: het PHP-script crasht hard in de try, nog voordat het in de catch belandt. Hoe wil je dan nog bij een logger uitkomen?
Als je het loggen almaar vooruit schuift, kom je er soms niet meer aan toe. Of je vergeet het, want van uitstel komt afstel en "dat doe ik morgen wel". Ondertussen blijven bugs onopgemerkt.
Kun je nog het verschil uitleggen tussen FATEL en ERROR?
Uit jouw link (thanks):
Emergency: system is unusable
Alert: action must be taken immediately
Critical: critical conditions
Error: error conditions
Warning: warning conditions
Notice: normal but significant condition
Informational: informational messages
Debug: debug-level messages
Ik zie het hier staan... maar ik weet niet hoe ik dan onderscheid moet maken. Wat is bijvoorbeeld het verschil tussen een error en critical? En tussen critical en alert? Dat komt toch allemaal op hetzelfde neer?
@Ward:
Ik voel dat je me iets probeert duidelijk te maken, maar ik zie het licht nog niet helemaal. Kun je eens schematisch een praktijkvoorbeeldje geven van wat je bedoelt?