Skip to content

Logging API

This page is the API reference for GGCommons logging: the logger type in each SDK, how you obtain one, the log methods and level predicates, the configuration type, the configurator entry points, and the per-language format tokens. For the concepts behind these — how levels are honored, the stdout-JSON sink, file rotation, and hot reload — see the Logging guide.

There is no gg.logging() accessor in any SDK. The framework configures your language’s logging framework when you build your GGCommons instance; component code obtains a logger from the native facility and writes to it. The configuration types and configurator functions below are wired by the framework — component authors normally only touch the get a logger and log surface.

SDK Obtain a logger Logger type Log methods Predicates Format key
Java LoggerFactory.getLogger(...) com.mbreissi.ggcommons.logging.Logger (interface) trace debug info warn error isTraceEnabled()isErrorEnabled() java_format
Python stdlib logging.getLogger(name) stdlib logging.Logger debug info warning error critical isEnabledFor(level) python_format
Rust tracing macros (no factory) n/a (macros) trace! debug! info! warn! error! tracing level checks rust_format
TypeScript logger / getLogger(name) Logger (class) debug info warn error none exported ts_format
import com.mbreissi.ggcommons.logging.Logger;
import com.mbreissi.ggcommons.logging.LoggerFactory;
Logger byClass = LoggerFactory.getLogger(MyApp.class);
Logger byName = LoggerFactory.getLogger("com.example.MyApp");

LoggerFactory is a static factory:

public final class LoggerFactory {
public static Logger getLogger(Class<?> clazz);
public static Logger getLogger(String name);
}

The factory auto-detects the underlying framework once at class-load time, preferring SLF4J, then Log4j2, then JUL. You can also bypass the facade and use Log4j2 directly (LogManager.getLogger(...)) — the library has already reconfigured the Log4j2 root logger.

com.mbreissi.ggcommons.logging.Logger is an interface. Each of trace/debug/info/warn/error has three overloads, plus a level predicate per level:

public interface Logger {
void trace(String message);
void trace(String message, Object... args); // SLF4J-style {} placeholders
void trace(String message, Throwable throwable);
// ... identical trio for debug, info, warn, error ...
boolean isTraceEnabled();
boolean isDebugEnabled();
boolean isInfoEnabled();
boolean isWarnEnabled();
boolean isErrorEnabled();
}

The (String, Object...) overload uses SLF4J-style {} placeholders; the (String, Throwable) overload attaches an exception. There is no fatal() method on this interface.

These types model the logging config section and drive the configurator. They are framework-facing — you rarely construct them yourself — but they expose the resolved values via getters.

com.mbreissi.ggcommons.config.LoggingConfiguration parses the logging JSON object and exposes typed getters:

LoggingConfiguration(JsonObject json);
org.apache.logging.log4j.Level getLevel(); // default INFO
String getFormat(); // java_format or DEFAULT_FORMAT
boolean isFormatExplicitlySet(); // true if java_format was provided
boolean isFileLoggingEnabled();
String getLogFilePath(); // == fileLogging.filePath
String getMaxFileSize(); // default "10MB"
int getBackupCount(); // default 5
java.util.Map<String, Level> getLoggerLevels(); // from logging.loggers
boolean isGlobalControlEnabled(); // default false

Defaults: level INFO, format %d{yyyy-MM-dd HH:mm:ss} [%-5p] %-25.25c{1}(%4L): %m%n, maxFileSize "10MB", backupCount 5. Obtain the live instance via ConfigManager.getLoggingConfig().

Configurator and reconfiguration entry points

Section titled “Configurator and reconfiguration entry points”

The framework calls these at startup and on hot reload. They are documented here for completeness; component authors do not normally invoke them.

// on ConfigManager — the live runtime configurator
public void reconfigureLogging(); // rebuilds the Log4j2 config from LoggingConfiguration
public LoggingConfiguration getLoggingConfig();

reconfigureLogging() runs at init and again on hot reload via the registered LoggingConfigChangeListener. It always installs a SYSTEM_OUT console appender, optionally a size-rotated RollingFile appender, sets the root level, and adds a per-logger LoggerConfig (with additivity=false) for each logging.loggers entry. When globalControl=true it delegates to GlobalLoggingManager, which rebuilds the entire Log4j2 configuration.

Each SDK reads only its own format key, written in its own syntax; a token from one language is meaningless to the others. Setting the value to the literal json (case-insensitive) selects the stdout-JSON sink instead of a text layout.

SDK Config key Syntax Default (when unset)
Java java_format Log4j2 PatternLayout %d{yyyy-MM-dd HH:mm:ss} [%-5p] %-25.25c{1}(%4L): %m%n
Python python_format logging.Formatter string %(asctime)s [%(levelname)s] %(name)s: %(message)s
Rust rust_format token template {timestamp} {level} {target} {message}
TypeScript ts_format token template {timestamp} [{level}] {message}

Token-template placeholders differ between Rust and TypeScript: Rust supports {timestamp}, {level}, {target}, {message} (it uses {target}), while TypeScript supports {timestamp}, {level}, {logger}, {message} (it uses {logger}). The effective format is resolved with the precedence: explicit *_format token, then the platform-profile default (json on Kubernetes), then the SDK’s built-in text default.

import com.mbreissi.ggcommons.logging.Logger;
import com.mbreissi.ggcommons.logging.LoggerFactory;
Logger log = LoggerFactory.getLogger(MyApp.class); // or getLogger("my.logger")
log.info("publish interval set to {}ms", interval); // SLF4J-style {} args
log.warn("retrying after error", throwable); // (String, Throwable) overload
if (log.isDebugEnabled()) {
log.debug("payload bytes: {}", payload.length);
}