Bird
Raised Fist0
Node.jsframework~10 mins

Logging with structured formats in Node.js - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Logging with structured formats
Start Application
↓
Create Logger
↓
Generate Log Message
↓
Format Log as JSON
↓
Output to Console/File
↓
Log Stored in Structured Format
The app starts, creates a logger, formats messages as JSON, and outputs them for easy reading and searching.
Execution Sample
Node.js
const log = (level, message, meta = {}) => {
  const entry = { level, message, timestamp: new Date().toISOString(), ...meta };
  console.log(JSON.stringify(entry));
};

log('info', 'User login', { userId: 123 });
This code logs a message with level, text, timestamp, and extra info as a JSON string.
Execution Table
StepActionInputOutputNotes
1Call log functionlevel='info', message='User login', meta={userId:123}entry object createdCombines inputs into one object with timestamp
2Create timestampnew Date().toISOString()"2024-06-01T12:00:00.000Z"Current time in ISO format
3Merge all fieldslevel, message, timestamp, meta{"level":"info","message":"User login","timestamp":"2024-06-01T12:00:00.000Z","userId":123}Final structured log entry
4Convert to JSON stringentry object"{\"level\":\"info\",\"message\":\"User login\",\"timestamp\":\"2024-06-01T12:00:00.000Z\",\"userId\":123}"Ready for output
5Output to consoleJSON stringPrinted JSON log lineVisible in console or log file
6End--Logging complete
💡 Logging function completes after outputting the structured JSON log line
Variable Tracker
VariableStartAfter Step 1After Step 3Final
levelundefinedinfoinfoinfo
messageundefinedUser loginUser loginUser login
metaundefined{userId:123}{userId:123}{userId:123}
timestampundefinedundefined2024-06-01T12:00:00.000Z2024-06-01T12:00:00.000Z
entryundefinedpartial object{"level":"info","message":"User login","timestamp":"2024-06-01T12:00:00.000Z","userId":123}final object
Key Moments - 3 Insights
Why do we use JSON.stringify before outputting the log?
Because the log entry is an object, and console.log prints objects differently. JSON.stringify converts it to a single-line string that is easy to read and parse, as shown in step 4 of the execution_table.
What is the purpose of the timestamp in the log entry?
The timestamp shows when the log happened. It helps track events over time. In the execution_table, step 2 creates this timestamp in a standard ISO format.
Why do we merge meta fields into the main log entry?
Merging meta fields adds extra details to the log without losing the main message or level. This is shown in step 3 where meta is combined with level, message, and timestamp.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 3, what does the 'entry' object contain?
AJust the timestamp field
BOnly level and message fields
CLevel, message, timestamp, and meta fields merged
DA plain string message
💡 Hint
Check the 'Output' column in step 3 of the execution_table for the full object contents.
At which step is the log entry converted into a JSON string?
AStep 4
BStep 2
CStep 3
DStep 5
💡 Hint
Look at the 'Action' column for the step mentioning JSON string conversion.
If we remove the meta parameter, what changes in the variable_tracker for 'entry'?
AThe level field will be missing
BThe entry object will not have meta fields
CThe timestamp will be missing
DThe message field will be empty
💡 Hint
Refer to the 'meta' and 'entry' rows in variable_tracker to see how meta affects the final object.
Concept Snapshot
Logging with structured formats in Node.js:
- Create a log object with level, message, timestamp, and extra data
- Use JSON.stringify to convert the object to a string
- Output the JSON string to console or file
- Structured logs are easy to search and analyze
- Always include timestamp for event tracking
Full Transcript
This visual execution shows how to log messages in Node.js using structured JSON format. The process starts by calling a log function with level, message, and optional meta data. A timestamp is created in ISO format. All fields are merged into one object. Then JSON.stringify converts this object into a string. Finally, the string is printed to the console. This method helps keep logs consistent and easy to read or parse by tools. Key points include why JSON.stringify is needed, the role of timestamp, and how meta data is merged into the log entry.

Practice

(1/5)
1. What is the main benefit of using structured logging in Node.js applications?
easy
A. Logs are stored as plain text without any format.
B. Logs are only saved in memory and not written to files.
C. Logs are encrypted automatically for security.
D. Logs are saved in a clear, organized JSON format for easy reading and processing.

