/* * Copyright 2015 the original author or authors. * @https://github.com/scouter-project/scouter * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package scouter.client.xlog; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Button; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import scouter.client.Images; import scouter.client.actions.OpenWorkspaceExplorerAction; import scouter.client.model.TextProxy; import scouter.client.model.XLogData; import scouter.client.model.XLogProxy; import scouter.client.server.ServerManager; import scouter.client.util.ConsoleProxy; import scouter.client.util.ExUtil; import scouter.client.util.RCPUtil; import scouter.client.util.StepWrapper; import scouter.lang.pack.XLogPack; import scouter.lang.step.Step; import scouter.lang.step.StepSingle; import scouter.lang.step.StepSummary; import scouter.io.DataInputX; import scouter.io.DataOutputX; import scouter.util.DateUtil; import scouter.util.SortUtil; public class SaveProfileJob extends Job{ public static String xLogDirName = "xlog"; String workingDir = ""; public static String xLogFileName = "xlog.xlog"; public static String profileFileName = "xlog.prof"; public static String profileSummaryFileName = "xlog_summary.prof"; long date; String yyyymmdd; XLogData xLogData; String txid; int maxBlock; private int serverId; boolean isSummary; IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); public SaveProfileJob(String name, long date, XLogData xLogData, String txid, int serverId, boolean isSummary) { super(name); this.date = date; this.yyyymmdd = DateUtil.yyyymmdd(date); this.xLogData = xLogData; this.txid = txid; this.serverId = serverId; this.isSummary = isSummary; } @Override protected IStatus run(IProgressMonitor monitor) { checkDir(); monitor.beginTask("Saveing full Profile to... "+workingDir, IProgressMonitor.UNKNOWN); createDirAndFile(); saveFullProfile(downloadFullProfile()); saveXLogData(); monitor.done(); ExUtil.exec(PlatformUI.getWorkbench().getDisplay(), new Runnable(){ public void run() { Action act = new OpenWorkspaceExplorerAction(window, "Workspace Explorer", Images.explorer, true, serverId); act.run(); } }); return Status.OK_STATUS; } private void checkDir() { String service = TextProxy.service.getText(xLogData.p.service).replaceAll("/", "_"); if(service.length() > 80){ service = service.substring(0, 80); } String serverName = ServerManager.getInstance().getServer(serverId).getName(); String dir = RCPUtil.getWorkingDirectory()+"/"+serverName+"/"+yyyymmdd+xLogData.objName+"/"+xLogDirName; File rootDir = new File(dir); File[] fs = rootDir.listFiles(); if(fs != null){ workingDir = dir+"/"+"["+String.format("%03d-", (fs.length+1))+DateUtil.format(date, "HHmmss")+"]"+txid+"_"+service+"/"; for(File f : fs){ String dirPath = f.getAbsolutePath(); if(f.isDirectory() && dirPath != null && dirPath.indexOf(txid+"_"+service) != -1){ workingDir = dirPath+"/"; break; } } }else{ workingDir = dir+"/"+"[001-"+DateUtil.format(date, "HHmmss")+"]"+txid+"_"+service+"/"; } } private void saveXLogData() { try { FileOutputStream fileOuputStream = new FileOutputStream(workingDir + xLogFileName); DataOutputX outX = new DataOutputX(); fileOuputStream.write(outX.writePack(xLogData.p).toByteArray()); fileOuputStream.close(); } catch (Exception e) { ConsoleProxy.errorSafe(e.toString()); } finally{ } } private void createDirAndFile() { File xlogDir = new File(workingDir); if (xlogDir.exists() == false) { xlogDir.mkdirs(); } File xlogFile = new File(xlogDir, xLogFileName); if (xlogFile.exists()) { xlogFile.delete(); } File profFile = new File(xlogDir, profileFileName); if (profFile.exists()) { profFile.delete(); } File profsumFile = new File(xlogDir, profileSummaryFileName); if (profsumFile.exists()) { profsumFile.delete(); } } private byte[] downloadFullProfile(){ return XLogProxy.getFullProfileByteArray(DateUtil.yyyymmdd(xLogData.p.endTime), xLogData.p.txid, maxBlock, serverId); } private void saveFullProfile(byte[] p) { try { FileOutputStream fileOuputStream; if(!isSummary){ fileOuputStream = new FileOutputStream(workingDir + profileFileName); }else{ fileOuputStream = new FileOutputStream(workingDir + profileSummaryFileName); } fileOuputStream.write(p); fileOuputStream.close(); } catch (Exception e) { e.printStackTrace(); } } public static XLogPack getTranxData(File xlogDir, StyledText header, int serverId) { String xlogPath = xlogDir.getAbsolutePath()+"/"+xLogFileName; File xlogFile = new File(xlogPath); if(!xlogFile.canRead()){ return null; } byte[] xlogb = new byte[(int) xlogFile.length()]; try { FileInputStream xlogInputStream = new FileInputStream(xlogFile); xlogInputStream.read(xlogb); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } DataInputX inX = new DataInputX(xlogb); XLogPack p = null; try { p = (XLogPack) inX.readPack(); } catch (IOException e) { e.printStackTrace(); } String date = DateUtil.yyyymmdd(p.endTime); if(p != null){ ProfileTextFull.buildXLogData(date, header, p, serverId); } return p; } public static StepWrapper[] getProfileData(XLogPack pack, File xLogDir, boolean isSummary) { String profilePath; if(!isSummary){ profilePath = xLogDir.getAbsolutePath()+"/"+profileFileName; }else{ profilePath = xLogDir.getAbsolutePath()+"/"+profileSummaryFileName; } File profileFile = new File(profilePath); if(!profileFile.canRead()){ return null; } byte[] profb = new byte[(int) profileFile.length()]; try { FileInputStream profileInputStream = new FileInputStream(profileFile); profileInputStream.read(profb); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } Step[] profile = null; try { profile = Step.toObjects(profb); } catch (IOException e) { e.printStackTrace(); } profile = SortUtil.sort(profile); HashMap<Integer, Integer> indent = new HashMap<Integer, Integer>(); long stime = pack.endTime - pack.elapsed; StepWrapper[] profWr = new StepWrapper[profile.length]; int expectedIdx = 0; int sSummaryIdx = 1; for(int inx = 0 ; inx < profile.length ; inx++){ if(profile[inx] instanceof StepSingle){ StepSingle sSingle = (StepSingle) profile[inx]; int space = 0; if (indent.containsKey(sSingle.parent)) { space = indent.get(sSingle.parent) + 2; } indent.put(sSingle.index, space); profWr[inx] = new StepWrapper(sSingle.start_time + stime, sSingle.start_cpu, space, -1, sSingle); expectedIdx = sSingle.index + 1; }else if(profile[inx] instanceof StepSummary){ StepSummary sSummary = (StepSummary) profile[inx]; profWr[inx] = new StepWrapper(-1, -1, -1, sSummaryIdx, sSummary); sSummaryIdx++; } } return profWr; } public static void setProfileData(XLogPack pack, StepWrapper[] profiles, StyledText text, int pageNum, int rowPerPage, Button prevBtn, Button nextBtn, Button startBtn, Button endBtn, int length, int serverId, int searchLineIndex, boolean isSummary){ String date = DateUtil.yyyymmdd(pack.endTime); int total = (profiles.length / rowPerPage) + 1; if(profiles.length % rowPerPage == 0){ total = total - 1; } if(pageNum > total){ pageNum = total - 1; } ProfileTextFull.buildProfile(date, text, pack, profiles, pageNum, rowPerPage, prevBtn, nextBtn, startBtn, endBtn, length, serverId, searchLineIndex, isSummary); } }