Logging - GameDevWeek/CodeBase GitHub Wiki

What is logging?

Logging is the process of printing messages to a console, a file or similar to help find out what a program is doing or what data it is processing. The simplest form of logging is using System.out.println(). You should AVOID THIS for any serious project:

  • It takes a huge hit on performance.
  • It's hard to filter.
  • It's hard to read what will be printed.
  • It's hard to translate.

Even if you don't care about the above, you still should care, because when you finish your project, you might not want a lot of the messages to be seen by the end-user.

So how can it be done better?

There are a couple of Logging Frameworks out there. We're going to use Logback with SL4J. SL4J is a Library that allows to easily replace the logging framework without having to rewrite any of your code. Logback is the actual logging framework we use, but you will never actually use Logback code.

How to use SL4J?

Create a logger in each class you want to log something, like this:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//...
public class MyClass {
    // Make sure the logger is private static final!
    private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
//...

Why a logger for each class? So the framework can log where a message has been printed automatically without you printing it. Even after refactoring or copy/paste, the log will always tell you the correct source.

Now, to actually log something, write this:

logger.info("Hello {}", name); // GOOD
logger.info("Hello " + name); // BAD

Placeholders

Notice the {} brackets in the above example. These are a placeholder for the following parameter name. The good thing about using it like this, is that the string will be generated only when it actually gets printed to the console. So for example, if you disabled logging, the string will never be created.

Log Levels

You might have wondered what the info method is in the above example. It is the log level to be used for logging. The six logging levels available are (in order):

  • trace (the least serious)
  • debug
  • info
  • warn
  • error
  • fatal (the most serious)

If the logging framework has been configured to only show logs more serious than info, then calls to logger.trace() and logger.debug() will never produce any output.

In the GDW CodeBase, These log-levels are also used to print messages colored to the Developer Console, where messages can also be filtered by level.

Parameter types

In this example, we pass a string as parameter:

String name = "Sheldon";
logger.info("Hello {}", name);

But The logging framework accepts any java class and uses its toString() method:

public class Vector2 {
//...
	@Override
	public String toString () {
		return "[" + x + ":" + y + "]";
	}
}
//...
Vector2 v = new Vector2(5.5f, 4.4f);
logger.info("I'm at position {}", v); // "I'm at position [5.5:4.4]"