Episode 3 — NodeJS MongoDB Backend Architecture / 3.12 — Logging and Monitoring
3.12 — Exercise Questions: Logging and Monitoring
Practice these 25+ questions to solidify your understanding of log levels, Winston configuration, Morgan middleware, error handling patterns, and production monitoring strategies.
< 3.12.c — Error Handling & Logging | Interview Questions >
Log Levels and Basics (Questions 1-7)
Q1. List the standard log levels from highest to lowest severity. Which level would you use to log a successful user login?
Hint: error > warn > info > http > debug > silly. Think about whether a login is noteworthy but routine.
Q2. If you set the log level to "warn", which log levels will be recorded and which will be suppressed?
Hint: Setting a level means "this level and all levels with higher severity."
Q3. What log level would you recommend for each environment (development, testing, staging, production) and why?
Hint: Development needs the most detail; production needs the least noise.
Q4. Explain the difference between structured and unstructured logging. Provide an example of each for a "payment failed" event.
Hint: Structured logging uses a consistent format (JSON) with named fields. Unstructured is free-form text.
Q5. Why should you NEVER log passwords, API keys, or credit card numbers? What would you log instead for a failed login attempt?
Hint: Log the event and identifying context (userId, email) without the sensitive payload.
Q6. What is log rotation? Explain why it is necessary and describe two common rotation strategies.
Hint: Log files grow indefinitely. Rotation creates new files periodically or when size limits are hit.
Q7. Why is console.log() insufficient for production applications? List at least 4 problems.
Hint: Think about levels, timestamps, persistence, structure, and configurability.
Winston (Questions 8-14)
Q8. Write a basic Winston logger configuration with two transports: one that logs errors to error.log and one that logs everything to combined.log.
Hint: Use winston.createLogger() with File transports. Set level: "error" on the error transport.
Q9. How do you add a Console transport that only appears in development? Write the code.
Hint: Check process.env.NODE_ENV and conditionally call logger.add().
Q10. What is the purpose of winston.format.errors({ stack: true })? What happens if you omit it?
Hint: Without it, Error objects lose their stack trace when serialized.
Q11. Configure Winston with winston-daily-rotate-file to create daily log files that are compressed after 1 day and deleted after 14 days.
Hint: Use DailyRotateFile transport with datePattern, zippedArchive, and maxFiles options.
Q12. Write a custom Winston format that outputs logs as: [TIMESTAMP] LEVEL: message {metadata}.
Hint: Use winston.format.printf() with destructured parameters.
Q13. What is defaultMeta in Winston? Why would you include service and environment fields?
Hint: defaultMeta adds the same metadata to every log entry automatically. Useful for multi-service architectures.
Q14. Explain the difference between Winston's format.json(), format.simple(), and format.colorize(). When would you use each?
Hint: JSON for production (machine-readable), simple for basic output, colorize for development terminal.
Morgan (Questions 15-19)
Q15. What is Morgan and how does it differ from Winston? Can they work together?
Hint: Morgan is HTTP-specific middleware. Winston is a general-purpose logger. They are often combined.
Q16. List the 5 predefined Morgan formats and explain when you would use each.
Hint: dev, combined, common, short, tiny — each varies in verbosity and intended environment.
Q17. Write code to create a custom Morgan token called :userId that logs the authenticated user's ID.
Hint: morgan.token("userId", (req) => ...) and include it in a custom format string.
Q18. How do you integrate Morgan with Winston so HTTP logs are written through Winston's transports?
Hint: Create a stream object with a write method that calls logger.http().
Q19. Write Morgan middleware that skips logging for health check endpoints (/health and /ready).
Hint: Use the skip option: morgan("combined", { skip: (req, res) => ... }).
Error Handling and Logging (Questions 20-25)
Q20. Write an Express error-handling middleware that logs the error (with stack trace, request URL, method, and user ID) and sends an appropriate JSON response.
Hint: Error middleware takes 4 parameters: (err, req, res, next). In production, hide the stack trace from the client.
Q21. What are unhandled promise rejections and uncaught exceptions? Write handlers for both that log the error and exit gracefully.
Hint: process.on("unhandledRejection", ...) and process.on("uncaughtException", ...). Uncaught exceptions require process.exit(1).
Q22. What is a request ID? Write middleware that generates a UUID for each request and attaches it to req.id.
Hint: Use the uuid package. Also check for an existing x-request-id header from upstream services.
Q23. Explain how request ID correlation works. Given 10,000 concurrent requests, how would you trace all logs for one specific request?
Hint: Include requestId in every log entry for that request. Search/filter logs by that ID.
Q24. What is Sentry? How does it differ from Winston? Write the basic Sentry setup for an Express application.
Hint: Sentry is an external error monitoring service that captures errors, tracks affected users, and sends alerts. Winston writes logs locally.
Q25. Describe the ELK stack (Elasticsearch, Logstash, Kibana). What role does each component play?
Hint: Elasticsearch stores and indexes logs. Logstash ingests and transforms logs. Kibana provides a visual dashboard.
Bonus Challenges (Questions 26-28)
Q26. Design a complete logging architecture for a microservices application with 5 services:
- How would you ensure consistent log format across all services?
- How would you trace a request that flows through multiple services?
- How would you centralize logs from all services?
- What alerting rules would you set up?
Hint: Shared logger package, distributed tracing with correlation IDs, ELK or cloud logging, alerts on error rate spikes.
Q27. Your production application suddenly starts throwing 500 errors. Using only logs, walk through the investigation process:
- Where do you start?
- What do you search for?
- How do you narrow down the root cause?
- How do you verify the fix?
Hint: Start with error logs, filter by time window, find the first occurrence, trace the request ID, check for common causes (DB, external API, memory).
Q28. Write a complete Express application setup file (app.js) that includes:
- Winston logger with daily rotation
- Morgan integration piped through Winston
- Request ID middleware
- Global error handling middleware
- Unhandled rejection/exception handlers
- Appropriate logging at each stage
Hint: Combine all concepts from 3.12.a, 3.12.b, and 3.12.c into a single, production-ready configuration.