diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 76abb74455..06a37c872f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe; import com.fr.base.Parameter; import com.fr.base.TRL; import com.fr.base.extension.FileExtension; +import com.fr.base.info.TemplateSaveInfoContext; import com.fr.base.io.BaseBook; import com.fr.base.iofile.attr.DesignBanCopyAttrMark; import com.fr.base.iofile.attr.TemplateIdAttrMark; @@ -1884,6 +1885,8 @@ public abstract class JTemplate> CallbackSaveWorker worker = new CallbackSaveWorker(new Callable() { @Override public Boolean call() throws Exception { + TemplateSaveInfoContext.getInstance().startRecord(); + TemplateSaveInfoContext.getInstance().collectInfo(template.suffix()); return saveRealFileByWorker(); } }, this); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfo.java b/designer-base/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfo.java index 99950edae7..8cef0d5afa 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfo.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfo.java @@ -33,6 +33,10 @@ public class ErrorInfo { private String log; private String stackTrace; + private boolean starting; + + private boolean remote; + public ErrorInfo(String username, String uuid, String activekey) { this.username = username; this.uuid = uuid; @@ -51,6 +55,22 @@ public class ErrorInfo { this.username = username; } + public boolean isStarting() { + return starting; + } + + public void setStarting(boolean starting) { + this.starting = starting; + } + + public boolean isRemote() { + return remote; + } + + public void setRemote(boolean remote) { + this.remote = remote; + } + public String getUuid() { return uuid; } @@ -126,6 +146,8 @@ public class ErrorInfo { jo.put("logid", logid); jo.put("log", log); jo.put("stacktrace", stackTrace); + jo.put("starting", starting); + jo.put("remote", remote); saveFileToCache(jo); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java b/designer-base/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java index ca3fd13ccc..69342d13e6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java @@ -4,6 +4,8 @@ import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.errorinfo.ErrorInfo; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; +import com.fr.start.common.DesignerStartupContext; +import com.fr.workspace.WorkContext; /** * @@ -35,6 +37,8 @@ public class StartErrorMessageCollector { errorInfo.setLogid(id); errorInfo.setLog(msg); errorInfo.setStackTrace(detail); + errorInfo.setStarting(DesignerStartupContext.getInstance().isOnStartup()); + errorInfo.setRemote(!WorkContext.getCurrent().isLocal()); errorInfo.saveAsJSON(); } diff --git a/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java index ed2597f1d7..b7a50a3af1 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/CallbackSaveWorker.java @@ -1,5 +1,6 @@ package com.fr.design.worker.save; +import com.fr.base.info.TemplateSaveInfoContext; import com.fr.common.util.Collections; import com.fr.design.mainframe.JTemplate; import java.util.LinkedList; @@ -34,6 +35,8 @@ public class CallbackSaveWorker extends SaveWorker { } successRunnableList = null; failRunnableList = null; + TemplateSaveInfoContext.getInstance().stopRecord(); + TemplateSaveInfoContext.getInstance().setSaveCompleted(success); } private void fireRunnable(List list) { diff --git a/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java b/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java index 5ed94d82eb..4114420e10 100644 --- a/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java +++ b/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupModel.java @@ -39,6 +39,11 @@ public class DesignerStartupModel { * mode:模式,0-有设计器起动页;1-无设计器起始页 */ private int mode; + + /** + * jdkVersion:JDK版本 + */ + private String jdkVersion; public DesignerStartupModel() { } @@ -73,7 +78,15 @@ public class DesignerStartupModel { public void setInfo(MachineInfo info) { this.info = info; } - + + public String getJdkVersion() { + return jdkVersion; + } + + public void setJdkVersion(String jdkVersion) { + this.jdkVersion = jdkVersion; + } + public int getMode() { return mode; } @@ -83,7 +96,7 @@ public class DesignerStartupModel { } private void fillInfo() { - + this.setJdkVersion(System.getProperty("java.runtime.version")); MachineInfo info = new MachineInfo(); AbstractOperatingSystem operatingSystem = OperatingSystem.getOperatingSystem(); info.setSystem(operatingSystem.getDisplayString()); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java index 615ee2a96b..bee247d8dd 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java @@ -57,6 +57,10 @@ public class InformationCollector implements XMLReadable, XMLWriter { */ private static final long DELTA = 24 * 3600 * 1000L; private static final long SEND_DELAY = 300 * 1000L; + /** + * 10分钟后再收集信息 + */ + private static final long SEND_DELAY_4_ERROR_INFO = 300 * 1000L * 2; private static final String FILE_NAME = "fr.info"; private static final String XML_START_STOP_LIST = "StartStopList"; private static final String XML_START_STOP = "StartStop"; @@ -64,6 +68,8 @@ public class InformationCollector implements XMLReadable, XMLWriter { private static final String ATTR_START = "start"; private static final String ATTR_STOP = "stop"; + private static final String THREAD_NAME = "ErrorInfoCollector"; + private static InformationCollector collector; /** @@ -143,9 +149,22 @@ public class InformationCollector implements XMLReadable, XMLWriter { */ public void collectStartTime() { this.current.setStartDate(dateToString()); + dealWithErrorInfo(); sendInfo(); } + private void dealWithErrorInfo() { + ScheduledExecutorService service = Executors + .newSingleThreadScheduledExecutor(new NamedThreadFactory(THREAD_NAME)); + service.schedule(() -> { + ErrorInfoUploader.getInstance().dealErrorInfo(false); + }, SEND_DELAY_4_ERROR_INFO, TimeUnit.MILLISECONDS); + service.shutdown(); + } + + /** + * 目前来看这些数据好像没啥用了,但是还是先留着吧,单独把错误信息拿出来用云端运维统一提交 + */ private void sendInfo() { if (!DesignerEnvManager.getEnvManager().isJoinProductImprove() || !FRContext.isChineseEnv()) { return; @@ -157,7 +176,6 @@ public class InformationCollector implements XMLReadable, XMLWriter { SolidCollector.getInstance().sendToCloudCenterAndDeleteFile(); FocusPointMessageUploader.getInstance().sendToCloudCenter(); ChartInfoCollector.getInstance().sendPointInfo(); - ErrorInfoUploader.getInstance().sendErrorInfo(); sendInfoSuccessCallback(); }, SEND_DELAY, TimeUnit.MILLISECONDS); service.shutdown(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java b/designer-realize/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java index 73ecf610d1..0a817b89ba 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/errorinfo/ErrorInfoUploader.java @@ -20,9 +20,10 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -37,6 +38,8 @@ public class ErrorInfoUploader { public static final String SUFFIX = ".json"; public static final String FOLDER_NAME = "errorInfo"; + private static final String CLOUD_KEY = "design.error"; + private static ErrorInfoUploader collector; // 在一台不能上网的电脑里发现了10w个errorinfo... private static final int MAX_ERROR_SIZE = 2000; @@ -148,6 +151,15 @@ public class ErrorInfoUploader { // 判断更新解决方案缓存. checkUpdateSolution(); + dealErrorInfo(true); + } + + /** + * 处理错误信息 + * + * @param needSend2Cloud 是否需要上传到云中心 + */ + public void dealErrorInfo(boolean needSend2Cloud) { //读取文件夹里的json, 加入上传队列中. File folder = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FOLDER_NAME)); if (!folder.exists()) { @@ -164,41 +176,65 @@ public class ErrorInfoUploader { } try { - if (ArrayUtils.isNotEmpty(files)) { - JSONArray jsonArray = new JSONArray(); - List tempFiles = new ArrayList<>(); - int count = 0; - for (File file : files) { - count++; - String filePath = file.getPath(); - String suffix = filePath.substring(filePath.lastIndexOf(".")); - - if (suffix.endsWith(SUFFIX)) { - String content = IOUtils.inputStream2String(new FileInputStream(file)); - if (content.length() > MAX_ERROR_SIZE) { - CommonIOUtils.deleteFile(file); - continue; - } - jsonArray.put(new JSONObject(content)); - tempFiles.add(file); - if (jsonArray.length() == MAX_ITEMS || count == files.length) { - String url = CloudCenter.getInstance().acquireUrlByKind("design.error"); - if (StringUtils.isBlank(url)) { - return; - } - if (sendErrorInfo(url, jsonArray)) { - deleteFiles(tempFiles); - } - jsonArray = new JSONArray(); - } + dealFiles(files, needSend2Cloud); + } catch (Exception ignore) { + + } + } + + private void dealFiles(File[] files, boolean needSend2Cloud) throws IOException { + if (ArrayUtils.isNotEmpty(files)) { + JSONArray jsonArray = new JSONArray(); + List tempFiles = new ArrayList<>(); + int count = 0; + for (File file : files) { + count++; + String filePath = file.getPath(); + String suffix = filePath.substring(filePath.lastIndexOf(".")); + + if (suffix.endsWith(SUFFIX)) { + String content = IOUtils.inputStream2String(Files.newInputStream(file.toPath())); + if (content.length() > MAX_ERROR_SIZE) { + CommonIOUtils.deleteFile(file); + continue; + } + jsonArray.put(new JSONObject(content)); + tempFiles.add(file); + if (jsonArray.length() == MAX_ITEMS || count == files.length) { + processInfos(jsonArray, needSend2Cloud, tempFiles); } } } - } catch (Exception ignore) { + } + } + private void processInfos(JSONArray jsonArray, boolean needSend2Cloud, List tempFiles) { + if (needSend2Cloud) { + String url = CloudCenter.getInstance().acquireUrlByKind(CLOUD_KEY); + if (StringUtils.isBlank(url)) { + return; + } + if (sendErrorInfo(url, jsonArray)) { + deleteFiles(tempFiles); + } + jsonArray = new JSONArray(); + } else { + sendInfos4AnalysisAndClearFiles(jsonArray, tempFiles); } } + + /** + * 提供给云端运维监听的方法(beforeExecute) + * + * @param jsonArray 要提交的信息 + * @param tempFiles 要删除的文件 + */ + private void sendInfos4AnalysisAndClearFiles(JSONArray jsonArray, List tempFiles) { + deleteFiles(tempFiles); + } + + private void deleteFiles(List files) { for (File file : files) { CommonIOUtils.deleteFile(file);