/* * 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.maria.views; import org.csstudio.swt.xygraph.dataprovider.CircularBufferDataProvider; import org.csstudio.swt.xygraph.dataprovider.Sample; import org.csstudio.swt.xygraph.figures.Trace; import org.csstudio.swt.xygraph.figures.Trace.PointStyle; import org.csstudio.swt.xygraph.figures.Trace.TraceType; import org.csstudio.swt.xygraph.figures.XYGraph; import org.eclipse.draw2d.FigureCanvas; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import scouter.client.Images; import scouter.client.listeners.RangeMouseListener; import scouter.client.maria.actions.OpenDigestTableAction; import scouter.client.model.AgentModelThread; import scouter.client.model.RefreshThread; import scouter.client.model.RefreshThread.Refreshable; import scouter.client.net.TcpProxy; import scouter.client.preferences.PManager; import scouter.client.preferences.PreferenceConstants; import scouter.client.server.Server; import scouter.client.server.ServerManager; import scouter.client.util.ChartUtil; import scouter.client.util.ColorUtil; import scouter.client.util.ConsoleProxy; import scouter.client.util.ExUtil; import scouter.client.util.ImageUtil; import scouter.client.util.ScouterUtil; import scouter.client.util.TimeUtil; import scouter.lang.counters.CounterConstants; import scouter.lang.pack.MapPack; import scouter.lang.value.DecimalValue; import scouter.lang.value.ListValue; import scouter.lang.value.MapValue; import scouter.lang.value.Value; import scouter.net.RequestCmd; import scouter.util.CastUtil; import scouter.util.DateUtil; import scouter.util.LinkedList; import scouter.util.LinkedList.ENTRY; public class DbRealtimeTotalActivityView extends ViewPart implements Refreshable { public static final String ID = DbRealtimeTotalActivityView.class.getName(); int serverId; RefreshThread thread; static long TIME_RANGE = DateUtil.MILLIS_PER_FIVE_MINUTE; static int REFRESH_INTERVAL = (int) (DateUtil.MILLIS_PER_SECOND * 2); static int BUFFER_SIZE = (int)(TIME_RANGE / REFRESH_INTERVAL) + 1; FigureCanvas canvas; XYGraph xyGraph; Trace callTrace; Trace selectTrace; Trace insertTrace; Trace updateTrace; Trace deleteTrace; boolean isStackView = true; LinkedList<ValueLog> valueLogs = new LinkedList<ValueLog>(); public void init(IViewSite site) throws PartInitException { super.init(site); String secId = site.getSecondaryId(); serverId = CastUtil.cint(secId); } public void createPartControl(Composite parent) { Server server = ServerManager.getInstance().getServer(serverId); this.setPartName("DB Activity[" + server.getName() + "]"); GridLayout layout = new GridLayout(1, true); layout.marginHeight = 5; layout.marginWidth = 5; parent.setLayout(layout); parent.setBackground(ColorUtil.getInstance().getColor(SWT.COLOR_WHITE)); parent.setBackgroundMode(SWT.INHERIT_FORCE); canvas = new FigureCanvas(parent); canvas.setLayoutData(new GridData(GridData.FILL_BOTH)); canvas.setScrollBarVisibility(FigureCanvas.NEVER); canvas.addControlListener(new ControlListener() { public void controlMoved(ControlEvent arg0) { } public void controlResized(ControlEvent arg0) { Rectangle r = canvas.getClientArea(); xyGraph.setSize(r.width, r.height); } }); xyGraph = new XYGraph(); xyGraph.setShowLegend(true); xyGraph.setShowTitle(false); canvas.setContents(xyGraph); xyGraph.primaryXAxis.setDateEnabled(true); xyGraph.primaryXAxis.setShowMajorGrid(true); xyGraph.primaryYAxis.setAutoScale(true); xyGraph.primaryYAxis.setShowMajorGrid(true); xyGraph.primaryXAxis.setFormatPattern("HH:mm:ss"); xyGraph.primaryYAxis.setFormatPattern("#,##0"); xyGraph.primaryXAxis.setTitle(""); xyGraph.primaryYAxis.setTitle(""); xyGraph.primaryYAxis.addMouseListener(new RangeMouseListener(getViewSite().getShell(), xyGraph.primaryYAxis)); CircularBufferDataProvider callProvider = new CircularBufferDataProvider(true); callProvider.setBufferSize(BUFFER_SIZE); callProvider.setCurrentXDataArray(new double[] {}); callProvider.setCurrentYDataArray(new double[] {}); callTrace = new Trace("Call (SUM)", xyGraph.primaryXAxis, xyGraph.primaryYAxis, callProvider); callTrace.setPointStyle(PointStyle.NONE); callTrace.setTraceType(TraceType.AREA); callTrace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH)); callTrace.setAreaAlpha(255); callTrace.setTraceColor(ColorUtil.getInstance().getColor(SWT.COLOR_DARK_BLUE)); xyGraph.addTrace(callTrace); CircularBufferDataProvider selectProvider = new CircularBufferDataProvider(true); selectProvider.setBufferSize(BUFFER_SIZE); selectProvider.setCurrentXDataArray(new double[] {}); selectProvider.setCurrentYDataArray(new double[] {}); selectTrace = new Trace("Select (SUM)", xyGraph.primaryXAxis, xyGraph.primaryYAxis, selectProvider); selectTrace.setPointStyle(PointStyle.NONE); selectTrace.setTraceType(TraceType.AREA); selectTrace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH)); selectTrace.setAreaAlpha(255); selectTrace.setTraceColor(ColorUtil.getInstance().getColor(SWT.COLOR_DARK_CYAN)); xyGraph.addTrace(selectTrace); CircularBufferDataProvider insertProvider = new CircularBufferDataProvider(true); insertProvider.setBufferSize(BUFFER_SIZE); insertProvider.setCurrentXDataArray(new double[] {}); insertProvider.setCurrentYDataArray(new double[] {}); insertTrace = new Trace("Insert (SUM)", xyGraph.primaryXAxis, xyGraph.primaryYAxis, insertProvider); insertTrace.setPointStyle(PointStyle.NONE); insertTrace.setTraceType(TraceType.AREA); insertTrace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH)); insertTrace.setAreaAlpha(255); insertTrace.setTraceColor(ColorUtil.getInstance().getColor(SWT.COLOR_DARK_GRAY)); xyGraph.addTrace(insertTrace); CircularBufferDataProvider updateProvider = new CircularBufferDataProvider(true); updateProvider.setBufferSize(BUFFER_SIZE); updateProvider.setCurrentXDataArray(new double[] {}); updateProvider.setCurrentYDataArray(new double[] {}); updateTrace = new Trace("Update (SUM)", xyGraph.primaryXAxis, xyGraph.primaryYAxis, updateProvider); updateTrace.setPointStyle(PointStyle.NONE); updateTrace.setTraceType(TraceType.AREA); updateTrace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH)); updateTrace.setAreaAlpha(255); updateTrace.setTraceColor(ColorUtil.getInstance().getColor(SWT.COLOR_DARK_GREEN)); xyGraph.addTrace(updateTrace); CircularBufferDataProvider deleteProvider = new CircularBufferDataProvider(true); deleteProvider.setBufferSize(BUFFER_SIZE); deleteProvider.setCurrentXDataArray(new double[] {}); deleteProvider.setCurrentYDataArray(new double[] {}); deleteTrace = new Trace("Delete (SUM)", xyGraph.primaryXAxis, xyGraph.primaryYAxis, deleteProvider); deleteTrace.setPointStyle(PointStyle.NONE); deleteTrace.setTraceType(TraceType.AREA); deleteTrace.setLineWidth(PManager.getInstance().getInt(PreferenceConstants.P_CHART_LINE_WIDTH)); deleteTrace.setAreaAlpha(255); deleteTrace.setTraceColor(ColorUtil.getInstance().getColor(SWT.COLOR_DARK_MAGENTA)); xyGraph.addTrace(deleteTrace); ScouterUtil.addHorizontalRangeListener(xyGraph.getPlotArea(), new OpenDigestTableAction(serverId), false); IToolBarManager man = getViewSite().getActionBars().getToolBarManager(); Action stackViewAct = new Action("Area Mode", IAction.AS_CHECK_BOX) { public void run() { isStackView = isChecked(); changeMode(); } }; stackViewAct.setImageDescriptor(ImageUtil.getImageDescriptor(Images.sum)); stackViewAct.setChecked(true); man.add(stackViewAct); Action openDailyView = new Action("Open Daily View", ImageUtil.getImageDescriptor(Images.calendar)) { public void run() { try { PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(DbTodayTotalActivityView.ID, ""+serverId, IWorkbenchPage.VIEW_ACTIVATE); } catch (PartInitException e) { ConsoleProxy.errorSafe(e.toString()); } } }; man.add(openDailyView); thread = new RefreshThread(this, REFRESH_INTERVAL); thread.start(); } public void setFocus() { } @Override public void dispose() { super.dispose(); if (this.thread != null) { this.thread.shutdown(); } } public void refresh() { TcpProxy tcp = TcpProxy.getTcpProxy(serverId); Value v = null; try { MapPack param = new MapPack(); ListValue objHashLv = AgentModelThread.getInstance().getLiveObjHashLV(serverId, CounterConstants.MARIA_PLUGIN); if (objHashLv.size() > 0) { param.put("objHash", objHashLv); v = tcp.getSingleValue(RequestCmd.DB_REALTIME_ACTIVITY, param); } } catch (Exception e) { ConsoleProxy.errorSafe(e.toString()); } finally { TcpProxy.putTcpProxy(tcp); } if (v == null) { ExUtil.exec(canvas, new Runnable() { public void run() { setTitleImage(Images.inactive); long now = TimeUtil.getCurrentTime(serverId); long stime = now - TIME_RANGE; xyGraph.primaryXAxis.setRange(stime, now + 1); } }); } else { MapValue mv = (MapValue) v; final DecimalValue callValue = new DecimalValue(mv.getLong("call")); final DecimalValue selectValue = new DecimalValue(mv.getLong("select")); final DecimalValue insertValue = new DecimalValue(mv.getLong("insert")); final DecimalValue updateValue = new DecimalValue(mv.getLong("update")); final DecimalValue deleteValue = new DecimalValue(mv.getLong("delete")); ExUtil.exec(canvas, new Runnable() { public void run() { setTitleImage(Images.active); long now = TimeUtil.getCurrentTime(serverId) / REFRESH_INTERVAL * REFRESH_INTERVAL; long stime = now - TIME_RANGE; xyGraph.primaryXAxis.setRange(stime, now + 1); ValueLog valueLog = new ValueLog(); valueLog.time = now; valueLog.delete = deleteValue.value; valueLog.update = updateValue.value; valueLog.insert = insertValue.value; valueLog.select = selectValue.value; valueLog.call = callValue.value; valueLogs.add(valueLog); if (valueLogs.size() > BUFFER_SIZE) { valueLogs.removeFirst(); } if (isStackView) { updateValue.value += deleteValue.value; insertValue.value += updateValue.value; selectValue.value += insertValue.value; callValue.value += selectValue.value; } ((CircularBufferDataProvider)callTrace.getDataProvider()).addSample(new Sample(now, callValue.value)); ((CircularBufferDataProvider)selectTrace.getDataProvider()).addSample(new Sample(now, selectValue.value)); ((CircularBufferDataProvider)insertTrace.getDataProvider()).addSample(new Sample(now, insertValue.value)); ((CircularBufferDataProvider)updateTrace.getDataProvider()).addSample(new Sample(now, updateValue.value)); ((CircularBufferDataProvider)deleteTrace.getDataProvider()).addSample(new Sample(now, deleteValue.value)); xyGraph.primaryYAxis.setRange(0, getMaxYValue()); } private double getMaxYValue() { if (isStackView) { return ChartUtil.getMax(((CircularBufferDataProvider)callTrace.getDataProvider()).iterator()); } double value = ChartUtil.getMax(((CircularBufferDataProvider)callTrace.getDataProvider()).iterator()); value = Math.max(value, ChartUtil.getMax(((CircularBufferDataProvider)selectTrace.getDataProvider()).iterator())); value = Math.max(value, ChartUtil.getMax(((CircularBufferDataProvider)insertTrace.getDataProvider()).iterator())); value = Math.max(value, ChartUtil.getMax(((CircularBufferDataProvider)updateTrace.getDataProvider()).iterator())); value = Math.max(value, ChartUtil.getMax(((CircularBufferDataProvider)deleteTrace.getDataProvider()).iterator())); return value; } }); } } protected void changeMode() { CircularBufferDataProvider delProvider = (CircularBufferDataProvider)deleteTrace.getDataProvider(); CircularBufferDataProvider upProvider = (CircularBufferDataProvider)updateTrace.getDataProvider(); CircularBufferDataProvider inProvider = (CircularBufferDataProvider)insertTrace.getDataProvider(); CircularBufferDataProvider selProvider = (CircularBufferDataProvider)selectTrace.getDataProvider(); CircularBufferDataProvider callProvider = (CircularBufferDataProvider)callTrace.getDataProvider(); delProvider.clearTrace(); upProvider.clearTrace(); inProvider.clearTrace(); selProvider.clearTrace(); callProvider.clearTrace(); int size = valueLogs.size(); if (size > 0) { ENTRY<ValueLog> entry = valueLogs.getFirst(); if (isStackView) { do { ValueLog log = entry.item; double x = log.time; double delValue = log.delete; double upValue = delValue + log.update; double inValue = upValue + log.insert; double selValue = inValue + log.select; double callValue = selValue + log.call; callProvider.addSample(new Sample(x, callValue)); selProvider.addSample(new Sample(x, selValue)); inProvider.addSample(new Sample(x, inValue)); upProvider.addSample(new Sample(x, upValue)); delProvider.addSample(new Sample(x, delValue)); } while ((entry = entry.next) != null); } else { do { ValueLog log = entry.item; double x = log.time; double delValue = log.delete; double upValue = log.update; double inValue = log.insert; double selValue = log.select; double callValue = log.call; callProvider.addSample(new Sample(x, callValue)); selProvider.addSample(new Sample(x, selValue)); inProvider.addSample(new Sample(x, inValue)); upProvider.addSample(new Sample(x, upValue)); delProvider.addSample(new Sample(x, delValue)); } while ((entry = entry.next) != null); } } if (isStackView) { deleteTrace.setTraceType(TraceType.AREA); updateTrace.setTraceType(TraceType.AREA); insertTrace.setTraceType(TraceType.AREA); selectTrace.setTraceType(TraceType.AREA); callTrace.setTraceType(TraceType.AREA); } else { deleteTrace.setTraceType(TraceType.SOLID_LINE); updateTrace.setTraceType(TraceType.SOLID_LINE); insertTrace.setTraceType(TraceType.SOLID_LINE); selectTrace.setTraceType(TraceType.SOLID_LINE); callTrace.setTraceType(TraceType.SOLID_LINE); } } private static class ValueLog { long time; double delete; double update; double insert; double select; double call; } }