Logging vs reporting (twee systemen)
In de backend bestaan twee los van elkaar staande systemen die makkelijk door elkaar worden gehaald. Dit document legt uit wat het verschil is en wanneer je welk systeem kiest. Voor concrete feiten (env-vars, endpoints, API) zie de reference-docs: Platform-logging en Reporting en eventservice.
Het mentale model
| Platform-logging | Reporting | |
|---|---|---|
| Doel | Vluchtige runtime-diagnostiek (debuggen, troubleshooten) | Duurzaam verslag van wat een proces heeft gedaan |
| Service | loggerService (pino) + logStore |
reportingService (alias logService) → eventService |
| Waar het landt | stdout + in-memory/Redis ringbuffer | MongoDB events-collectie |
| Levensduur | Kort (TTL, standaard 7 dagen; ringbuffer rolt) | Permanent (tot expliciet verwijderd) |
| Zichtbaar via | GET /logs + Tapster-beheer “Logging” |
Tijdlijn, en kan notificaties triggeren |
| Eenheid | Losse regels per log-call | Eén Event per proces-run (gebundeld) |
Kort gezegd: logging is voor de ontwikkelaar/on-call, reporting is voor de business/audit. Een logregel beantwoordt “wat gebeurde er net in de code”; een Event beantwoordt “wat heeft deze run verwerkt, en kun je dat later terugvinden”.
Platform-logging
loggerService is een dunne contextuele wrapper rond pino. Er zijn
vier bronnen (app, http, bull, error), elk met een eigen pino-instance. Elke
log-call gaat naar stdout (en optioneel naar dagbestanden) én naar een unified
logStore (in-memory of Redis), die de admin-UI en GET /logs voeden.
Gebruik dit voor: business-acties, state-changes, fouten, job start/finish, HTTP-requests. Het is bewust vluchtig: de ringbuffer heeft een maximum en een TTL. Reken er niet op voor langetermijn-audit.
Zie ook ADR 0001 — log-level voor HTTP-fouten.
Reporting
reportingService (in de codebase geïmporteerd als logService via een alias) verzamelt
tekstregels in een in-memory context, en zet ze bij flush() om in precies één Event.
Het is event-only: de oude e-mail- en console-transports bestaan niet meer, en de
transportName-parameter van flush() wordt genegeerd.
eventService is de laag eronder: het maakt het Event aan, plaatst het op de tijdlijn en
kan op basis van het EventType notificaties versturen. Een Event kan gekoppeld zijn aan
een bron-document via sourceDoc { id, model } (de model moet in de
onModelRegistry staan, anders kan de tijdlijn-populate en notificatie-dispatch het niet
resolven).
Gebruik dit voor: import/export, batch-jobs, migraties, data-repair en andere processen met een duidelijk begin en einde waarvan je een navigeerbaar verslag wilt bewaren.
Een concreet voorbeeld: process-response
De deelnamemonitor-campagne (processResponse) is een goed voorbeeld van waarom de twee
systemen naast elkaar bestaan:
- Tijdens de verwerking schrijft de code per locatie een regel (“Locatie verwerkt X”, “Tag niet gevonden … overgeslagen”). Dat zou je vluchtig kunnen loggen.
- Aan het einde wil je weten: welke campagne, door wie gestart, hoeveel verwerkt / overgeslagen / niet-verwerkt, en dat verslag terug kunnen vinden bij de campagne.
Daarom gebruikt processResponse de reportingService: het bundelt de regels en flusht ze
als één Event met sourceDoc { model: 'ParticipationMonitorCampaign' }, de triggerende
gebruiker en een gestructureerde samenvatting. Dat is reporting, niet platform-logging.
Vuistregel
- Moet het na een week nog terugvindbaar zijn, of hoort het op een tijdlijn / bij een
document? → reporting (
reportingService/eventService). - Is het diagnostiek die je morgen tijdens debuggen wilt kunnen filteren? → logging
(
loggerService/req.logger). - Geen
console.login business-code; gebruik altijd een van bovenstaande.