Monitoring & Logging
Part of the Full Stack Developer Roadmap
In short
A user says 'checkout failed'. A React crash, an API 500 or a slow database? With error tracking on both ends and one request id linking them, you'll know in minutes.
Tracking errors and performance across both your frontend (Sentry for React) and backend (structured logs, APM) — a full-stack issue can originate on either side, so you need visibility into both.

Think of it like this
One patient file, every department
In a good hospital, your file travels with you from OPD to X-ray to the ward, with one patient number on every page. Any doctor can read the whole story. A request id does that for your app: the same id on the browser error, the API log and the slow query.
Watch it happen
Following one failed checkout
x-request-id: r-81f2
1/6The frontend sends the order request with a request id in a header.
The big ideas
What you need to know
Structured logs
Log JSON with fields like reqId, userId and durationMs, not loose strings. Then you can search and filter.
One id end to end
Create a request id at the edge, pass it into every log line, and return it to the user in error messages.
Error tracking on both sides
Tools like Sentry capture React crashes and API exceptions with stack traces, browser details and the release version.
Alert on symptoms
Alert when the error rate or response time jumps, not on every single error, or people learn to ignore alerts.
See it in code
Walk through the code
1import pino from "pino";2import { randomUUID } from "node:crypto";3 4const logger = pino();5 6app.use((req, res, next) => {7 req.id = req.get("x-request-id") ?? randomUUID();8 res.set("x-request-id", req.id);9 req.log = logger.child({ reqId: req.id, method: req.method, path: req.path });10 next();11});12 13app.use((err, req, res, _next) => {14 req.log.error({ err }, "request failed");15 res.status(500).json({ error: "Something went wrong", reqId: req.id });16});1/3Reuse the id the frontend sent, or create one, and echo it back in the response header.
pino writes one JSON line per log. The pino-http package does much of this for you; this version shows the moving parts.
Save yourself the pain
Common mistakes
Oops
Logging console.log('error!!') and nothing else.
Do this instead
Log structured JSON with the request id, user id and error object, so you can actually find it later.
Oops
Logging passwords, tokens or full card details.
Do this instead
Redact sensitive fields. pino's redact option can blank out paths like req.headers.authorization.
Oops
Only tracking backend errors.
Do this instead
Add error tracking to the frontend too. Many bugs never reach the API at all.
Your mission
Trace one request across the stack
Quick check
A user reports 'Something went wrong (ref r-81f2)'. What's the fastest next step?
Go deeper
- 1Set up Sentry (or similar) on both your frontend and backend.
- 2Correlate a frontend error with the backend request that caused it, using a shared request ID.
- 3Set up basic uptime monitoring for your deployed backend API.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.