All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4j2Appender Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
package com.alibaba.schedulerx.worker.log.appender;

import java.io.Serializable;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.util.Booleans;
import org.apache.logging.log4j.core.util.Throwables;
import org.apache.logging.log4j.status.StatusLogger;
import org.joda.time.DateTime;

import com.alibaba.schedulerx.common.constants.CommonConstants;
import com.alibaba.schedulerx.protocol.Worker.WorkerReportLogRequest;
import com.alibaba.schedulerx.worker.SchedulerxWorker;
import com.alibaba.schedulerx.worker.container.ContainerFactory;
import com.alibaba.schedulerx.worker.discovery.ServerDiscovery;
import com.alibaba.schedulerx.worker.discovery.ServerDiscoveryFactory;
import com.alibaba.schedulerx.worker.domain.JobContext;

/**
 * @author xiaomeng.hxm
 *
 */
@Plugin(name = "SchedulerxLog4j2Appender", category = "Core", elementType = "appender", printObject = true)
public class SchedulerxLog4j2Appender extends AbstractAppender {

    private String userAgent = "log4j2";
    private String source;

    private static final Logger logger = StatusLogger.getLogger();
    
    protected SchedulerxLog4j2Appender(String name,
                             Filter filter,
                             Layout layout,
                             boolean ignoreExceptions                      
    ) {
        super(name, filter, layout, ignoreExceptions);
    }

    @Override
    public void start() {
        try {
            super.start();
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    @Override
    public void stop() {
        super.stop();
    }

    @Override
    public void append(LogEvent event) {
        JobContext jobContext = ContainerFactory.getContainerPool().getContext();
        //如果不在ThreadContainer的线程中,当前版本不收集
        if (jobContext == null) {
            logger.warn("jobContext is null, threadName={}, stackTrace={}, message={}", 
                event.getThreadName(), event.getSource(), event.getMessage().getFormattedMessage());
            return;
        }
        if (StringUtils.isEmpty(jobContext.getGroupId()) || !LogConfig.INSTANCE.isEnable()) {
            return;
        }
        
        try {
            WorkerReportLogRequest.Builder builder = WorkerReportLogRequest.newBuilder();
            builder.setAppGroupId(jobContext.getAppGroupId());
            builder.setExecutionId(jobContext.getUniqueId());
            builder.setTime(DateTime.now().toString(CommonConstants.DATE_TIME_PATTERN));
            builder.setLevel(event.getLevel().toString());
            String message = event.getMessage().getFormattedMessage();
            builder.setMessage(event.getMessage().getFormattedMessage());
            builder.setThread(event.getThreadName());
            builder.setGroup("schedulerx-user");
            builder.setSource(SchedulerxWorker.WORKER_ADDR);
            if (getLayout() != null) {
                builder.setLog(new String(getLayout().toByteArray(event)));
            } else {
                builder.setLog(message);
            }
            String throwable = getThrowableStr(event.getThrown());
            if (throwable != null) {
                builder.setThrowable(throwable);
            }
            
            ServerDiscovery serverDiscovery = ServerDiscoveryFactory.getDiscovery(jobContext.getGroupId());
            if (serverDiscovery != null && serverDiscovery.getLogRouter() != null) {
                serverDiscovery.getLogRouter().tell(builder.build(), null);
            } else {
                LOGGER.warn("serverDiscovery or LogRouter is null, groupId={}", jobContext.getGroupId());
            }
        } catch (Exception e) {
            LOGGER.warn("report log failed, appGroupId={}, key={}", jobContext.getAppGroupId(), jobContext.getUniqueId(), e);
        }
    }

    private String getThrowableStr(Throwable throwable) {
        if (throwable == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (String s : Throwables.toStringList(throwable)) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append(System.getProperty("line.separator"));
            }
            sb.append(s);
        }
        return sb.toString();
    }

    @PluginFactory
    public static SchedulerxLog4j2Appender createAppender(
            @PluginAttribute("name") final String name,
            @PluginElement("Filter") final Filter filter,
            @PluginElement("Layout") Layout layout,
            @PluginConfiguration final Configuration config,
            @PluginAttribute("ignoreExceptions") final String ignore,
            @PluginAttribute("project") final String project,
            @PluginAttribute("logStore") final String logStore,
            @PluginAttribute("endpoint") final String endpoint,
            @PluginAttribute("accessKeyId") final String accessKeyId,
            @PluginAttribute("accessKeySecret") final String accessKeySecret,
            @PluginAttribute("stsToken") final String stsToken,

            @PluginAttribute("totalSizeInBytes") final String  totalSizeInBytes,
            @PluginAttribute("maxBlockMs") final String  maxBlockMs,
            @PluginAttribute("ioThreadCount") final String  ioThreadCount,
            @PluginAttribute("batchSizeThresholdInBytes") final String  batchSizeThresholdInBytes,
            @PluginAttribute("batchCountThreshold") final String  batchCountThreshold,
            @PluginAttribute("lingerMs") final String  lingerMs,
            @PluginAttribute("retries") final String  retries,
            @PluginAttribute("baseRetryBackoffMs") final String  baseRetryBackoffMs,
            @PluginAttribute("maxRetryBackoffMs") final String maxRetryBackoffMs,

            @PluginAttribute("topic") final String topic,
            @PluginAttribute("source") final String source,
            @PluginAttribute("timeFormat") final String timeFormat,
            @PluginAttribute("timeZone") final String timeZone,
            @PluginAttribute("mdcFields") final String mdcFields) {

        Boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
        return new SchedulerxLog4j2Appender(name, filter, layout, ignoreExceptions);
    }

    static boolean isStrEmpty(String str) {
        return str == null || str.length() == 0;
    }

    static int parseStrToInt(String str, final int defaultVal) {
        if (!isStrEmpty(str)) {
            try {
                return Integer.valueOf(str);
            } catch (NumberFormatException e) {
                return defaultVal;
            }
        } else {
            return defaultVal;
        }
    }

    static void checkCondition(Boolean condition, String errorMsg) {
        if (!condition) {
            throw new IllegalArgumentException(errorMsg);
        }
    }

    public String getUserAgent() {
        return userAgent;
    }

    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy