Printing the “source” class in a log statement with a log4j wrapper

后端 未结 3 1990
遇见更好的自我
遇见更好的自我 2021-01-02 19:02

My application has a homebrew logging class that I\'m migrating to using log4j under the covers. However, since I\'m using the homebrew class to pass the rest of the applica

3条回答
  •  [愿得一人]
    2021-01-02 19:50

    In Log4J API about Logger.log(String callerFQCN, Priority level, Object message, Throwable t):

    Parameters:

    • callerFQCN - The wrapper class' fully qualified class name.
    • level - The level of the logging request.
    • message - The message of the logging request.
    • t - The throwable of the logging request, may be null.

    See: Log4J API.

    Quite weird I know, argument is called "callerFQCN" which seams to be the caller object class, BUT (muajaja!) it's actually the "wrapper" class (ex MyClass.class.getName()).

    Actually, the caller is get by the Throwable argument I think. Not sure, haven't checked the implementation.

    As you leave Throwable argument null, I think something like this must be happening below:

    StackTraceElement[] stack = (new Throwable()).getStackTrace();
    String caller = stack[something, meaby 1].getClassName();
    

    If you want to create a Logger wrapper you need to do something like this:

    public static void myWarn(String message) {
        myLogger.log(MyWrapper.class.getName(), message, Level.WARN, null);
    }
    

    This work without problem as a wrapper.

    Or, if you absolutely need to maintain the interface you show below, do something like this:

    // Warning: Pseudocode
    public static void myWarn(Object source, String message) {
        String sourceClass = source.class.GetName();
        StackTraceElement[] stack = (new Throwable()).getStackTrace();
        stack[1, or meaby 2... or 0?] = new whatever(sourceClass);
        myLogger.log(MyWrapper.class.getName(), message, Level.WARN, myStack);
    }
    

    Hope this helps.

提交回复
热议问题