Using the trace(…) command from anywhere in your Extension code

The trace(…) method is a useful little tool to log any information in the log files for debugging your Extension code.

It is available in the main Extension class and in every Request or Event handler. However, often times, developers need to log messages from other places in their code such as data classes, or any other object that doesn’t extend the Request/Event base classes.

How can we call trace(…) from somewhere else?

1) Refer to the Extension main class.

We can grab a reference to the Extension itself in the constructor of our class.

public class SpaceShip
{
	private SFSExtension ext;
	private float currentSpeed = 0;

	public SpaceShip()
	{
		ext = (SFSExtension) SmartFoxServer.getInstance().getZoneManager().getZoneByName("GameZone").getExtension();
	}

	public void setSpeed(float speed)
	{
		this.currentSpeed = speed;
		ext.trace("Current speed is now: ", currentSpeed);
	}
}

There is  probably one small downsides with this approach: there is a dependency on the zone name, which could be resolved by moving the string outside of the class as a static member of another class, which takes care of the constants in the game.

2) Inject the logger when constructing new objects.

Instead of referencing the Extension we could pass the Extension’s underlying logger to all those objects that need to use it.

import org.slf4j.Logger;

public class SpaceShip
{
	private final Logger logger
	private float currentSpeed = 0;

	public SpaceShip(Logger logger)
	{
		this.logger = logger;
	}

	public void setSpeed(float speed)
	{
		this.currentSpeed = speed;
		logger.info("Current speed is now: " + currentSpeed);
	}
}

This time we’re using the SLF4J logger instance directly, which is where the trace command output goes, and we no longer depend on our Extension instance directly. This is probably the best approach for object reuse.

The logger can be injected by the main class at creation time:

public class MySpaceExtension extends SFSExtension
{
	@Override
	public void init()
	{
		//... init code ...

		SpaceShip mainShip = new SpaceShip(this.getLogger());
	}
}

Regardless of what approach you will use, also keep in mind that you can work with different logging levels such as DEBUG, INFO, WARN, ERROR, to differentiate the types of output of our log traces. This will be very useful to silence all unwanted debugging logs when in production.

In order to switch the default logging level of the Extension you can edit the SFS2X/config/log4j.properties file at this line:

log4j.category.Extensions=INFO,consoleAppender,fileAppender

For more information on configuring the server’s logging system please refer to the documentation.