Skip to content

Logging

Overview

Consulo provides a platform-wide logging facility through the Logger interface in the consulo.logging package. It supports standard log levels and is the recommended way to emit diagnostic messages from plugin code.

Obtaining a Logger Instance

Logger provides two static factory methods:

// By class -- the fully qualified class name is used as the logger category
private static final Logger LOG = Logger.getInstance(MyService.class);

// By explicit category name
private static final Logger LOG = Logger.getInstance("my.plugin.category");

Logger instances are typically stored as private static final fields so that a single instance is shared across all usages within a class.

Log Levels

The Logger interface defines five log levels, listed from most to least severe:

error()

Logs a message at the error level. This level indicates a serious failure that should be investigated. Calling error() will also record a Throwable stack trace automatically if one is not supplied explicitly.

LOG.error("Failed to load configuration");
LOG.error("Failed to load configuration", exception);
LOG.error("Failed to load configuration", exception, "additional detail 1", "additional detail 2");

Variants accepting Attachment objects are available for including file contents or other data:

LOG.error("Unexpected PSI state", new Attachment("file.txt", fileContent));

warn()

Logs a message at the warn level. Use this for situations that are unexpected but recoverable.

LOG.warn("Configuration file not found, using defaults");
LOG.warn("Unexpected state encountered", exception);

info()

Logs a message at the info level. Use this for significant but normal events such as lifecycle milestones.

LOG.info("Plugin initialized successfully");
LOG.info("Connection established", exception); // includes stack trace for context

debug()

Logs a message at the debug level. Use this for detailed diagnostic information useful during development. Debug messages are typically disabled in production.

LOG.debug("Processing element: " + element.getName());
LOG.debug("Cache miss for key", throwable);

A varargs variant is also available that concatenates arguments only when debug logging is enabled:

LOG.debug("Resolved reference: ", target, " in file: ", file);

trace()

Logs a message at the trace level, which is finer-grained than debug. Use this for very detailed internal events within a subsystem to avoid overwhelming the log when only debug level is enabled. By default, trace() delegates to debug() and isTraceEnabled() delegates to isDebugEnabled().

LOG.trace("Entering method processToken");
LOG.trace(exception);

Guarding Expensive Log Statements

When constructing a log message is expensive (e.g., involves string concatenation or calling toString() on complex objects), guard the call with isDebugEnabled() or isTraceEnabled():

if (LOG.isDebugEnabled()) {
    LOG.debug("Detailed tree structure: " + psiElement.subtreeToString());
}

if (LOG.isTraceEnabled()) {
    LOG.trace("Token stream: " + tokenStream.dump());
}

This avoids the cost of building the message string when the corresponding log level is not active.

Assertions with assertTrue()

Logger provides an assertion method that logs an error (rather than throwing) when a condition is not met:

LOG.assertTrue(googler != null, "Expected non-null Googler instance");

If the condition is false, an error is logged with the message "Assertion failed: Expected non-null Googler instance" and a Throwable is recorded for the stack trace. The method returns the value of the condition, which can be useful in boolean expressions:

// Short form without a message
LOG.assertTrue(googler != null);

Best Practices

  • Declare loggers as private static final Logger LOG = Logger.getInstance(YourClass.class).
  • Use error() only for genuinely unexpected failures. Overusing it creates noise and makes real errors harder to spot.
  • Prefer warn() for recoverable problems and info() for important lifecycle events.
  • Guard expensive debug() / trace() calls with isDebugEnabled() / isTraceEnabled().
  • Use assertTrue() for internal invariant checks during development; do not use it as a substitute for proper input validation.
  • Use the varargs debug(String message, Object... details) overload when you want automatic concatenation that is skipped if debug is disabled.