NjConsole Docs

πŸ“ NjLogger & Logs panel

πŸ“˜ NjLogger basics

NjLogger is a high-performance alternative to Debug.Log, designed to minimize overhead and integrate tightly with NjConsole. Compared to Debug.Log, which allocates memory and generates costly stack traces, NjLogger offers:

// These logs will appear in NjConsole with appropriate severity styling
NjLogger.Debug("This is a debug level text - they get auto excluded in release builds");
NjLogger.Info("This is an info level text");
NjLogger.Warn("This is a warning level text");
NjLogger.Error("This is an error level text - an alert shows when an error is logged.");
        
// Mixing types? No problem. This won't allocate.
NjLogger.Info("Mix argument types without allocation... integer:",123," float:", 123.45f," bool:", true);

// Link to objects for runtime inspection
var playerObj = GetTestPlayerObj();
NjLogger.Info("Here is a log with a link to ", playerObj.AsLogRef(), " - you can inspect it");

// Log object as plain string (no link)
NjLogger.Info("If you don't want a link, this is how... ", playerObj.AsString());

// Use named channels to group logs (recommended to keep as static readonly)
static readonly LogChannel channel = new LogChannel("myChannel");

channel.Info("A log in `myChannel`");
channel.Warn("A warning in `myChannel`");

// Unity's native logs still show up in NjConsole
Debug.Log("Logs from Unity’s Debug.Log() automatically appear in NjConsole");

Screenshot of logs panel

πŸ” Log filtering

Screenshot of log filtering

NjConsole provides powerful filtering options to help you focus on the logs that matter:

πŸ”— Logs object linking

You can include object references directly in your logs.
When clicked, they open in the Object Inspector for quick inspection and editing.

var playerObj = GetTestPlayerObj();
NjLogger.Info("Here is a log with a link to ", playerObj);
NjLogger.Info("Here is a link to ", playerObj.AsLogRef(), " - mixed in multiple arguments");

When you click the log entry in the console, a button will appear for any linked object:
Screenshot of object link
Clicking the button opens the object in the inspector:
Screenshot of object link

♻️ Memory-Safe by Design
Object links are held via weak references, so they won’t cause memory leaks. However, if the object is garbage collected, the link may expire.
To retain the object for the log’s lifetime (as long as it stays in the ring buffer), use a strong reference:
NjLogger.Info("A strong object link:", aTestObj.AsStrongLogRef());

⚠️ Limitations
While you can view and modify many fields and properties, not all data types are fully editable (yet).

πŸ”§ Advanced topics

πŸ” Sending Logs To NjLogger from Your Own Logger

πŸ”€ Sending Logs From NjLogger to Your Own Logger

To forward logs from NjLogger into your own logging system, implement and register a custom NjLogger.IHandler.

// Register once during initialization
NjLogger.AddHandler(new MyLoggerBridge());

public class MyLoggerBridge : NjLogger.IHandler {
  public void HandleLog(ref NjLogger.LogRow logRow){
    var message = logRow.GetString(LoggerUtils.TempStringBuilder);
    var level = logRow.Level;
    // Forward to your logger
  }
  public void HandleException(Exception exception, ref LogRow logRow){
    var message = logRow.GetString(LoggerUtils.TempStringBuilder);
    var level = logRow.Level;
    // Forward exception to your logger
  }
}

⚠️ Only register your handler once. Multiple registrations will result in duplicate logs.

🧡 Extracting Log Strings from NjLogger

NjLogger stores logs in a rotating ring buffer, with the size controlled by MaxHistoryCount (set in Project Settings for Editor/Player).

To export logs (from newest to oldest) as a single string:

var stringBuilder = new StringBuilder();
NjLogger.LogsHistory.GenerateHistoryNewestToOldest(stringBuilder);
var logMessages = stringBuilder.ToString();

For finer control, you can iterate manually:

NjLogger.LogsHistory.ForEachLogNewestToOldest((log) =>
{
    var message = log.GetLineString();
    var level = log.Level;
    var time = log.Time;
    var channelName = log.GetChannelName();
    var channelTag = !string.IsNullOrEmpty(channelName) ? $" [{channelName}]" : "";
    var formattedLogString = $"[{time:HH:mm:ss}] [{level}]{channelTag} {message}";

    //Debug.Log(formattedLogString);
});

If you need the other direction, use ForEachLogOldestToNewest

⏱ Customize timestamp format in logs panel

  1. Create a class that implements both IConsoleTimestampFormatter and IConsoleExtension.
  2. Mark the class with the [Serializable] attribute.
    [Serializable]
    public class MyCustomTimestampFormatter : IConsoleTimestampFormatter, IConsoleExtension
    {
     public void AppendFormatted(LogLine log, StringBuilder stringBuilder)
     {
         var time = log.Time;
         LoggerUtils.AppendNumWithZeroPadding(stringBuilder, time.Hour, 2);
         stringBuilder.Append(":");
         LoggerUtils.AppendNumWithZeroPadding(stringBuilder, time.Minute, 2);
         stringBuilder.Append(":");
         LoggerUtils.AppendNumWithZeroPadding(stringBuilder, time.Second, 2);
     }
    }
    
  3. In Project Settings > NjConsole > Extension Modules, add your new class to the list.
  4. Click Apply Extension Changes to reload.
  5. In the Logs Panel, click the Time dropdown (top-right), and select Custom Module.
    Note. if you have multiple IConsoleTimestampFormatter modules added, it might not pick the right one.

NjConsole doc home