scouter.client.maria.views.DigestTableView.java Source code

Java tutorial

Introduction

Here is the source code for scouter.client.maria.views.DigestTableView.java

Source

/*
 *  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 java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

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.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

import scouter.client.Images;
import scouter.client.model.AgentDailyListProxy;
import scouter.client.model.DigestModel;
import scouter.client.model.RefreshThread;
import scouter.client.model.RefreshThread.Refreshable;
import scouter.client.model.TextProxy;
import scouter.client.net.INetReader;
import scouter.client.net.TcpProxy;
import scouter.client.popup.DigestDetailDialog;
import scouter.client.sorter.TreeLabelSorter;
import scouter.client.util.ConsoleProxy;
import scouter.client.util.ExUtil;
import scouter.client.util.ImageUtil;
import scouter.client.util.TimeUtil;
import scouter.io.DataInputX;
import scouter.lang.DigestKey;
import scouter.lang.counters.CounterConstants;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.Pack;
import scouter.lang.pack.PackEnum;
import scouter.lang.pack.StatusPack;
import scouter.lang.value.ListValue;
import scouter.lang.value.MapValue;
import scouter.net.RequestCmd;
import scouter.util.CastUtil;
import scouter.util.DateUtil;
import scouter.util.FormatUtil;

public class DigestTableView extends ViewPart implements Refreshable {

    public final static String ID = DigestTableView.class.getName();

    double PICO = Math.pow(10, -12);
    int serverId;

    Composite parent;
    TreeViewer viewer;
    TreeColumnLayout columnLayout;

    AgentDailyListProxy agentProxy = new AgentDailyListProxy();

    RefreshThread thread;
    boolean isAutoRefresh = false;

    String date;
    long stime, etime;
    HashMap<Integer, DigestModel> root = new HashMap<Integer, DigestModel>();

    public void init(IViewSite site) throws PartInitException {
        super.init(site);
        String secId = site.getSecondaryId();
        this.serverId = CastUtil.cint(secId);
    }

    public void createPartControl(Composite parent) {
        this.parent = parent;
        GridLayout gridlayout = new GridLayout(1, false);
        gridlayout.marginHeight = 0;
        gridlayout.horizontalSpacing = 0;
        gridlayout.marginWidth = 0;
        parent.setLayout(gridlayout);
        columnLayout = new TreeColumnLayout();
        Composite mainComp = new Composite(parent, SWT.NONE);
        mainComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        mainComp.setLayout(columnLayout);
        viewer = new TreeViewer(mainComp, SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
        createColumns();
        final Tree tree = viewer.getTree();
        tree.setHeaderVisible(true);
        tree.setLinesVisible(true);
        viewer.setLabelProvider(new TreeLabelProvider());
        viewer.setContentProvider(new TreeContentProvider());
        viewer.setComparator(new TreeLabelSorter(viewer));
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                StructuredSelection sel = (StructuredSelection) event.getSelection();
                Object o = sel.getFirstElement();
                if (o instanceof DigestModel) {
                    DigestModel model = (DigestModel) o;
                    new DigestDetailDialog().show(model, stime, etime, serverId);
                }
            }
        });
        viewer.setInput(root);

        IToolBarManager man = getViewSite().getActionBars().getToolBarManager();
        Action actAutoRefresh = new Action("Auto Refresh in 10 sec.", IAction.AS_CHECK_BOX) {
            public void run() {
                isAutoRefresh = isChecked();
                if (isAutoRefresh) {
                    thread.interrupt();
                }
            }
        };
        actAutoRefresh.setImageDescriptor(ImageUtil.getImageDescriptor(Images.refresh_auto));
        man.add(actAutoRefresh);

        long now = TimeUtil.getCurrentTime(serverId);
        date = DateUtil.yyyymmdd(now);
        stime = now - DateUtil.MILLIS_PER_FIVE_MINUTE;
        etime = now;
        loadQueryJob.schedule(2000);

        thread = new RefreshThread(this, 10000);
        thread.start();
    }

    public void refresh() {
        if (isAutoRefresh) {
            root.clear();
            long now = TimeUtil.getCurrentTime(serverId);
            date = DateUtil.yyyymmdd(now);
            stime = now - DateUtil.MILLIS_PER_FIVE_MINUTE;
            etime = now;
            loadQueryJob.schedule();
        }
    }

    public void setInput(long stime, long etime) {
        if (loadQueryJob.getState() == Job.WAITING || loadQueryJob.getState() == Job.RUNNING) {
            MessageDialog.openInformation(null, "STOP", "Previous loading is not yet finished");
            return;
        }
        if (etime - stime < DateUtil.MILLIS_PER_MINUTE) {
            stime = etime - DateUtil.MILLIS_PER_MINUTE;
        }
        root.clear();
        this.stime = stime;
        this.etime = etime;
        this.date = DateUtil.yyyymmdd(stime);
        loadQueryJob.schedule();
    }

    ArrayList<DigestSchema> columnList = new ArrayList<DigestSchema>();

    private void createColumns() {
        columnList.clear();
        for (DigestSchema column : DigestSchema.values()) {
            createTreeViewerColumn(column.getTitle(), column.getWidth(), column.getAlignment(), true, true,
                    column.isNumber());
            columnList.add(column);
        }
    }

    private TreeViewerColumn createTreeViewerColumn(String title, int width, int alignment, boolean resizable,
            boolean moveable, final boolean isNumber) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(viewer, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setAlignment(alignment);
        column.setMoveable(moveable);
        columnLayout.setColumnData(column, new ColumnPixelData(width, resizable));
        column.setData("isNumber", isNumber);
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                TreeLabelSorter sorter = (TreeLabelSorter) viewer.getComparator();
                TreeColumn selectedColumn = (TreeColumn) e.widget;
                sorter.setColumn(selectedColumn);
            }
        });
        return viewerColumn;
    }

    public void setFocus() {

    }

    Job loadQueryJob = new Job("Load Digest List...") {

        HashMap<DigestKey, MapPack> summaryMap = new HashMap<DigestKey, MapPack>();
        HashMap<Integer, StatusPack> firstStatusMap = new HashMap<Integer, StatusPack>();
        HashMap<Integer, StatusPack> lastStatusMap = new HashMap<Integer, StatusPack>();

        protected IStatus run(final IProgressMonitor monitor) {
            summaryMap.clear();
            firstStatusMap.clear();
            lastStatusMap.clear();
            monitor.beginTask(DateUtil.hhmmss(stime) + " ~ " + DateUtil.hhmmss(etime), 100);
            TcpProxy tcp = TcpProxy.getTcpProxy(serverId);
            try {
                MapPack param = new MapPack();
                ListValue objHashLv = agentProxy.getObjHashLv(date, serverId, CounterConstants.MARIA_PLUGIN);
                if (objHashLv.size() > 0) {
                    param.put("objHash", objHashLv);
                    param.put("date", date);
                    param.put("time", stime);
                    List<Pack> firstList = tcp.process(RequestCmd.DB_LAST_DIGEST_TABLE, param);
                    for (Pack p : firstList) {
                        StatusPack s = (StatusPack) p;
                        firstStatusMap.put(s.objHash, s);
                    }
                    param.put("stime", stime);
                    param.put("etime", etime);
                    tcp.process(RequestCmd.DB_DIGEST_TABLE, param, new INetReader() {
                        public void process(DataInputX in) throws IOException {
                            Pack p = in.readPack();
                            switch (p.getPackType()) {
                            case PackEnum.MAP:
                                MapPack m = (MapPack) p;
                                if (m.containsKey("percent")) {
                                    monitor.worked(m.getInt("percent"));
                                } else {
                                    int objHash = m.getInt("objHash");
                                    int digestHash = m.getInt("digestHash");
                                    summaryMap.put(new DigestKey(objHash, digestHash), m);
                                }
                                break;
                            case PackEnum.PERF_STATUS:
                                StatusPack sp = (StatusPack) p;
                                lastStatusMap.put(sp.objHash, sp);
                                break;
                            }
                        }
                    });
                }
            } catch (Exception e) {
                ConsoleProxy.errorSafe(e.toString());
            } finally {
                TcpProxy.putTcpProxy(tcp);
            }
            Iterator<Integer> itr = lastStatusMap.keySet().iterator();
            while (itr.hasNext()) {
                int objHash = itr.next();
                StatusPack firstStatus = firstStatusMap.get(objHash);
                StatusPack lastStatus = lastStatusMap.get(objHash);
                HashMap<Integer, MapValue> firstMap = new HashMap<Integer, MapValue>();
                if (firstStatus == null) {
                    // nothing
                } else {
                    // index first values for delta
                    MapValue firstData = firstStatus.data;
                    ListValue firstDigestLv = firstData.getList("DIGEST_TEXT");
                    for (int i = 0; i < firstDigestLv.size(); i++) {
                        int digestHash = firstDigestLv.getInt(i);
                        MapValue valueMap = new MapValue();
                        Enumeration<String> keys = firstData.keys();
                        while (keys.hasMoreElements()) {
                            String key = keys.nextElement();
                            valueMap.put(key, firstData.getList(key).get(i));
                        }
                        firstMap.put(digestHash, valueMap);
                    }
                }
                MapValue data = lastStatus.data;
                ListValue digestLv = data.getList("DIGEST_TEXT");
                ListValue schemaNameLv = data.getList("SCHEMA_NAME");
                ListValue executionLv = data.getList("COUNT_STAR");
                ListValue timerWaitLv = data.getList("SUM_TIMER_WAIT");
                ListValue lockTimeLv = data.getList("SUM_LOCK_TIME");
                ListValue errorsLv = data.getList("SUM_ERRORS");
                ListValue warnsLv = data.getList("SUM_WARNINGS");
                ListValue rowsAffectedLv = data.getList("SUM_ROWS_AFFECTED");
                ListValue rowsSentLv = data.getList("SUM_ROWS_SENT");
                ListValue rowsExaminedLv = data.getList("SUM_ROWS_EXAMINED");
                ListValue createdTmpDiskTablesLv = data.getList("SUM_CREATED_TMP_DISK_TABLES");
                ListValue createdTmpTablesLv = data.getList("SUM_CREATED_TMP_TABLES");
                ListValue selectFullJoin = data.getList("SUM_SELECT_FULL_JOIN");
                ListValue selectFullRangeJoin = data.getList("SUM_SELECT_FULL_RANGE_JOIN");
                ListValue selectRangeLv = data.getList("SUM_SELECT_RANGE");
                ListValue selectRangeCheckLv = data.getList("SUM_SELECT_RANGE_CHECK");
                ListValue selectScanLv = data.getList("SUM_SELECT_SCAN");
                ListValue sortMergePassesLv = data.getList("SUM_SORT_MERGE_PASSES");
                ListValue sortRangeLv = data.getList("SUM_SORT_RANGE");
                ListValue sortRowsLv = data.getList("SUM_SORT_ROWS");
                ListValue sortScanLv = data.getList("SUM_SORT_SCAN");
                ListValue noIndexUsedLv = data.getList("SUM_NO_INDEX_USED");
                ListValue noGoodIndexUsedLv = data.getList("SUM_NO_GOOD_INDEX_USED");
                ListValue firstSeenLv = data.getList("FIRST_SEEN");
                ListValue lastSeenLv = data.getList("LAST_SEEN");

                for (int i = 0; i < digestLv.size(); i++) {
                    if (lastSeenLv.getLong(i) < stime || lastSeenLv.getLong(i) > etime) {
                        continue;
                    }
                    DigestModel model = new DigestModel();
                    int digestHash = digestLv.getInt(i);
                    MapPack m = summaryMap.get(new DigestKey(objHash, digestHash));
                    if (m == null)
                        continue;
                    long maxTimerWait = m.getLong("MAX_TIMER_WAIT");
                    long minTimerWait = m.getLong("MIN_TIMER_WAIT");
                    long avgTimerWait = m.getLong("AVG_TIMER_WAIT");
                    int count = m.getInt("count");
                    model.objHash = objHash;
                    model.digestHash = digestHash;
                    model.name = TextProxy.object.getLoadText(date, objHash, serverId);
                    model.database = TextProxy.maria.getLoadText(date, schemaNameLv.getInt(i), serverId);
                    model.firstSeen = firstSeenLv.getLong(i);
                    model.lastSeen = lastSeenLv.getLong(i);
                    model.avgResponseTime = avgTimerWait / (double) count;
                    model.minResponseTime = minTimerWait;
                    model.maxResponseTime = maxTimerWait;

                    MapValue firstValue = firstMap.get(digestHash);
                    if (firstValue == null) {
                        firstValue = new MapValue();
                    }
                    model.execution = executionLv.getInt(i) - firstValue.getInt("COUNT_STAR");
                    if (model.execution < 1) {
                        System.out.println("first=>" + firstStatus);
                        System.out.println("last =>" + lastStatus);
                    }
                    model.errorCnt = errorsLv.getInt(i) - firstValue.getInt("SUM_ERRORS");
                    model.warnCnt = warnsLv.getInt(i) - firstValue.getInt("SUM_WARNINGS");
                    model.sumResponseTime = timerWaitLv.getLong(i) - firstValue.getLong("SUM_TIMER_WAIT");
                    model.lockTime = lockTimeLv.getLong(i) - firstValue.getLong("SUM_LOCK_TIME");
                    model.rowsAffected = rowsAffectedLv.getLong(i) - firstValue.getLong("SUM_ROWS_AFFECTED");
                    model.rowsSent = rowsSentLv.getLong(i) - firstValue.getLong("SUM_ROWS_SENT");
                    model.rowsExamined = rowsExaminedLv.getLong(i) - firstValue.getLong("SUM_ROWS_EXAMINED");
                    model.createdTmpDiskTables = createdTmpDiskTablesLv.getLong(i)
                            - firstValue.getLong("SUM_CREATED_TMP_DISK_TABLES");
                    model.createdTmpTables = createdTmpTablesLv.getLong(i)
                            - firstValue.getLong("SUM_CREATED_TMP_TABLES");
                    model.selectFullJoin = selectFullJoin.getLong(i) - firstValue.getLong("SUM_SELECT_FULL_JOIN");
                    model.selectFullRangeJoin = selectFullRangeJoin.getLong(i)
                            - firstValue.getLong("SUM_SELECT_FULL_RANGE_JOIN");
                    model.selectRange = selectRangeLv.getLong(i) - firstValue.getLong("SUM_SELECT_RANGE");
                    model.selectRangeCheck = selectRangeCheckLv.getLong(i)
                            - firstValue.getLong("SUM_SELECT_RANGE_CHECK");
                    model.selectScan = selectScanLv.getLong(i) - firstValue.getLong("SUM_SELECT_SCAN");
                    model.sortMergePasses = sortMergePassesLv.getLong(i)
                            - firstValue.getLong("SUM_SORT_MERGE_PASSES");
                    model.sortRange = sortRangeLv.getLong(i) - firstValue.getLong("SUM_SORT_RANGE");
                    model.sortRows = sortRowsLv.getLong(i) - firstValue.getLong("SUM_SORT_ROWS");
                    model.sortScan = sortScanLv.getLong(i) - firstValue.getLong("SUM_SORT_SCAN");
                    model.noIndexUsed = noIndexUsedLv.getLong(i) - firstValue.getLong("SUM_NO_INDEX_USED");
                    model.noGoodIndexUsed = noGoodIndexUsedLv.getLong(i)
                            - firstValue.getLong("SUM_NO_GOOD_INDEX_USED");

                    DigestModel parent = root.get(digestHash);
                    if (parent == null) {
                        parent = new DigestModel();
                        parent.digestHash = digestHash;
                        String digestTxt = TextProxy.maria.getLoadText(date, digestHash, serverId);
                        parent.name = digestTxt == null ? "unknown hash" : digestTxt;
                        root.put(digestHash, parent);
                    }
                    model.parent = parent;
                    parent.addChild(model);
                }
            }
            Iterator<DigestModel> parents = root.values().iterator();
            while (parents.hasNext()) {
                DigestModel parent = parents.next();
                DigestModel[] childs = parent.getChildArray();
                if (childs != null) {
                    double sumAvg = 0.0d;
                    for (DigestModel child : childs) {
                        sumAvg += child.avgResponseTime;
                    }
                    parent.avgResponseTime = sumAvg / childs.length;
                }
            }
            monitor.done();
            ExUtil.exec(viewer.getTree(), new Runnable() {
                public void run() {
                    DigestTableView.this.setContentDescription(DateUtil.format(stime, "MM-dd HH:mm:ss") + " ~ "
                            + DateUtil.format(etime, "MM-dd HH:mm:ss") + " (" + root.size() + ")");
                    viewer.refresh();
                }
            });
            return Status.OK_STATUS;
        }
    };

    class TreeContentProvider implements ITreeContentProvider {

        public void dispose() {
        }

        public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof DigestModel) {
                DigestModel parent = (DigestModel) parentElement;
                Object[] array = parent.getChildArray();
                if (array != null)
                    return array;
            }
            return new Object[0];
        }

        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof HashMap) {
                HashMap map = (HashMap) inputElement;
                Object[] objArray = new Object[map.size()];
                Iterator itr = map.values().iterator();
                int cnt = 0;
                while (itr.hasNext()) {
                    objArray[cnt] = itr.next();
                    cnt++;
                }

                return objArray;
            }
            return new Object[0];
        }

        public Object getParent(Object element) {
            if (element instanceof DigestModel) {
                return ((DigestModel) element).parent;
            }
            return null;
        }

        public boolean hasChildren(Object element) {
            if (element instanceof DigestModel) {
                return ((DigestModel) element).getChildArray() != null;
            }
            return false;
        }
    }

    class TreeLabelProvider implements ITableLabelProvider {

        public void addListener(ILabelProviderListener listener) {
        }

        public void dispose() {
        }

        public boolean isLabelProperty(Object element, String property) {
            return false;
        }

        public void removeListener(ILabelProviderListener listener) {
        }

        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }

        public String getColumnText(Object element, int columnIndex) {
            if (element instanceof DigestModel) {
                DigestModel model = (DigestModel) element;
                DigestSchema column = columnList.get(columnIndex);
                switch (column) {
                case DIGEST_TEXT:
                    return model.name;
                case SCHEMA_NAME:
                    return model.database;
                case COUNT_STAR:
                    return FormatUtil.print(model.execution, "#,##0");
                case SUM_ERRORS:
                    return FormatUtil.print(model.errorCnt, "#,##0");
                case SUM_WARNINGS:
                    return FormatUtil.print(model.warnCnt, "#,##0");
                case SUM_TIMER_WAIT:
                    return FormatUtil.print(model.sumResponseTime * PICO, "#,##0.00#");
                case AVG_TIMER_WAIT:
                    return FormatUtil.print(model.avgResponseTime * PICO, "#,##0.00#");
                case MIN_TIMER_WAIT:
                    return FormatUtil.print(model.minResponseTime * PICO, "#,##0.00#");
                case MAX_TIMER_WAIT:
                    return FormatUtil.print(model.maxResponseTime * PICO, "#,##0.00#");
                case SUM_LOCK_TIME:
                    return FormatUtil.print(model.lockTime * PICO, "#,##0.00#");
                case SUM_ROWS_AFFECTED:
                    return FormatUtil.print(model.rowsAffected, "#,##0");
                case SUM_ROWS_SENT:
                    return FormatUtil.print(model.rowsSent, "#,##0");
                case SUM_ROWS_EXAMINED:
                    return FormatUtil.print(model.rowsExamined, "#,##0");
                case SUM_CREATED_TMP_DISK_TABLES:
                    return FormatUtil.print(model.createdTmpDiskTables, "#,##0");
                case SUM_CREATED_TMP_TABLES:
                    return FormatUtil.print(model.createdTmpTables, "#,##0");
                case SUM_SELECT_FULL_JOIN:
                    return FormatUtil.print(model.selectFullJoin, "#,##0");
                case SUM_SELECT_FULL_RANGE_JOIN:
                    return FormatUtil.print(model.selectFullRangeJoin, "#,##0");
                case SUM_SELECT_RANGE:
                    return FormatUtil.print(model.selectRange, "#,##0");
                case SUM_SELECT_RANGE_CHECK:
                    return FormatUtil.print(model.selectRangeCheck, "#,##0");
                case SUM_SELECT_SCAN:
                    return FormatUtil.print(model.selectScan, "#,##0");
                case SUM_SORT_MERGE_PASSES:
                    return FormatUtil.print(model.sortMergePasses, "#,##0");
                case SUM_SORT_RANGE:
                    return FormatUtil.print(model.sortRange, "#,##0");
                case SUM_SORT_ROWS:
                    return FormatUtil.print(model.sortRows, "#,##0");
                case SUM_SORT_SCAN:
                    return FormatUtil.print(model.sortScan, "#,##0");
                case SUM_NO_INDEX_USED:
                    return FormatUtil.print(model.noIndexUsed, "#,##0");
                case SUM_NO_GOOD_INDEX_USED:
                    return FormatUtil.print(model.noGoodIndexUsed, "#,##0");
                case FIRST_SEEN:
                    return DateUtil.timestamp(model.firstSeen);
                case LAST_SEEN:
                    return DateUtil.timestamp(model.lastSeen);
                }
            }
            return null;
        }
    }

    public void dispose() {
        super.dispose();
        if (loadQueryJob != null
                && (loadQueryJob.getState() == Job.WAITING || loadQueryJob.getState() == Job.RUNNING)) {
            loadQueryJob.cancel();
        }
    }

    public static void main(String[] args) {
        System.out.println(139871834183L * Math.pow(10, -12));
    }
}