How to do low level system design for a Logging Framework like Log4J
In this tutorial, we are going to learn about implementing the system design for a Logging Framework like Log4J in web applications with various design patterns.
- Ability to log in more than one place i.e., Console, Log files and databases etc.
- Ability to log multiple category of logs like INFO, DEBUG and ERROR etc.
- Categorization and place of logging should be configurable which it should be dynamic.
- Logger Class - Which will be exposed to the application.
- Log Category - This should be selected at runtime based on parameters.
- Sink - There can be multiple sinks that can be selected at runtime based on the parameters or from the config files.
In the above image we can see a high level design where application uses the logger class to write the logs and Logger class has a mechanism to differentiate the category of the logs into INFO, ERROR and DEBUG and these should be independent of each other because adding or removing a new category shouldn’t disturb the existing one and same goes with the Sink.
While designing any application we should always refer or relate our application architecture to a design pattern because design patterns are already time tested and common problems or basic errors can avoided using the design patterns.
In this LLD we are going to see how the design patterns are related or implemented. So firstly, start with the creational design pattern i.e., what are the objects required? In here we require Logger object followed by INFO, LOGGER and ERROR classes or ENUM’s and SINK with different logics to print the log on file, console and database.
- Logger class should be a Singleton class. Since we require only one instance of the Logger class to avoid data inconsistency.
- Category also remains as Singleton class.
- Considering the requirement changes in the SINK. We should go with the factory or abstract factory design to create the objects on fly.
- In this system design we don’t have to use the Structural design pattern. Since there no coupling or bridging between two classes and here data flows from application to SINK in which it can be considered as single system.
- In category we can see INFO, ERROR and DEBUG which must restrictive to each other which means when INFO log is printing we shouldn’t see the other two logs and same goes with the others. This resembles the chain of responsibility principle.
- SINK is similar to the category and dependent on the logging system and we’ll have an observer to keep track of changes.
Here is the code. Refer to this github Link.