Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Log Utils] Make Non-Static/Modify backend.

Open
#6 3 comments 0 reactions 1 assignee View on GitHub

@Jonathing is already working on this.

Since May 15, 2025.

Assessment

This issue has not been assessed yet.

Description

Currently I am using a custom Logger that allows for using the Log4J backend.
Specifically its the use of the StringFormatterMessageFactory which allows for String.format style log commands:
info("[%3d/%3d] Running test", current, max)
[INFO] [ 1/100] Running Test
As well as exception as last argument support:
info("Failed to download %s", fileName, ex)

[INFO] Failed to download version.json
java.io.IOException: File Not Found
  at whatever

I also made it implement Closeable so I can do things like:

try (var l = log.push()) {
  log.info("This is indented");
}
log.info("This is not");

At the end of the day it just drills down to log(Level, String) and log(Level, String, Object[]) so it doesn't need to use L4J levels, but allowing things to be instance based would allow the consumer to choose. I specifically care because I like L4J's logging to a file. Tho that can be easily duplicated without L4J.

package net.minecraftforge.ir.util;

import java.io.Closeable;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.StringFormatterMessageFactory;

public class Log implements Closeable {
    private static Class<?> getCallerClass() {
        StackTraceElement ste = Thread.currentThread().getStackTrace()[3];
        try {
            return Class.forName(ste.getClassName());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private final Logger logger;
    private int tabLevel = 0;

    public Log() {
        this(LogManager.getLogger(getCallerClass(), StringFormatterMessageFactory.INSTANCE));
    }

    public Log(Logger logger) {
        this.logger = logger;
    }

    @Override
    public void close() {
        tabLevel--;
    }

    public Log push() {
        tabLevel++;
        return this;
    }

    public Log pop() {
        tabLevel--;
        return this;
    }

    private String getIndent() {
        return "  ".repeat(tabLevel);
    }

    private void log(Level level, String message) {
        logger.log(level, getIndent() + message);
    }

    private void log(Level level, String message, Object[] args) {
        logger.log(level, getIndent() + message, args);
    }

    public void info(String message) {
        log(Level.INFO, message);
    }

    public void info(String message, Object... args) {
        log(Level.INFO, message, args);
    }

    public void warn(String message) {
        log(Level.WARN, message);
    }

    public void warn(String message, Object... args) {
        log(Level.WARN, message, args);
    }

    public void error(String message) {
        log(Level.ERROR, message);
    }

    public void error(String message, Object... args) {
        log(Level.ERROR, message, args);
    }

    public void debug(String message) {
        log(Level.DEBUG, message);
    }

    public void debug(String message, Object... args) {
        log(Level.DEBUG, message, args);
    }
}

Dominant language
Java
Stars
0
Forks
5
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from MinecraftForge/Utils

All issues in MinecraftForge/Utils

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.