帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

165 lines
6.0 KiB

package com.fr.design.mainframe.errorinfo;
import com.fr.base.io.IOFile;
import com.fr.base.io.XMLReadHelper;
import com.fr.design.DesignerEnvManager;
import com.fr.design.i18n.Toolkit;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.third.apache.logging.log4j.core.Filter;
import com.fr.third.apache.logging.log4j.core.Layout;
import com.fr.third.apache.logging.log4j.core.LogEvent;
import com.fr.third.apache.logging.log4j.core.appender.AbstractAppender;
import com.fr.third.apache.logging.log4j.core.config.Property;
import com.fr.third.apache.logging.log4j.core.layout.PatternLayout;
import com.fr.web.session.SessionLocalManager;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.stable.web.SessionProvider;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.web.core.SessionPoolManager;
import com.fr.web.core.TemplateSessionIDInfo;
import com.fr.workspace.WorkContext;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
/**
* 收集设计器报错信息的appender.
* <p>
* Created by Administrator on 2017/7/24 0024.
*/
public class ErrorInfoLogAppender extends AbstractAppender {
private static final int ERROR_LEN = 8;
private static final int ERROR_STACK_TRACE = 15;
private static final String ERROR_CODE = Toolkit.i18nText("Fine-Design_Report_Engine_ErrorCode_Prefix") + ".*?[:,:]";
// 缓存下不变的, 没必要频繁取.
private String username;
private String uuid;
private String activekey;
protected ErrorInfoLogAppender(String name, Filter filter,
Layout<? extends Serializable> layout,
boolean ignoreExceptions,
Property[] properties) {
super(name, filter, layout, ignoreExceptions, properties);
DesignerEnvManager envManager = DesignerEnvManager.getEnvManager();
this.username = envManager.getDesignerLoginUsername();
this.uuid = envManager.getUUID();
this.activekey = envManager.getActivationKey();
}
public static ErrorInfoLogAppender createErrorLogAppender() {
return new ErrorInfoLogAppender(ErrorInfoLogAppender.class.getSimpleName(), null, PatternLayout.newBuilder().withPattern("%d{HH:mm:ss} %t %p [%c] %m%n %throwable{0}").build(), false, Property.EMPTY_ARRAY);
}
@Override
public void append(LogEvent event) {
this.subAppend(event);
}
public boolean requiresLayout() {
return true;
}
public void subAppend(LogEvent event) {
Level level = event.getLevel();
// 只分析上传记录error以上的.
if (level.isMoreSpecificThan(Level.ERROR)) {
String msg = (String) this.toSerializable(event);
// 这个id并不是一定会有的, 有就记录下, 说明是预览模板出的错.
String templateid = readTemplateID();
String logid = readLogID(msg);
ErrorInfo errorInfo = new ErrorInfo(username, uuid, activekey);
errorInfo.setTemplateid(templateid);
errorInfo.setLog(msg);
errorInfo.setLogid(logid);
errorInfo.setStackTrace(readStackTrace(event));
errorInfo.saveAsJSON();
}
}
private String readStackTrace(LogEvent event) {
StackTraceElement[] s = event.getThrown() == null ? null : event.getThrown().getStackTrace();
StringBuilder sb = new StringBuilder();
if (s != null) {
int len = Math.min(s.length, ERROR_STACK_TRACE);
for (int i = 0; i < len; i++) {
sb.append(s[i].toString()).append("\n");
}
}
return sb.toString();
}
private String readLogID(String log) {
// 报错信息国际化不规范, 有些是中文分号, 有些是英文
String[] matchs = log.split(ERROR_CODE);
if (matchs.length <= 1) {
return StringUtils.EMPTY;
}
String includeIDStr = matchs[1].trim();
try {
return Long.parseLong(includeIDStr.substring(0, ERROR_LEN)) + StringUtils.EMPTY;
} catch (Exception ignore) {
}
return StringUtils.EMPTY;
}
private String readTemplateID() {
SessionProvider logDuration = SessionLocalManager.getSession();
if (logDuration == null) {
return StringUtils.EMPTY;
}
String sessionID = logDuration.getSessionID();
TemplateSessionIDInfo infor = SessionPoolManager.getSessionIDInfor(sessionID, TemplateSessionIDInfo.class);
if (infor == null) {
return StringUtils.EMPTY;
}
String bookPath = infor.getRelativePath();
// 这个iofile只读一个templateid, 其他以后有需要再读.
IOFile file = new IOFile() {
@Override
public void readStream(InputStream in) throws Exception {
XMLableReader xmlReader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER);
xmlReader.readXMLObject(this);
xmlReader.close();
in.close();
}
@Override
public void readXML(XMLableReader reader) {
readDesign(reader);
}
@Override
protected String openTag() {
return StringUtils.EMPTY;
}
@Override
protected void mainContent(XMLPrintWriter writer) {
}
};
try {
//如果bookPath是null,ResourceIOUtils会因为无法读取文件夹的流输出error日志,输出日志会再次走到这里,引起死循环
if (StringUtils.isNotBlank(bookPath)) {
file.readStream(new ByteArrayInputStream(WorkContext.getWorkResource().readFully(StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, bookPath))));
return file.getTemplateID();
}
} catch (Exception ignore) {
}
return StringUtils.EMPTY;
}
}