Solution

  1. Step 1: Understand structured logging

    Structured logging means saving logs in a format like JSON that is easy to read and parse.
  2. Step 2: Identify the benefit

    This format helps both humans and tools quickly understand log data.
  3. Final Answer:

    Logs are saved in a clear, organized JSON format for easy reading and processing. -> Option D
  4. Quick Check:

    Structured logging = JSON format logs [OK]
Hint: Structured logs use JSON for clarity and easy parsing [OK]
Common Mistakes:
  • Thinking logs are encrypted by default
  • Confusing plain text logs with structured logs
  • Assuming logs are only stored in memory
2. Which of the following is the correct way to create a logger using the pino library in Node.js?
easy
A. const logger = require('pino')();
B. const logger = new pino.Logger();
C. const logger = pino.create();
D. const logger = require('pino').createLogger();

Solution

  1. Step 1: Recall pino import syntax

    The pino library is imported using require('pino'), which returns a function.
  2. Step 2: Create logger instance

    Calling this function with () creates the logger instance: require('pino')()
  3. Final Answer:

    const logger = require('pino')(); -> Option A
  4. Quick Check:

    pino logger created by calling require('pino')() [OK]
Hint: Use require('pino')() to create logger instance [OK]
Common Mistakes:
  • Using createLogger() which does not exist
  • Trying to use new keyword with pino
  • Calling pino.create() which is invalid
3. What will be the output of the following Node.js code using pino?
const pino = require('pino');
const logger = pino();
logger.info({ user: 'alice', action: 'login' }, 'User action');
medium
A. User action: user=alice, action=login
B. {"level":30,"time":<timestamp>,"msg":"User action","user":"alice","action":"login"}
C. {"message":"User action","user":"alice","action":"login"}
D. Error: Missing log level

Solution

  1. Step 1: Understand pino.info() output format

    pino logs messages as JSON with fields like level, time, msg, and any extra data.
  2. Step 2: Analyze given code

    Calling logger.info with an object and message logs JSON with level 30 (info), timestamp, msg, and object keys.
  3. Final Answer:

    {"level":30,"time":<timestamp>,"msg":"User action","user":"alice","action":"login"} -> Option B
  4. Quick Check:

    pino logs JSON with level and message [OK]
Hint: pino logs JSON with level, time, msg, and extra data [OK]
Common Mistakes:
  • Expecting plain text output instead of JSON
  • Confusing message key name
  • Thinking log level is missing
4. Identify the error in this code snippet using pino for structured logging:
const pino = require('pino');
const logger = pino();
logger.info('User logged in', { user: 'bob' });
medium
A. The order of arguments is incorrect; the object should come first.
B. Missing semicolon after require statement.
C. pino() must be called with configuration object.
D. logger.info cannot accept two arguments.

Solution

  1. Step 1: Check pino.info argument order

    pino expects the first argument as an object with extra data, second as message string.
  2. Step 2: Analyze given code

    The code passes message string first, then object, which is reversed and causes wrong output.
  3. Final Answer:

    The order of arguments is incorrect; the object should come first. -> Option A
  4. Quick Check:

    pino.info(object, message) argument order [OK]
Hint: Pass object first, then message string to logger.info [OK]
Common Mistakes:
  • Swapping message and object arguments
  • Thinking semicolon is mandatory for correctness
  • Assuming pino() needs config always
5. You want to log user events with structured logs including user ID, event type, and timestamp using pino. Which code snippet correctly logs this data ensuring timestamp is included in the JSON output?
hard
A. logger.info({ userId: 123, event: 'click' }, 'User event at ' + new Date());
B. logger.info('User event', { userId: 123, event: 'click', timestamp: Date.now() });
C. logger.info({ userId: 123, event: 'click', time: new Date().toISOString() }, 'User event');
D. logger.info({ userId: 123, event: 'click', timestamp: Date.now() });

Solution

  1. Step 1: Ensure correct argument order and timestamp format

    pino expects object first, then message string. Timestamp should be ISO string for readability.
  2. Step 2: Check each option

    logger.info({ userId: 123, event: 'click', time: new Date().toISOString() }, 'User event'); passes object with userId, event, and ISO timestamp, then message string. This is correct.
  3. Final Answer:

    logger.info({ userId: 123, event: 'click', time: new Date().toISOString() }, 'User event'); -> Option C
  4. Quick Check:

    Object first with ISO timestamp, then message [OK]
Hint: Pass object with ISO timestamp first, then message string [OK]
Common Mistakes:
  • Swapping message and object arguments
  • Using Date.now() without formatting
  • Concatenating message and timestamp in string
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard