Inside the House of Eternal Return

KivaKit — Logging isn’t Special.

In KivaKit, the Logger interface isn’t special. It is just a Listener that handles status messages, the same as any other listener.

To learn in detail how messaging works in KivaKit, see the Medium article
Why Messaging is a Better Way to Report Status in Java.

Here is the essence of Logger:

interface Logger extends Listener
{
void log(Message message);

default void onMessage(Message message)
{
log(message);
}
}

When Logger receives a message in onMessage(), it calls log(). The log() method creates a LogEntry from the message, adds context information, and then routes the entry to one or more Logs:

class LogEntry { [...] }interface Log
{
void log(LogEntry);
}

In a Java, most of us have been using (approximately) this idiom for logging for a long time:

Logger logger = Logger.getLogger(getClass());    [...]logger.error("Failed to launch invasion of {}", planet);

A logger instance is created as a field (static or not), and methods are called on the logger to record status information during method calls.

In a KivaKit Java application, you could construct a Logger by hand, but there’s no reason to if you’re a Component (components are Repeaters, and therefore Broadcasters as well). Instead, we simply transmit status messages to any interested listener(s) like this:

class Army extends BaseComponent
{
[...]
problem("Failed to launch invasion of $", planet);
}

Here, the problem() method is a convenience method provided by a super-interface (Transceiver). This method will create a Problem (which is a Message) and transmit it to whatever object(s) are listening to Army.

In our example here, CommandCenter is listening:

class CommandCenter extends BaseComponent
{
void attack()
{
var army = listenTo(new Army());
[...]
}
}
class InvasionApplication extends Application
{
CommandCenter commandCenter = listenTo(new CommandCenter());
[...]
}

When CommandCenter receives our Problem message, it will repeat that message to its listeners, and those listeners will repeat it, and so on, until our message reaches the end of the listener chain. In our case, the terminal listener is a Logger instance belonging to InvasionApplication:

Army ==> CommandCenter ==> [...] ==> InvasionApplication ==> Logger

In Application.run(), the Logger listens to the application like this:

class Application extends BaseComponent
{
Logger LOGGER = LoggerFactory.newLogger();
[...] void run(String[] arguments)
{
LOGGER.listenTo(this);
[...]
}
}

The logger logs the message, and that’s the end of the story.

Conclusion

Loggers in KivaKit are not special. A Logger is just a kind of Listener. We can, of course, make new Loggers, and new Logs, as in existing logging frameworks. But the key advantage in KivaKit is:

The status messages that Loggers receive can also be processed in other ways, by other kinds of Listeners.

To illustrate, here are just a few other Listeners:

Listener             Purpose
------------------- ----------------------------------------------
MessageList Capture messages in a list
MutableCount Count messages
MessageAlarm Trigger an alarm if there are too many problems
StatusPanel Show status messages in a Swing panel
ValidationIssues Capture problems during validation
Converter Broadcast conversion errors
ThrowingListener Throws an exception when a problem is received
ConsoleWriter Writes status messages directly to the console
MicroservletRequest Captures microservlet request handling errors

Notes

KivaKit has a few Logs to choose from:

  • ConsoleLog
  • FileLog
  • EmailLog

and it is easy to create new ones (see ConsoleLog to see how easy).

Loggers and Logs can be configured at runtime by defining system properties, as described here.

More about KivaKit

https://state-of-the-art.org/

https://www.kivakit.org/

--

--

--

TNAV, KivaKit, Apache Wicket, Lexakai, writer, doc filmmaker, peer-reviewed researcher, Meisner-trained actor, artist, designer, founder(3x), born skeptic

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Build your own deep learning box — Hardware assembly

What I’ve learned in Encora Apprentice: Week 15 (Last week)

NEXT.exchange — Development Update

Image and Docker Commands

Building a Dashboard App using Plotly’s Dash: Favicon, Google analytics, Custom CSS

How Managed Print Services Can Benefit Your Business

My Android App — MyTechLog

How I used Google Cloud Storage to host my own Terraform providers registry

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jonathan Locke

Jonathan Locke

TNAV, KivaKit, Apache Wicket, Lexakai, writer, doc filmmaker, peer-reviewed researcher, Meisner-trained actor, artist, designer, founder(3x), born skeptic

More from Medium

Serialization Cake— Part One

How a Little-Known Jackson Feature Helped Secure My Domain Code

Investigating Java Heap memory and Native memory leaks

JVM memory model

Why we use Java at Jibit