/*
* 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.views;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
import au.com.bytecode.opencsv.CSVWriter;
import scouter.client.Images;
import scouter.client.model.TextProxy;
import scouter.client.net.TcpProxy;
import scouter.client.popup.AlertNotifierDialog;
import scouter.client.popup.CalendarDialog;
import scouter.client.server.Server;
import scouter.client.server.ServerManager;
import scouter.client.sorter.ColumnLabelSorter;
import scouter.client.util.ColorUtil;
import scouter.client.util.ConsoleProxy;
import scouter.client.util.ExUtil;
import scouter.client.util.ImageUtil;
import scouter.client.util.TimeUtil;
import scouter.lang.AlertLevel;
import scouter.lang.pack.AlertPack;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.Pack;
import scouter.lang.value.MapValue;
import scouter.net.RequestCmd;
import scouter.util.DateUtil;
import scouter.util.HashUtil;
import scouter.util.StringEnumer;
import scouter.util.StringUtil;
public class AlertDetailListView extends ViewPart implements CalendarDialog.ILoadCalendarDialog {
public static final String ID = AlertDetailListView.class.getName();
private int serverId;
private Text dateText;
private DateTime fromTime;
private DateTime toTime;
private Text maxCountText;
private Combo levelCombo;
private Text objText;
private Text keyText;
private TableViewer viewer;
private String yyyymmdd;
private TableColumnLayout tableColumnLayout;
public void init(IViewSite site) throws PartInitException {
super.init(site);
String secId = site.getSecondaryId();
serverId = Integer.valueOf(secId);
yyyymmdd = DateUtil.yyyymmdd(TimeUtil.getCurrentTime(serverId));
}
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(1, true));
Group parentGroup = new Group(parent, SWT.NONE);
parentGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
GridLayout layout = new GridLayout(10, false);
parentGroup.setLayout(layout);
Label label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("Date");
dateText = new Text(parentGroup, SWT.READ_ONLY | SWT.BORDER);
dateText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
dateText.setBackground(ColorUtil.getInstance().getColor("white"));
dateText.setText(DateUtil.format(TimeUtil.getCurrentTime(serverId), "yyyy-MM-dd"));
Button button = new Button(parentGroup, SWT.PUSH);
button.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
button.setImage(Images.calendar);
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
switch (event.type) {
case SWT.Selection:
Display display = Display.getCurrent();
if (display == null) {
display = Display.getDefault();
}
CalendarDialog dialog = new CalendarDialog(display, AlertDetailListView.this);
dialog.show(dateText.getLocation().x, dateText.getLocation().y, DateUtil.yyyymmdd(yyyymmdd));
break;
}
}
});
long now = TimeUtil.getCurrentTime(serverId);
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("From");
fromTime = new DateTime(parentGroup, SWT.TIME | SWT.SHORT);
fromTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
fromTime.setHours(DateUtil.getHour(now) - 1);
fromTime.setMinutes(DateUtil.getMin(now));
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("To");
toTime = new DateTime(parentGroup, SWT.TIME | SWT.SHORT);
toTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
toTime.setHours(DateUtil.getHour(now));
toTime.setMinutes(DateUtil.getMin(now));
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("Count(Max:1000)");
maxCountText = new Text(parentGroup, SWT.BORDER);
maxCountText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
maxCountText.setText("500");
maxCountText.setToolTipText("1~1000");
maxCountText.addKeyListener(new KeyListener() {
public void keyReleased(KeyEvent e) {
String count = maxCountText.getText();
if (StringUtil.isEmpty(count)) {
return;
}
try {
Integer.valueOf(count);
} catch(Exception ex) {
MessageDialog.openError(maxCountText.getShell(), "Invalid Count", "Count is allowed only digits");
maxCountText.setText("");
}
}
public void keyPressed(KeyEvent e) {
}
});
button = new Button(parentGroup, SWT.PUSH);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
button.setText("&Search");
button.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
load();
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("Level");
GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.horizontalSpan = 2;
levelCombo = new Combo (parentGroup, SWT.READ_ONLY);
levelCombo.setLayoutData(gridData);
levelCombo.add("ALL");
StringEnumer itr = AlertLevel.names();
while (itr.hasMoreElements()) {
levelCombo.add(itr.nextString());
}
levelCombo.select(0);
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("Object");
objText = new Text(parentGroup, SWT.BORDER);
objText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
label = new Label(parentGroup, SWT.NONE);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
label.setText("Key");
keyText = new Text(parentGroup, SWT.BORDER);
gridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
gridData.horizontalSpan = 3;
keyText.setLayoutData(gridData);
button = new Button(parentGroup, SWT.PUSH);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
button.setText("&Clear");
button.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
levelCombo.select(0);
objText.setText("");
keyText.setText("");
viewer.getTable().removeAll();
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
Composite tableComposite = new Composite(parent, SWT.NONE);
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
viewer = new TableViewer(tableComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
createColumns();
final Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
viewer.setContentProvider(new ArrayContentProvider());
viewer.setComparator(new ColumnLabelSorter(viewer));
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
StructuredSelection sel = (StructuredSelection) event.getSelection();
Object o = sel.getFirstElement();
if (o instanceof AlertData) {
AlertData data = (AlertData) o;
Display display = Display.getCurrent();
if (display == null) {
display = Display.getDefault();
}
AlertNotifierDialog alertDialog = new AlertNotifierDialog(display, serverId);
alertDialog.setObjName(data.object);
alertDialog.setPack(data.toPack());
alertDialog.show(getViewSite().getShell().getBounds());
} else {
System.out.println(o);
}
}
});
IToolBarManager man = getViewSite().getActionBars().getToolBarManager();
man.add(new Action("Export CSV", ImageUtil.getImageDescriptor(Images.csv)) {
public void run() {
Server server = ServerManager.getInstance().getServer(serverId);
FileDialog dialog = new FileDialog(getViewSite().getShell(), SWT.SAVE);
dialog.setOverwrite(true);
String filename = "[" + server.getName() + "]" + yyyymmdd + "_" + fromTime.getHours() + fromTime.getMinutes() + "_" + toTime.getHours() + toTime.getMinutes() + ".csv";
dialog.setFileName(filename);
dialog.setFilterExtensions(new String[] { "*.csv", "*.*" });
dialog.setFilterNames(new String[] { "CSV File(*.csv)", "All Files" });
String fileSelected = dialog.open();
if (fileSelected != null) {
CSVWriter cw = null;
try {
cw = new CSVWriter(new FileWriter(fileSelected));
int colCnt = viewer.getTable().getColumnCount();
List<String> list = new ArrayList<String>();
for (int i = 0; i < colCnt; i++) {
TableColumn column = viewer.getTable().getColumn(i);
list.add(column.getText());
}
cw.writeNext(list.toArray(new String[list.size()]));
cw.flush();
TableItem[] items = viewer.getTable().getItems();
if (items != null && items.length > 0) {
for (TableItem item : items) {
list.clear();
for (int i = 0; i < colCnt; i++) {
list.add(item.getText(i));
}
cw.writeNext(list.toArray(new String[list.size()]));
cw.flush();
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (cw != null) {
cw.close();
}
} catch (Throwable th) {}
}
}
}
});
}
private void createColumns() {
for (AlertColumnEnum column : AlertColumnEnum.values()) {
TableViewerColumn c = createTableViewerColumn(column.getTitle(), column.getWeight(), column.getAlignment(), column.isResizable(), column.isMoveable(), column.isNumber());
ColumnLabelProvider labelProvider = null;
switch (column) {
case TIME :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return DateUtil.format(((AlertData) element).time, "yyyy-MM-dd HH:mm:ss");
}
return null;
}
};
break;
case LEVEL :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return ((AlertData) element).level;
}
return null;
}
};
break;
case OBJECT :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return ((AlertData) element).object;
}
return null;
}
};
break;
case TITLE :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return ((AlertData) element).title;
}
return null;
}
};
break;
case MESSAGE :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return ((AlertData) element).message;
}
return null;
}
};
break;
case TAGS :
labelProvider = new ColumnLabelProvider() {
public String getText(Object element) {
if (element instanceof AlertData) {
return ((AlertData) element).tags.toString();
}
return null;
}
};
break;
}
if (labelProvider != null) {
c.setLabelProvider(labelProvider);
}
}
}
private TableViewerColumn createTableViewerColumn(String title, int weight, int alignment, boolean resizable, boolean moveable, final boolean isNumber) {
final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setAlignment(alignment);
column.setMoveable(moveable);
tableColumnLayout.setColumnData(column, new ColumnWeightData(weight, 10, resizable));
column.setData("isNumber", isNumber);
column.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ColumnLabelSorter sorter = (ColumnLabelSorter) viewer.getComparator();
TableColumn selectedColumn = (TableColumn) e.widget;
sorter.setColumn(selectedColumn);
}
});
return viewerColumn;
}
public void setFocus() {
}
public void setInput(long stime, long etime) {
onPressedOk(DateUtil.yyyymmdd(stime));
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(stime));
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minutes = calendar.get(Calendar.MINUTE);
int seconds = calendar.get(Calendar.SECOND);
fromTime.setTime(hours, minutes, seconds);
calendar = Calendar.getInstance();
calendar.setTime(new Date(etime));
hours = calendar.get(Calendar.HOUR_OF_DAY);
minutes = calendar.get(Calendar.MINUTE);
seconds = calendar.get(Calendar.SECOND);
toTime.setTime(hours, minutes, seconds);
}
private void load() {
int fromHour = fromTime.getHours();
int fromMin = fromTime.getMinutes();
int toHour = toTime.getHours();
int toMin = toTime.getMinutes();
final long stime = DateUtil.getTime(yyyymmdd + (fromHour < 10 ? "0" + fromHour : fromHour) + (fromMin < 10 ? "0" + fromMin : fromMin), "yyyyMMddHHmm");
final long etime = DateUtil.getTime(yyyymmdd + (toHour < 10 ? "0" + toHour : toHour) + (toMin < 10 ? "0" + toMin : toMin), "yyyyMMddHHmm");
final String count = maxCountText.getText();
final String level = levelCombo.getText();
final String object = objText.getText();
final String key = keyText.getText();
ExUtil.asyncRun(new Runnable() {
public void run() {
TcpProxy tcp = TcpProxy.getTcpProxy(serverId);
final List<AlertData> dataList = new ArrayList<AlertData>();
try {
MapPack param = new MapPack();
param.put("date", yyyymmdd);
param.put("stime", stime);
param.put("etime", etime);
if (StringUtil.isNotEmpty(count)) {
param.put("count", Long.valueOf(count));
}
if (StringUtil.isNotEmpty(level) && "ALL".equalsIgnoreCase(level) == false) {
param.put("level", level);
}
if (StringUtil.isNotEmpty(object)) {
param.put("object", object);
}
if (StringUtil.isNotEmpty(key)) {
param.put("key", key);
}
List<Pack> packList = tcp.process(RequestCmd.ALERT_LOAD_TIME, param);
for (Pack pack : packList) {
if (pack instanceof AlertPack) {
AlertPack alertPack = (AlertPack) pack;
AlertData data = new AlertData();
data.time = alertPack.time;
data.level = AlertLevel.getName(alertPack.level);
data.object = TextProxy.object.getLoadText(yyyymmdd, alertPack.objHash, serverId);
data.title = alertPack.title;
data.message = alertPack.message;
data.objType = alertPack.objType;
data.tags = alertPack.tags;
dataList.add(data);
}
}
} catch (Exception e) {
e.printStackTrace();
ConsoleProxy.errorSafe(e.getMessage());
} finally {
TcpProxy.putTcpProxy(tcp);
}
ExUtil.exec(viewer.getTable(), new Runnable() {
public void run() {
viewer.setInput(dataList);
}
});
}
});
}
public void onPressedOk(long startTime, long endTime) { }
public void onPressedOk(String date) {
this.yyyymmdd = date;
dateText.setText(date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8));
}
public void onPressedCancel() { };
enum AlertColumnEnum {
TIME("TIME", 6, SWT.RIGHT, true, true, false), //
LEVEL("LEVEL", 3, SWT.CENTER, true, true, false), //
OBJECT("OBJECT", 9, SWT.LEFT, true, true, false),
TITLE("TITLE", 10, SWT.LEFT, true, true, false),
MESSAGE("MESSAGE", 25, SWT.LEFT, true, true, false),
TAGS("TAGs", 7, SWT.LEFT, true, true, false);
private final String title;
private final int weight;
private final int alignment;
private final boolean resizable;
private final boolean moveable;
private final boolean isNumber;
private AlertColumnEnum(String text, int weight, int alignment, boolean resizable, boolean moveable, boolean isNumber) {
this.title = text;
this.weight = weight;
this.alignment = alignment;
this.resizable = resizable;
this.moveable = moveable;
this.isNumber = isNumber;
}
public String getTitle(){
return title;
}
public int getAlignment(){
return alignment;
}
public boolean isResizable(){
return resizable;
}
public boolean isMoveable(){
return moveable;
}
public int getWeight() {
return weight;
}
public boolean isNumber() {
return this.isNumber;
}
}
static class AlertData {
public long time;
public String level;
public String object;
public String title;
public String message;
public MapValue tags;
public String objType;
public AlertPack toPack() {
AlertPack pack = new AlertPack();
pack.level = AlertLevel.getValue(level);
pack.message = message;
pack.objHash = object == null ? 0 : HashUtil.hash(object);
pack.objType = objType;
pack.tags = tags;
pack.time = time;
pack.title = title;
return pack;
}
public String toString() {
return "AlertData [time=" + time + ", level=" + level + ", object="
+ object + ", title=" + title + ", message=" + message
+ ", tags=" + tags + ", objType=" + objType + "]";
}
}
}