/*
* 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.batch.views;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import scouter.client.Activator;
import scouter.client.Images;
import scouter.client.batch.actions.OpenBatchStackJob;
import scouter.client.util.ImageUtil;
import scouter.lang.pack.BatchPack;
import scouter.lang.value.MapValue;
import scouter.util.SystemUtil;
public class BatchDetailView extends ViewPart {
public static final String ID = BatchDetailView.class.getName();
private StyledText text;
private BatchPack pack;
private int serverId;
Menu contextMenu;
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
public void createPartControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(1, true));
text = new StyledText(composite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
text.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
text.setText("");
if(SystemUtil.IS_MAC_OSX){
text.setFont(new Font(null, "Courier New", 12, SWT.NORMAL));
}else{
text.setFont(new Font(null, "Courier New", 10, SWT.NORMAL));
}
text.setBackgroundImage(Activator.getImage("icons/grid.jpg"));
IToolBarManager man = getViewSite().getActionBars().getToolBarManager();
man.add(openThreadDumpDialog);
man.add(openSFADialog);
//createContextMenu();
}
private void createContextMenu() {
contextMenu = new Menu(text);
MenuItem menu = new MenuItem(contextMenu, SWT.PUSH);
menu.setText("Stack Frequency Analyzer");
menu.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if(pack == null || !pack.isStack){
return;
}
openSFADialog.run();
}
});
menu = new MenuItem(contextMenu, SWT.PUSH);
menu.setText("Batch Thread Dump View");
menu.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
if(pack == null || !pack.isStack){
return;
}
openThreadDumpDialog.run();
}
});
text.setMenu(contextMenu);
}
public void setInput(BatchPack pack, int serverId) {
this.pack = pack;
this.serverId = serverId;
setPartName(pack.objName + " - " + pack.batchJobId);
StringBuilder buffer = new StringBuilder(10240);
String lineSeparator = System.getProperty("line.separator");
buffer.append("-[").append(pack.batchJobId).append("]----------------------------------------------").append(lineSeparator);
buffer.append("PID : ").append(pack.pID).append(lineSeparator);
buffer.append("Run Command: ").append(pack.args).append(lineSeparator);
if(pack.isStack){
buffer.append("Stack Dump: O").append(lineSeparator);
createContextMenu();
}else{
buffer.append("Stack Dump: X").append(lineSeparator);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
buffer.append("Start Time: ").append(sdf.format(new Date(pack.startTime))).append(lineSeparator);
buffer.append("Stop Time: ").append(sdf.format(new Date(pack.startTime + pack.elapsedTime))).append(lineSeparator);
buffer.append("Elapsed Time: ").append(String.format("%,d",pack.elapsedTime)).append("ms").append(lineSeparator);
if(pack.cpuTime > 0){
buffer.append("CPU Time: ").append(String.format("%,d",pack.cpuTime/1000000L)).append("ms").append(lineSeparator);
}
if(pack.gcCount > 0){
buffer.append("GC Count: ").append(pack.gcCount).append(lineSeparator);
buffer.append("GC Time: ").append(pack.gcTime).append("ms").append(lineSeparator);
}
if(pack.sqlTotalCnt > 0){
buffer.append("SQL Time: ").append(String.format("%,d",(pack.sqlTotalTime/1000000L))).append("ms").append(lineSeparator);
buffer.append("SQL Type: ").append(pack.sqlTotalCnt).append(lineSeparator);
buffer.append("SQL Runs: ").append(String.format("%,d",pack.sqlTotalRuns)).append(lineSeparator);
}
if(pack.threadCnt > 0){
buffer.append("Thread Count: ").append(pack.threadCnt).append(lineSeparator);
}
if(pack.sqlTotalCnt > 0){
buffer.append(lineSeparator).append("<SQLs>").append(lineSeparator);
int index = 0;
buffer.append("Index Runs TotalTime MinTime MaxTime Rows (Measured) StartTime EndTime").append(lineSeparator);
buffer.append("--------------------------------------------------------------------------------------------------------------------------------------");
List<MapValue> stats = pack.sqlStats;
for(MapValue mapValue : stats){
index++;
buffer.append(lineSeparator);
buffer.append(String.format("%5s", index)).append(' ');
buffer.append(String.format("%,13d", mapValue.getLong("runs"))).append(' ');
buffer.append(String.format("%,13d", (mapValue.getLong("totalTime")/1000000L))).append(' ');
buffer.append(String.format("%,13d", (mapValue.getLong("minTime")/1000000L))).append(' ');
buffer.append(String.format("%,13d", (mapValue.getLong("maxTime")/1000000L))).append(' ');
buffer.append(String.format("%,13d", mapValue.getLong("processedRows"))).append(' ').append(String.format("%10s", mapValue.getBoolean("rowed"))).append(' ');
buffer.append(sdf.format(new Date(mapValue.getLong("startTime")))).append(' ');
buffer.append(sdf.format(new Date(mapValue.getLong("endTime"))));
}
buffer.append(lineSeparator).append("--------------------------------------------------------------------------------------------------------------------------------------").append(lineSeparator);
buffer.append(lineSeparator).append("<SQL Texts>").append(lineSeparator);
index = 0;
Map<Integer, String> sqls = pack.uniqueSqls;
for(MapValue mapValue : stats){
index++;
buffer.append("-----------------").append(lineSeparator);
buffer.append("#SQLINX-").append(index).append(lineSeparator);
buffer.append(sqls.get((int)mapValue.getLong("hashValue"))).append(lineSeparator);
}
}
text.setText(buffer.toString());
}
public void setFocus() {
}
Action openSFADialog = new Action("Stack Frequency Analyzer", ImageUtil.getImageDescriptor(Images.page_white_stack)) {
public void run() {
new OpenBatchStackJob(pack, serverId, true).schedule();
}
};
Action openThreadDumpDialog = new Action("Batch Thread Dump View", ImageUtil.getImageDescriptor(Images.thread)) {
public void run() {
new OpenBatchStackJob(pack, serverId, false).schedule();
}
};
}