com.alibaba.schedulerx.worker.log.appender.SchedulerxLog4jAppender Maven / Gradle / Ivy
package com.alibaba.schedulerx.worker.log.appender;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
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
*
*/
public class SchedulerxLog4jAppender extends AppenderSkeleton {
private String userAgent = "log4j";
private String source = "";
private String timeFormat = "yyyy-MM-dd'T'HH:mm:ssZ";
private String timeZone = "UTC";
@Override
public void activateOptions() {
try {
super.activateOptions();
} catch (Exception e) {
LogLog.error("", e);
}
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
doClose();
} catch (Exception e) {
LogLog.error("Failed to close LoghubAppender.", e);
}
}
});
}
@Override
public void close() {
try {
doClose();
} catch (Exception e) {
LogLog.error("Failed to close LoghubAppender.", e);
}
}
private void doClose() throws InterruptedException {
}
@Override
public boolean requiresLayout() {
return true;
}
@Override
protected void append(LoggingEvent event) {
JobContext jobContext = ContainerFactory.getContainerPool().getContext();
//如果不在ThreadContainer的线程中,当前版本不收集
if (jobContext == null) {
LogLog.warn("jobContext is null, threadName=" + event.getThreadName() + ", message=" + event.getMessage().toString());
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());
Object message = event.getMessage();
if (message == null) {
builder.setMessage("");
} else {
builder.setMessage(event.getMessage().toString());
}
builder.setThread(event.getThreadName());
builder.setGroup("schedulerx-user");
builder.setSource(SchedulerxWorker.WORKER_ADDR);
if (getLayout() != null) {
builder.setLog(getLayout().format(event));
} else {
builder.setLog(event.getMessage().toString());
}
String throwable = getThrowableStr(event);
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 {
LogLog.warn("serverDiscovery or LogRouter is null, groupId={}" + jobContext.getGroupId());
}
} catch (Exception e) {
LogLog.warn("report log failed, appGroupId=" + jobContext.getAppGroupId() + ", key=" + jobContext.getUniqueId(), e);
}
}
/**
* createTopic
* @param jobContext
* @return
*/
private String createTopic(JobContext jobContext) {
return "group-" + jobContext.getAppGroupId();
}
private String getThrowableStr(LoggingEvent event) {
ThrowableInformation throwable = event.getThrowableInformation();
if (throwable == null) {
return null;
}
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (String s : throwable.getThrowableStrRep()) {
if (isFirst) {
isFirst = false;
} else {
sb.append(System.getProperty("line.separator"));
}
sb.append(s);
}
return sb.toString();
}
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;
}
public String getTimeFormat() {
return timeFormat;
}
public void setTimeFormat(String timeFormat) {
this.timeFormat = timeFormat;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
}