diff --git a/designer/src/com/fr/design/mainframe/InformationCollector.java b/designer/src/com/fr/design/mainframe/InformationCollector.java index f50cc5dadf..4bac9a15b0 100644 --- a/designer/src/com/fr/design/mainframe/InformationCollector.java +++ b/designer/src/com/fr/design/mainframe/InformationCollector.java @@ -10,6 +10,7 @@ import com.fr.data.core.db.dml.Delete; import com.fr.data.core.db.dml.Select; import com.fr.data.core.db.dml.Table; import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.errorinfo.ErrorInfoUploader; import com.fr.design.mainframe.templateinfo.TemplateInfoCollector; import com.fr.general.*; import com.fr.general.http.HttpClient; @@ -317,6 +318,7 @@ public class InformationCollector implements XMLReadable, XMLWriter { sendFunctionsInfo(); sendUserInfo(); TemplateInfoCollector.getInstance().sendTemplateInfo(); + ErrorInfoUploader.getInstance().sendErrorInfo(); } }); sendThread.start(); diff --git a/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfo.java b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfo.java new file mode 100644 index 0000000000..c101706496 --- /dev/null +++ b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfo.java @@ -0,0 +1,130 @@ +package com.fr.design.mainframe.errorinfo; + +import com.fr.base.FRContext; +import com.fr.general.IOUtils; +import com.fr.json.JSONException; +import com.fr.json.JSONObject; +import com.fr.stable.EncodeConstants; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.core.UUID; + +import java.io.*; +import java.text.DateFormat; +import java.util.Date; + +/** + * Created by Administrator on 2017/7/24 0024. + */ +public class ErrorInfo { + + private String username; + private String uuid; + private String activekey; + private String uploadtime; + private String templateid; + private String logid; + private String log; + + public ErrorInfo(String username, String uuid, String activekey) { + this.username = username; + this.uuid = uuid; + this.activekey = activekey; + this.uploadtime = dateToString(); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getActivekey() { + return activekey; + } + + public void setActivekey(String activekey) { + this.activekey = activekey; + } + + public String getUploadtime() { + return uploadtime; + } + + public void setUploadtime(String uploadtime) { + this.uploadtime = uploadtime; + } + + public String getTemplateid() { + return templateid; + } + + public void setTemplateid(String templateid) { + this.templateid = templateid; + } + + public String getLogid() { + return logid; + } + + public void setLogid(String logid) { + this.logid = logid; + } + + public String getLog() { + return log; + } + + public void setLog(String log) { + this.log = log; + } + + private String dateToString(){ + DateFormat df = FRContext.getDefaultValues().getDateTimeFormat(); + return df.format(new Date()); + } + + /** + * 将出错对象存为json字符串, 并放到设计器缓存目录. + * 等下一次上传到云中心. + */ + public void saveAsJSON(){ + JSONObject jo = JSONObject.create(); + try { + jo.put("username", username); + jo.put("uuid", uuid); + jo.put("activekey", activekey); + jo.put("templateid", templateid); + jo.put("uploadtime", uploadtime); + jo.put("logid", logid); + jo.put("log", log); + } catch (JSONException ignore) { + } + + saveFileToCache(jo); + } + + private void saveFileToCache(JSONObject jo) { + String content = jo.toString(); + String fileName = UUID.randomUUID() + ErrorInfoUploader.SUFFIX; + File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), ErrorInfoUploader.FOLDER_NAME, fileName)); + try { + StableUtils.makesureFileExist(file); + FileOutputStream out = new FileOutputStream(file); + InputStream in = new ByteArrayInputStream(content.getBytes(EncodeConstants.ENCODING_UTF_8)); + IOUtils.copyBinaryTo(in, out); + out.close(); + } catch (IOException ignore) { + } + } +} diff --git a/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoLogAppender.java b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoLogAppender.java new file mode 100644 index 0000000000..1d4f65de53 --- /dev/null +++ b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoLogAppender.java @@ -0,0 +1,139 @@ +package com.fr.design.mainframe.errorinfo; + +import com.fr.base.FRContext; +import com.fr.base.io.IOFile; +import com.fr.base.io.XMLReadHelper; +import com.fr.design.DesignerEnvManager; +import com.fr.general.FRLogLevel; +import com.fr.general.FRLogManager; +import com.fr.general.LogDuration; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLableReader; +import com.fr.web.core.SessionDealWith; +import com.fr.web.core.SessionIDInfor; +import org.apache.log4j.AppenderSkeleton; +import org.apache.log4j.Level; +import org.apache.log4j.spi.LoggingEvent; + +import java.io.InputStream; + +/** + * 收集设计器报错信息的appender. + *
+ * Created by Administrator on 2017/7/24 0024.
+ */
+public class ErrorInfoLogAppender extends AppenderSkeleton {
+
+ private static final int ERROR_LEN = 8;
+
+ // 缓存下不变的, 没必要频繁取.
+ private String username;
+ private String uuid;
+ private String activekey;
+
+ public ErrorInfoLogAppender() {
+ this.layout = new org.apache.log4j.PatternLayout("%d{HH:mm:ss} %t %p [%c] %m%n");
+
+ DesignerEnvManager envManager = DesignerEnvManager.getEnvManager();
+ this.username = envManager.getBBSName();
+ this.uuid = envManager.getUUID();
+ this.activekey = envManager.getActivationKey();
+ }
+
+ protected void append(LoggingEvent event) {
+ this.subAppend(event);
+ }
+
+ public boolean requiresLayout() {
+ return true;
+ }
+
+ public synchronized void close() {
+ if (this.closed) {
+ return;
+ }
+ this.closed = true;
+
+ }
+
+ public void subAppend(LoggingEvent event) {
+ Level level = event.getLevel();
+ // 只分析上传记录error以上的.
+ if (level.isGreaterOrEqual(FRLogLevel.ERROR)) {
+ String msg = this.layout.format(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.saveAsJSON();
+ }
+ }
+
+ private String readLogID(String log) {
+ int dotIndex = log.lastIndexOf(":");
+ if (dotIndex != -1) {
+ int end = Math.min(dotIndex + ERROR_LEN, log.length());
+ String logid = log.substring(dotIndex + 1, end).trim();
+ try {
+ Long.parseLong(logid);
+ return logid;
+ } catch (Exception ignore) {
+
+ }
+ }
+
+ return StringUtils.EMPTY;
+ }
+
+ private String readTemplateID() {
+ LogDuration logDuration = FRLogManager.getSession();
+ if (logDuration == null) {
+ return StringUtils.EMPTY;
+ }
+
+ String sessionID = logDuration.getSessionID();
+ SessionIDInfor infor = SessionDealWith.getSessionIDInfor(sessionID);
+ if (infor == null) {
+ return StringUtils.EMPTY;
+ }
+
+ String bookPath = infor.getBookPath();
+ // 这个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) {
+ super.readXML(reader);
+ readDesign(reader);
+ }
+
+ @Override
+ protected String openTag() {
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ protected void mainContent(XMLPrintWriter writer) {
+ }
+ };
+ try {
+ file.readStream(FRContext.getCurrentEnv().readBean(bookPath, ProjectConstants.REPORTLETS_NAME));
+ return file.getTemplateID();
+ } catch (Exception ignore) {
+ }
+
+ return StringUtils.EMPTY;
+ }
+}
\ No newline at end of file
diff --git a/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java
new file mode 100644
index 0000000000..0204d33a96
--- /dev/null
+++ b/designer/src/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java
@@ -0,0 +1,98 @@
+package com.fr.design.mainframe.errorinfo;
+
+import com.fr.general.*;
+import com.fr.general.http.HttpClient;
+import com.fr.json.JSONObject;
+import com.fr.stable.CodeUtils;
+import com.fr.stable.EnvChangedListener;
+import com.fr.stable.ProductConstants;
+import com.fr.stable.StableUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.HashMap;
+
+/**
+ * Created by Administrator on 2017/7/24 0024.
+ */
+public class ErrorInfoUploader {
+
+ public static final String SUFFIX = ".json";
+ public static final String FOLDER_NAME = "errorInfo";
+
+ private static ErrorInfoUploader collector;
+
+ static {
+ GeneralContext.addEnvChangedListener(new EnvChangedListener() {
+ @Override
+ public void envChanged() {
+ FRLogger.getLogger().addLogAppender(new ErrorInfoLogAppender());
+ }
+ });
+ }
+
+ private ErrorInfoUploader() {
+ FRLogger.getLogger().addLogAppender(new ErrorInfoLogAppender());
+ }
+
+ public static ErrorInfoUploader getInstance() {
+ if (collector == null) {
+ collector = new ErrorInfoUploader();
+ }
+
+ return collector;
+ }
+
+ public void sendErrorInfo(){
+ //读取文件夹里的json, 加入上传队列中.
+ File folder = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FOLDER_NAME));
+ if (!folder.exists()) {
+ return;
+ }
+
+ File[] files = folder.listFiles();
+ try {
+ for (File file : files) {
+ String filePath = file.getPath();
+ String suffix = filePath.substring(filePath.lastIndexOf("."));
+
+ if (suffix.endsWith(SUFFIX)) {
+ Thread.sleep(1000L);
+ String content = IOUtils.inputStream2String(new FileInputStream(file));
+ String url = SiteCenter.getInstance().acquireUrlByKind("design.error");
+ if (sendErroInfo(url, content)) {
+ file.delete();
+ }
+ }
+ }
+ } catch (Exception ignore) {
+
+ }
+ }
+
+ private boolean sendErroInfo(String url, String content) {
+ HashMap