【PowerJob】如何扩展OmsLogger实现普通日志上报

31 阅读1分钟

为什么要扩展OmsLogger?

旧代码中通常使用slf4j日志门面+logback或者log4j日志实现打印日志,在PowerJob执行中不会上报这些日志,只会上报OmsLogger的日志,如果将旧代码中的日志全部改成OmgLogger也不现实,会造成业务代码和日志强耦合的情况。

扩展实现

针对常用的日志实现扩展日志附加器,下面给出log4j和logback的扩展,其他日志同理。

代码可参考github:github.com/zendodx/pow…

log4j日志附加器

使用ThreadLocal存储OmgLogger,打印日志时额外使用OmgLogger打印。

/**
 * Log4j 2.x Appender,把日志实时转发到 PowerJob OmsLogger
 * <p>
 * 配置方式(log4j2.xml):
 * {@code <OmsLogger name="OMS" pattern="%m%n"/>}
 * <p>
 * 代码中:
 * {@code OmsLogger logger = context.getOmsLogger();Log4j2OmsLoggerAppender.setOmsLogger(logger);}
 */
@Plugin(name = "OmsLogger", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
public class Log4j2OmsLoggerAppender extends AbstractAppender {
    private static final ThreadLocal<OmsLogger> HOLDER = new InheritableThreadLocal<>();

    protected Log4j2OmsLoggerAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, Property[] properties) {
        super(name, filter, layout, ignoreExceptions, properties);
    }

    @PluginFactory
    public static Log4j2OmsLoggerAppender createAppender(
            @PluginAttribute("name") String name,
            @PluginElement("Filter") Filter filter,
            @PluginAttribute("pattern") String pattern,
            @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
            @PluginAttribute("properties") Property[] properties) {
        PatternLayout layout = PatternLayout.newBuilder().withPattern(pattern).build();
        return new Log4j2OmsLoggerAppender(name, filter, layout, ignoreExceptions, properties);
    }

    public static void setOmsLogger(OmsLogger logger) {
        HOLDER.set(logger);
    }

    public static void remove() {
        HOLDER.remove();
    }

    @Override
    public void append(LogEvent event) {
        OmsLogger omsLogger = HOLDER.get();
        if (omsLogger == null) return;
        String msg = Arrays.toString(getLayout().toByteArray(event)).trim();
        switch (event.getLevel().intLevel()) {
            case 400: // INFO
                omsLogger.info(msg);
                break;
            case 500: // WARN
                omsLogger.warn(msg);
                break;
            case 600: // ERROR
                omsLogger.error(msg, event.getThrown());
                break;
            default:
                omsLogger.debug(msg);
        }
    }
}

logback日志附加器

使用ThreadLocal存储OmgLogger,打印日志时额外使用OmgLogger打印。

/**
 * logback适配OmsLogger的适配器
 * <p>
 * 配置方式(logback.xml):
 * {@code <appender name="OMS" class="tech.powerjob.worker.extend.log.LogbackOmsLoggerAppender"/>}
 * <p>
 * 代码中:
 * {@code OmsLogger logger = context.getOmsLogger();LogbackOmsLoggerAppender.setOmsLogger(logger);}
 */
public class LogbackOmsLoggerAppender extends AppenderBase<ILoggingEvent> {
    private static final ThreadLocal<OmsLogger> HOLDER = new InheritableThreadLocal<>();

    /* 由 Processor 启动时注入 */
    public static void setOmsLogger(OmsLogger logger) {
        HOLDER.set(logger);
    }

    public static void remove() {
        HOLDER.remove();
    }

    @Override
    protected void append(ILoggingEvent event) {
        OmsLogger omsLogger = HOLDER.get();
        if (omsLogger == null) {
            return;
        }
        String msg = event.getFormattedMessage();
        switch (event.getLevel().toInt()) {
            case Level.INFO_INT:
                omsLogger.info(msg);
                break;
            case Level.WARN_INT:
                omsLogger.warn(msg);
                break;
            case Level.ERROR_INT:
                omsLogger.error(msg, event.getThrowableProxy() != null ? ((ThrowableProxy) event.getThrowableProxy()).getThrowable() : null);
                break;
            default:
                omsLogger.debug(msg);
        }
    }
}