340. Design Multi-Module Logging Framework
Design Multi-Module Logging Framework
Design a logging framework for three application modules: "MODULE1", "MODULE2", and "MODULE3".
A module submits a log with a sequence number, destination, log level, and activity data. The framework places every accepted log in a shared buffer and writes it to the selected destination as a stream.
The supported logging destinations are "FILE" and "TOOL". A log receives an acknowledgement only after it has been written successfully.
The framework must also support retrieving logs by destination, module, log level, and an inclusive sequence-number range.

Class Definition

MultiModuleLoggingFramework()
  • The framework starts with an empty buffer and no written logs.
  • The framework supports both "FILE" and "TOOL" destinations.

Method Signatures

Submit an Activity Log

String logActivity(long sequenceNumber, String moduleName, String destinationType, String logLevel, String logData)
  • sequenceNumber is a positive identifier supplied by the module.
  • sequenceNumber must be unique across all logs in the framework.
  • Sequence numbers do not need to be consecutive or submitted in increasing order.
  • moduleName must be "MODULE1", "MODULE2", or "MODULE3".
  • destinationType must be "FILE" or "TOOL".
  • logLevel must be "INFO", "WARNING", or "ERROR".
  • logData contains the activity information to be logged.
    It doesn't contain comma character for consistency.
  • After the log has been written successfully, return "ACK,sequenceNumber".
  • Return "REJECTED" if any input is invalid or the sequence number has already been used.
  • A rejected log is not written to any destination.

Fetch Logs

List<String> getLogs(String destinationType, String moduleName, String logLevel, long minimumSequenceNumber, long maximumSequenceNumber)
  • Return logs whose sequence numbers are between minimumSequenceNumber and maximumSequenceNumber, inclusive.
  • Use "FILE" or "TOOL" to filter by destination. Use "ALL" to include both destinations.
  • Use a supported module name to filter by module. Use "ALL" to include every module.
  • Use a supported log level to filter by level. Use "ALL" to include every log level.
  • A log is returned only when it satisfies every supplied filter.
  • Return matching logs in increasing sequence number order.
  • Represent each returned log as "sequenceNumber,destinationType,moduleName,logLevel,logData".
  • Return an empty list when no log matches the filters.

Logging Rules

  • Every accepted sequence number must be unique.
  • Each accepted log must be written exactly once.
  • An acknowledgement is returned only after the corresponding log has been written.
  • Logs may be submitted in any sequence-number order.
  • Rejected logs must not appear in retrieval results.
  • Retrieval results are always sorted by increasing sequence number.
  • Commas in logData are preserved as part of the activity data.

Constraints

  • 1 ≤ sequenceNumber ≤ 1,000,000,000
  • moduleName is "MODULE1", "MODULE2", or "MODULE3".
  • destinationType is "FILE" or "TOOL" when submitting a log.
  • destinationType is "FILE", "TOOL", or "ALL" when fetching logs.
  • logLevel is "INFO", "WARNING", or "ERROR" when submitting a log.
  • logLevel may also be "ALL" when fetching logs.
  • 1 ≤ logData.length() ≤ 10,000
  • 1 ≤ minimumSequenceNumber ≤ maximumSequenceNumber ≤ 1,000,000,000
  • At most 100,000 logs are submitted to one framework instance.

Example 1

MultiModuleLoggingFramework()
Output: A logging framework with no written logs.
logActivity(sequenceNumber = 205, moduleName = "MODULE2", destinationType = "FILE", logLevel = "INFO", logData = "Invoice generated")
Output: "ACK,205"
logActivity(sequenceNumber = 110, moduleName = "MODULE1", destinationType = "TOOL", logLevel = "ERROR", logData = "Payment timed out")
Output: "ACK,110"
getLogs(destinationType = "FILE", moduleName = "ALL", logLevel = "ALL", minimumSequenceNumber = 1, maximumSequenceNumber = 500)
Output: ["205,FILE,MODULE2,INFO,Invoice generated"]
Only the log written to the "FILE" destination is returned.

Example 2

MultiModuleLoggingFramework()
Output: A logging framework with no written logs.
logActivity(sequenceNumber = 72, moduleName = "MODULE3", destinationType = "TOOL", logLevel = "WARNING", logData = "Cache is nearly full")
Output: "ACK,72"
logActivity(sequenceNumber = 24, moduleName = "MODULE3", destinationType = "TOOL", logLevel = "INFO", logData = "Cache refreshed")
Output: "ACK,24"
logActivity(sequenceNumber = 95, moduleName = "MODULE1", destinationType = "FILE", logLevel = "WARNING", logData = "Login attempt delayed")
Output: "ACK,95"
getLogs(destinationType = "TOOL", moduleName = "MODULE3", logLevel = "ALL", minimumSequenceNumber = 1, maximumSequenceNumber = 100)
Output: ["24,TOOL,MODULE3,INFO,Cache refreshed", "72,TOOL,MODULE3,WARNING,Cache is nearly full"]
Both matching logs are returned in increasing sequence number order.

Example 3

MultiModuleLoggingFramework()
Output: A logging framework with no written logs.
logActivity(sequenceNumber = 45, moduleName = "MODULE2", destinationType = "FILE", logLevel = "ERROR", logData = "Report generation failed")
Output: "ACK,45"
logActivity(sequenceNumber = 45, moduleName = "MODULE1", destinationType = "TOOL", logLevel = "INFO", logData = "User signed in")
Output: "REJECTED"
getLogs(destinationType = "ALL", moduleName = "ALL", logLevel = "ERROR", minimumSequenceNumber = 1, maximumSequenceNumber = 100)
Output: ["45,FILE,MODULE2,ERROR,Report generation failed"]
The second log is rejected because sequence number 45 was already used.


Please use Laptop/Desktop or any other large screen to add/edit code.