Problem: Normalize Logger Interfaces

Easy
15 min
Adapt inconsistent logging libraries to a single, predictable interface.

Problem statement

Your team’s codebase uses two different logging systems across services:

  • Some modules use the native console object (console.logconsole.error).

  • Others rely on a custom in-house logger with logInfo() and logError() methods.

The inconsistency causes confusion and brittle integrations. You’ve been tasked to create a unified adapter so that the rest of the system can use a single, predictable interface.

Goal

Implement a LoggerAdapter class that wraps either console or customLogger and exposes these two methods:

  • .info(message) → routes to the correct info-level method

  • .error(message) → routes to the correct error-level method

Constraints

  • The adapter must delegate to the correct underlying method (logInfo or console.loglogError or console.error).

  • Do not modify the original logger implementations.

  • The calling code should always use the same LoggerAdapter interface.

Sample output

The examples below illustrate what the output should look like:

const consoleLogger = new LoggerAdapter(console);
const internalLogger = new LoggerAdapter(customLogger);
consoleLogger.info('Server started');
internalLogger.info('Server started');
consoleLogger.error('Failed to connect');
internalLogger.error('Failed to connect');
/* Expected output:
Server started
customLogger info: Server started
Failed to connect
customLogger error: Failed to connect
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Normalize Logger Interfaces

Easy
15 min
Adapt inconsistent logging libraries to a single, predictable interface.

Problem statement

Your team’s codebase uses two different logging systems across services:

  • Some modules use the native console object (console.logconsole.error).

  • Others rely on a custom in-house logger with logInfo() and logError() methods.

The inconsistency causes confusion and brittle integrations. You’ve been tasked to create a unified adapter so that the rest of the system can use a single, predictable interface.

Goal

Implement a LoggerAdapter class that wraps either console or customLogger and exposes these two methods:

  • .info(message) → routes to the correct info-level method

  • .error(message) → routes to the correct error-level method

Constraints

  • The adapter must delegate to the correct underlying method (logInfo or console.loglogError or console.error).

  • Do not modify the original logger implementations.

  • The calling code should always use the same LoggerAdapter interface.

Sample output

The examples below illustrate what the output should look like:

const consoleLogger = new LoggerAdapter(console);
const internalLogger = new LoggerAdapter(customLogger);
consoleLogger.info('Server started');
internalLogger.info('Server started');
consoleLogger.error('Failed to connect');
internalLogger.error('Failed to connect');
/* Expected output:
Server started
customLogger info: Server started
Failed to connect
customLogger error: Failed to connect
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
// Simulated in-house custom logger
const customLogger = {
logInfo(msg) {
console.log(`customLogger info: ${msg}`);
},
logError(msg) {
console.error(`customLogger error: ${msg}`);
}
};
// Your code here
// Example usage
const consoleLogger = new LoggerAdapter(console);
const internalLogger = new LoggerAdapter(customLogger);
consoleLogger.info('Server started');
internalLogger.info('Server started');
consoleLogger.error('Failed to connect');
internalLogger.error('Failed to connect');
/* Expected output:
Server started
customLogger info: Server started
Failed to connect
customLogger error: Failed to connect
*/