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
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; |
|
} |
|
}
|
|
|