将Log4j PatternLayout扩展转换为Log4j2

eulz3vhy  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(150)

我正在将一个大型应用程序从Log4j1转换为Log4j2,并发现了这个类。PatternLayout不能在Log4j2中扩展,但我知道我使用Plugins将这个类转换为Lug4j2。我查看了这些教程(Extending Log4j2Log4j2 PluginsProgrammatic Configuration with Log4j2),但我还不知道具体怎么做,看来只能套用教程了,如果它与所介绍的用例完全相同。有人能帮助我吗?如何获得具体信息?我必须查看Log4j2源代码吗?

package aa.bbb.cccc;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import org.apache.log4j.Level;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

public class PatternLayout extends org.apache.log4j.PatternLayout {

    private static final SimpleDateFormat DATE_FORMAT;

    /**
     * ANSI-Format for the level
     */
    private static final HashMap<Level, CliColor> LEVELS;

    static {
        LEVELS = new HashMap<Level, CliColor>();
        LEVELS.put(Level.TRACE, CliColor.BLUE);
        LEVELS.put(Level.DEBUG, CliColor.CYAN);
        LEVELS.put(Level.INFO, CliColor.GREEN);
        LEVELS.put(Level.WARN, CliColor.YELLOW);
        LEVELS.put(Level.ERROR, CliColor.RED);
        LEVELS.put(Level.FATAL, CliColor.RED);
        DATE_FORMAT = new SimpleDateFormat("HH:mm:ss,SSS");
    }

    /**
     * Pads a string until it has the desired length. The space
     * is filled with spaces.
     *
     * @param str The string to pad.
     * @param length The desired length of the string.
     * @return A padded string.
     */
    public static String leftPad(String str, int length) {
        if (str.length() > length) {
            return str.substring(0, length);
        }

        if (str.length() < length) {
            StringBuilder stringBuilder = new StringBuilder(str);
            for (int i = str.length(); i < length; ++i) {
                stringBuilder.append(' ');
            }
            return stringBuilder.toString();
        }

        return str;
    }

    @Override
    public String format(LoggingEvent event) {
        return String.format("%s %s %s %s\n", DATE_FORMAT.format(new Date()),
                        formatLevel(event), formatLocationInfo(event),
                        formatMessage(event));
    }

    /**
     * @param event The event that gets formatted
     * @return A string representing the log level.
     */
    private String formatLevel(LoggingEvent event) {
        Level level = event.getLevel();
        String levelName = leftPad(level.toString(), 5);
        CliColor ansiConfig = LEVELS.get(level);

        if (ansiConfig == null) {
            return CliColor.color(levelName, CliColor.BOLD);
        }

        return CliColor.color(levelName, CliColor.BOLD, ansiConfig);
    }

    /**
     * @param event The event that gets formatted
     * @return A formatted location info.
     */
    private String formatLocationInfo(LoggingEvent event) {
        LocationInfo locationInfo = event.getLocationInformation();
        final String line = locationInfo.getLineNumber();
        String className = locationInfo.getClassName();
        className = className.substring(className.lastIndexOf('.') + 1);

        return "[\u001b[0;33m" + className + ":" + line + "\u001B[m]";
    }

    /**
     * @param event The event that gets formatted
     * @return Formatted message.
     */
    private String formatMessage(LoggingEvent event) {
        if (event.getMessage() == null) {
            return "";
        }

        return event.getMessage().toString();
    }
}
y4ekin9u

y4ekin9u1#

由于PatternLayout本身是final,因此您可以改为扩展PatternLayout的父类并完成任务。

package com.example;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;

public class HelloPattern extends AbstractStringLayout {

    private static final SimpleDateFormat DATE_FORMAT;
    /**
     * ANSI-Format for the level
     */
    private static final HashMap<Level, CliColor> LEVELS;

    static {
        LEVELS = new HashMap<Level, CliColor>();
        LEVELS.put(Level.TRACE, CliColor.BLUE);
        LEVELS.put(Level.DEBUG, CliColor.CYAN);
        LEVELS.put(Level.INFO, CliColor.GREEN);
        LEVELS.put(Level.WARN, CliColor.YELLOW);
        LEVELS.put(Level.ERROR, CliColor.RED);
        LEVELS.put(Level.FATAL, CliColor.RED);
        DATE_FORMAT = new SimpleDateFormat("HH:mm:ss,SSS");
    }

    protected HelloPattern(Charset charset) {
        super(charset);
    }

    protected HelloPattern(Charset aCharset, byte[] header, byte[] footer) {
        super(aCharset, header, footer);
    }

    protected HelloPattern(Configuration config,
        Charset aCharset,
        Serializer headerSerializer,
        Serializer footerSerializer) {
        super(config, aCharset, headerSerializer, footerSerializer);
    }

    /**
     * Pads a string until it has the desired length. The space is filled with spaces.
     *
     * @param str    The string to pad.
     * @param length The desired length of the string.
     * @return A padded string.
     */
    public static String leftPad(String str, int length) {
        if (str.length() > length) {
            return str.substring(0, length);
        }

        if (str.length() < length) {
            StringBuilder stringBuilder = new StringBuilder(str);
            for (int i = str.length(); i < length; ++i) {
                stringBuilder.append(' ');
            }
            return stringBuilder.toString();
        }

        return str;
    }

    @Override
    public boolean requiresLocation() {
        return true;
    }

    @Override
    public String toSerializable(LogEvent event) {
        return String.format("%s %s %s %s\n", DATE_FORMAT.format(new Date()),
            formatLevel(event), formatLocationInfo(event),
            formatMessage(event));
    }

    /**
     * @param event The event that gets formatted
     * @return A string representing the log level.
     */
    private String formatLevel(LogEvent event) {
        Level level = event.getLevel();
        String levelName = leftPad(level.toString(), 5);
        CliColor ansiConfig = LEVELS.get(level);

        if (ansiConfig == null) {
            return CliColor.color(levelName, CliColor.BOLD);
        }

        return CliColor.color(levelName, CliColor.BOLD, ansiConfig);
    }

    /**
     * @param event The event that gets formatted
     * @return A formatted location info.
     */
    private String formatLocationInfo(LogEvent event) {
        Throwable thrown = event.getThrown();
        final int line = thrown.getStackTrace()[0].getLineNumber();
        String className = thrown.getStackTrace()[0].getClassName();
        className = className.substring(className.lastIndexOf('.') + 1);

        return "[\u001b[0;33m" + className + ":" + line + "\u001B[m]";
    }

    //Tried best to get it right

    /**
     * @param event The event that gets formatted
     * @return Formatted message.
     */
    private String formatMessage(LogEvent event) {
        if (event.getMessage() == null) {
            return "";
        }

        return event.getMessage().toString();
    }

    enum CliColor {
        BLUE, CYAN, GREEN, YELLOW, RED, BOLD;

        public static String color(String level, CliColor color) {
            return "stringBasedonyourimplementation";
        }

        public static String color(String levelName, CliColor bold, CliColor ansiConfig) {
            return "stringBasedonyourimplementation";
        }
    }
}

注意:因为我没有足够的关于CliColor的信息,所以添加了mock impl来给予你这个想法。另外还有locationInfo。

相关问题