-
Notifications
You must be signed in to change notification settings - Fork 0
Boot Log
Logging subsystem for boot sequence messages before the full logging infrastructure is ready.
BootLog is JNode's logging interface used during the bootstrap phase—before Log4j or other full logging systems are initialized. It provides a lightweight, immediate logging mechanism with five severity levels: DEBUG, INFO, WARN, ERROR, and FATAL.
The boot logging system consists of three key components:
| Component | File | Purpose |
|---|---|---|
BootLog |
core/src/core/org/jnode/bootlog/BootLog.java |
Interface defining logging methods |
BootLogInstance |
core/src/core/org/jnode/bootlog/BootLogInstance.java |
Singleton accessor for the system BootLog |
BootLogImpl |
core/src/core/org/jnode/vm/BootLogImpl.java |
Default implementation |
BootLog is initialized early in VmSystem.initialize():
VmSystem.initialize()
└─> InitialNaming.setNameSpace(new DefaultNameSpace())
└─> BootLogImpl.initialize() <-- Boot log initialized here
└─> BootLogInstance.set(new BootLogImpl())
This happens immediately after the InitialNaming namespace is set up, making BootLog available to all subsequent boot code.
Code retrieves the system BootLog via BootLogInstance.get():
BootLog log = BootLogInstance.get();
log.info("Starting device manager");
log.error("Failed to initialize", ex);The BootLogInstance class uses InitialNaming.lookup(BootLog.class) to retrieve the registered instance, providing type-safe service access similar to JNDI but simpler.
| Level | Constant | Typical Output |
|---|---|---|
| DEBUG | 1 | Console (configurable via setDebugOut) |
| INFO | 2 | System.out |
| WARN | 3 | System.out |
| ERROR | 4 | System.err |
| FATAL | 5 | System.err |
If no PrintStream is available (e.g., early boot before System streams are set up), BootLogImpl.log() falls back to Unsafe.debug() for raw output:
private void log(int level, PrintStream ps, String msg, Throwable ex) {
if (ps != null) {
// Use PrintStream
ps.println(msg);
if (ex != null) ex.printStackTrace(ps);
} else {
// Fallback to Unsafe.debug
Unsafe.debug(msg);
Unsafe.debug("\n");
}
}Once the system is fully initialized, the Log4jConfigurePlugin replaces the BootLog with full Log4j logging:
BootLogInstance.get().setDebugOut(new PrintStream(new WriterOutputStream(console.getOut(), false), true));public interface BootLog {
public static final int DEBUG = 1;
public static final int INFO = 2;
public static final int WARN = 3;
public static final int ERROR = 4;
public static final int FATAL = 5;
void debug(String msg);
void debug(String msg, Throwable ex);
void info(String msg);
void info(String msg, Throwable ex);
void warn(String msg);
void warn(String msg, Throwable ex);
void error(String msg);
void error(String msg, Throwable ex);
void fatal(String msg);
void fatal(String msg, Throwable ex);
void setDebugOut(PrintStream out);
}A utility class providing static get/set methods that delegate to InitialNaming:
public final class BootLogInstance {
public static BootLog get() {
return InitialNaming.lookup(BootLog.class);
}
public static void set(BootLog bootLog) throws NameAlreadyBoundException, NamingException {
InitialNaming.bind(BootLog.class, bootLog);
}
}BootLog is used extensively across the codebase (240+ references), typically for:
- Driver initialization — Device managers, drivers, bus enumeration
- Compiler debug output — L1/L2 compiler state, method compilation
- Plugin lifecycle — Plugin loading, dependency resolution
- Error reporting — Fatal conditions, missing resources
Example usage:
// From DefaultDeviceManager.java
BootLogInstance.get().debug("Found " + extensions.length + " device finders");
BootLogInstance.get().warn("Ignoring unrecognised descriptor element: " + elementName);
BootLogInstance.get().error("Cannot find finder class " + className, ex);- No filtering — Unlike Log4j, BootLog has no concept of log levels to suppress output; all calls print immediately.
- No category/logger separation — All messages go through a single global logger; no per-component filtering.
-
InitialNaming dependency —
BootLogInstance.get()will throw anErrorif called beforeInitialNamingis initialized. -
Debug output streams — The
setDebugOut()method only affects DEBUG level; other levels use System.out/System.err directly. -
No exception handling during fatal — The
error()method historically had a commented-outThread.sleep()for crash dump scenarios.
- Boot-Sequence — Where BootLog fits in the boot process (Phase 2: VM Initialization)
- InitialNaming-Service-Registry — The service registry BootLogInstance uses
- VM-Unsafe — Fallback output used when PrintStreams aren't available
- Architecture — System layers, where boot logging fits