2 The use case for log4print

 

This chapter covers

  • Essential terms and concepts in logging
  • Building log4print, a simple logging framework
  • Understanding the challenges that logging frameworks solve

Twenty years ago, I worked on a massive project. The system was overly complex–more than 30 subsystems ran independently. Today, we’d call this a microservice architecture, except these were more macroservices. The challenge was the same: tracing how data moved through the system. I sketched the architecture in Figure 2.1 to give you a sense of the scale.

Figure 2.1 A real-world example of a complicated architecture with multiple subsystems. In some cases, developers connected hundreds of so-called microservices, making it hard to understand how data flows.
CH02 F01 architecture

I remember staring at a sketch like this and wondering how anything worked. My job was to help identify and fix problems at runtime. Unfortunately, developers had turned off logging. The company policy demanded it to save costs. Suddenly, every system was on alert. Something terrible had happened. Our investigation led nowhere until we convinced the company to turn logging back on. Minutes later, we found the problem.

The message read:

---
I could not reach the deprecated service after 30 seconds of waiting.
Here is a NullPointerException because we did not expect this.
---

2.1 Log files and log messages

2.2 Log4print: let’s start!

2.2.1 Our first message

2.2.2 Turning logging on and off

2.2.3 Using classes for logging

2.2.4 Extracting to the Logger class

2.2.5 Introducing logging configuration

2.2.6 The LoggerManager

2.2.7 Log-Levels

2.2.8 The Atlantis Angle

2.2.9 Configuring log-levels

2.2.10 Destinations: Logging appenders

2.2.11 Using the new system

2.3 Why not write a custom logging system?

2.3.1 Reconfiguration

2.3.2 Dealing with files

2.3.3 Multithreading issues

2.3.4 Problems with System.out.println

2.3.5 More features