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

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

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

import java.time.ZoneId;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

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;

import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.classic.spi.ThrowableProxyUtil;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.encoder.Encoder;

/**
 * @author xiaomeng.hxm
 *
 */
public class SchedulerxLogbackAppender extends UnsynchronizedAppenderBase {

    private String userAgent = "logback";

    protected Encoder encoder;

    protected String topic = ""; //
    protected String source = ""; //

    protected String timeZone = "UTC";
    protected String timeFormat = "yyyy-MM-dd'T'HH:mmZ";
    protected DateTimeFormatter formatter;
    protected java.time.format.DateTimeFormatter formatter1;
    
    @Override
    public void start() {
        try {
            doStart();
        } catch (Exception e) {
            addError("Failed to start SchedulerxLogbackAppender.", e);
        }
    }

    private void doStart() {
        try {
            formatter = DateTimeFormat.forPattern(timeFormat).withZone(DateTimeZone.forID(timeZone));
        } catch (Exception e){
            formatter1 = java.time.format.DateTimeFormatter.ofPattern(timeFormat).withZone(ZoneId.of(timeZone));
        }
        
        super.start();
    }

    @Override
    public void stop() {
        try {
            doStop();
        } catch (Exception e) {
            addError("Failed to stop SchedulerxLogbackAppender.", e);
        }
    }

    private void doStop() throws InterruptedException {
        if (!isStarted()) {
            return;
        }

        super.stop();
    }

    @Override
    public void append(E eventObject) {
        try {
            appendEvent(eventObject);
        } catch (Exception e) {
            addError("Failed to append event.", e);
        }
    }

    private void appendEvent(E eventObject) {
        //init Event Object
        if (!(eventObject instanceof LoggingEvent)) {
            return;
        }
        
        LoggingEvent event = (LoggingEvent) eventObject;
        
        JobContext jobContext = ContainerFactory.getContainerPool().getContext();
        //如果不在ThreadContainer的线程中,当前版本不收集
        if (jobContext == null) {
            addWarn("jobContext is null, threadName=" + event.getThreadName()
                + ", stackTrace=" + event.getCallerData() + ", message=" + event.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.getFormattedMessage();
            builder.setMessage(message);
            builder.setThread(event.getThreadName());
            builder.setGroup("schedulerx-user");
            builder.setSource(SchedulerxWorker.WORKER_ADDR);
            if (this.encoder != null) {
                builder.setLog(new String(this.encoder.encode(eventObject)));
            } else {
                builder.setLog(message);
            }
            IThrowableProxy iThrowableProxy = event.getThrowableProxy();
            if (iThrowableProxy != null) {
                String throwable = getExceptionInfo(iThrowableProxy);
                throwable += fullDump(event.getThrowableProxy().getStackTraceElementProxyArray());
                builder.setThrowable(throwable);
            }
            
            ServerDiscovery serverDiscovery = ServerDiscoveryFactory.getDiscovery(jobContext.getGroupId());
            if (serverDiscovery != null && serverDiscovery.getLogRouter() != null) {
                serverDiscovery.getLogRouter().tell(builder.build(), null);
            } else {
                addWarn("serverDiscovery or LogRouter is null, groupId=" + jobContext.getGroupId());
            }
        } catch (Exception e) {
            addWarn("report log failed, appGroupId=" + jobContext.getAppGroupId() + ", key=" + jobContext.getUniqueId(), e);
        }
    }

    /**
     * createTopic
     * @param jobContext
     * @return
     */
    private String createTopic(JobContext jobContext) {
        return "group-" + jobContext.getAppGroupId();
    }

    public String getTimeFormat() {
        return timeFormat;
    }

    public void setTimeFormat(String timeFormat) {
        this.timeFormat = timeFormat;
    }

    private String getExceptionInfo(IThrowableProxy iThrowableProxy) {
        String s = iThrowableProxy.getClassName();
        String message = iThrowableProxy.getMessage();
        return (message != null) ? (s + ": " + message) : s;
    }

    private String fullDump(StackTraceElementProxy[] stackTraceElementProxyArray) {
        StringBuilder builder = new StringBuilder();
        for (StackTraceElementProxy step : stackTraceElementProxyArray) {
            builder.append(CoreConstants.LINE_SEPARATOR);
            String string = step.toString();
            builder.append(CoreConstants.TAB).append(string);
            ThrowableProxyUtil.subjoinPackagingData(builder, step);
        }
        return builder.toString();
    }

    public String getTopic() {
        return topic;
    }

    public void setTopic(String topic) {
        this.topic = topic;
    }

    public String getSource() {
        return source;
    }

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

    public String getTimeZone() {
        return timeZone;
    }

    public void setTimeZone(String timeZone) {
        this.timeZone = timeZone;
    }

    public String getUserAgent() {
        return userAgent;
    }

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

    public Encoder getEncoder() {
        return encoder;
    }

    public void setEncoder(Encoder encoder) {
        this.encoder = encoder;
    }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy