diff --git a/scouter.agent.host/src/scouter/agent/counter/task/HostNetDiskPerf.java b/scouter.agent.host/src/scouter/agent/counter/task/HostNetDiskPerf.java new file mode 100644 index 000000000..27bca7a08 --- /dev/null +++ b/scouter.agent.host/src/scouter/agent/counter/task/HostNetDiskPerf.java @@ -0,0 +1,181 @@ +package scouter.agent.counter.task; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * + * original from - https://svn.apache.org/repos/asf/chukwa/trunk/src/main/java/org/apache/hadoop/chukwa/datacollection/adaptor/sigar/SigarRunner.java + * + */ +/** + * Net Usage, Disk Usage + * author: gunlee01@gmail.com + */ + + +import org.hyperic.sigar.*; +import scouter.agent.Logger; +import scouter.agent.counter.CounterBasket; +import scouter.agent.counter.anotation.Counter; +import scouter.lang.counters.CounterConstants; + +import java.util.HashMap; +import java.util.Map; + +public class HostNetDiskPerf { + static int SLEEP_TIME = 2000; + static Sigar sigarImpl = new Sigar(); + static SigarProxy sigar = SigarProxyCache.newInstance(sigarImpl, SLEEP_TIME); + + private static String[] netIf = null; + private static FileSystem[] fs = null; + + private static HashMap> previousNetworkStats = new HashMap>(); + private static HashMap> previousDiskStats = new HashMap>(); + private static final String RX_DELTA = "rxD"; + private static final String TX_DELTA = "txD"; + private static final String READ_DELTA = "rdD"; + private static final String WRITE_DELTA = "wrD"; + private static volatile long rxTotalBytesPerSec = 0L; + private static volatile long txTotalBytesPerSec = 0L; + private static volatile long readTotalBytesPerSec = 0L; + private static volatile long writeTotalBytesPerSec = 0L; + + public static long getRxTotalBytesPerSec() { + return HostNetDiskPerf.rxTotalBytesPerSec; + } + + public static long getTxTotalBytesPerSec() { + return HostNetDiskPerf.txTotalBytesPerSec; + } + + public static long getReadTotalBytesPerSec() { + return HostNetDiskPerf.readTotalBytesPerSec; + } + + public static long getWriteTotalBytesPerSec() { + return HostNetDiskPerf.writeTotalBytesPerSec; + } + + @Counter(interval = 10000) + public void process(CounterBasket pw) { + try { + netUsage(10); + diskIO(10); + SigarProxyCache.clear(sigar); + } catch (Exception e) { + Logger.println("A141", 10, "HostPerfProcess10s", e); + } + } + + private void netUsage(int checkIntervalSec) { + try { + if (netIf == null) { + netIf = sigar.getNetInterfaceList(); + } + long tmpRxTotal = 0L; + long tmpTxTotal = 0L; + + for (int i = 0; i < netIf.length; i++) { + NetInterfaceStat net = null; + try { + net = sigar.getNetInterfaceStat(netIf[i]); + } catch (SigarException e) { + // Ignore the exception when trying to stat network interface + Logger.println("A143", 300, "SigarException trying to stat network device " + netIf[i], e); + continue; + } + Map netMap = new HashMap(); + long rxBytes = net.getRxBytes(); + long txBytes = net.getTxBytes(); + + netMap.put(CounterConstants.HOST_NET_RX_BYTES, rxBytes); + netMap.put(CounterConstants.HOST_NET_TX_BYTES, txBytes); + + Map preMap = previousNetworkStats.get(netIf[i]); + + if (preMap != null) { + long rxDelta = (rxBytes - preMap.get(CounterConstants.HOST_NET_RX_BYTES)) / checkIntervalSec; // per sec delta + long txDelta = (txBytes - preMap.get(CounterConstants.HOST_NET_TX_BYTES)) / checkIntervalSec; // per sec delta + + netMap.put(this.RX_DELTA, rxDelta); + netMap.put(this.TX_DELTA, txDelta); + + tmpRxTotal += rxDelta; + tmpTxTotal += txDelta; + } + previousNetworkStats.put(netIf[i], netMap); + } + + HostNetDiskPerf.rxTotalBytesPerSec = tmpRxTotal; + HostNetDiskPerf.txTotalBytesPerSec = tmpTxTotal; + + } catch (SigarException se) { + Logger.println("A144", 60, "SigarException on net usage", se); + HostNetDiskPerf.rxTotalBytesPerSec = 0; + HostNetDiskPerf.txTotalBytesPerSec = 0; + } + } + + private void diskIO(int checkIntervalSec) { + try { + if (fs == null) { + fs = sigar.getFileSystemList(); + } + long tmpReadTotal = 0L; + long tmpWriteTotal = 0L; + + for (int i = 0; i < fs.length; i++) { + FileSystemUsage usage = null; + try { + usage = sigar.getFileSystemUsage(fs[i].getDirName()); + } catch (SigarException e) { + // Ignore the exception when trying to stat file interface + Logger.println("A145", 300, "SigarException trying to stat file system device " + fs[i], e); + continue; + } + Map fsMap = new HashMap(); + long readBytes = usage.getDiskReadBytes(); + long writeBytes = usage.getDiskWriteBytes(); + + fsMap.put(CounterConstants.HOST_DISK_READ_BYTES, readBytes); + fsMap.put(CounterConstants.HOST_DISK_WRITE_BYTES, writeBytes); + + Map preMap = previousDiskStats.get(fs[i].getDevName()); + + if (preMap != null) { + long readDelta = (readBytes - preMap.get(CounterConstants.HOST_DISK_READ_BYTES)) / checkIntervalSec; // per sec delta + long writeDelta = (writeBytes - preMap.get(CounterConstants.HOST_DISK_WRITE_BYTES)) / checkIntervalSec; // per sec delta + + fsMap.put(this.READ_DELTA, readDelta); + fsMap.put(this.WRITE_DELTA, writeDelta); + + tmpReadTotal += readDelta; + tmpWriteTotal += writeDelta; + } + previousDiskStats.put(fs[i].getDevName(), fsMap); + } + + HostNetDiskPerf.readTotalBytesPerSec = tmpReadTotal; + HostNetDiskPerf.writeTotalBytesPerSec = tmpWriteTotal; + + } catch (SigarException se) { + Logger.println("A144", 60, "SigarException on net usage", se); + HostNetDiskPerf.rxTotalBytesPerSec = 0; + HostNetDiskPerf.txTotalBytesPerSec = 0; + } + } + +} diff --git a/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java b/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java index f6c730e58..d4db43aca 100644 --- a/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java +++ b/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java @@ -1,17 +1,27 @@ -package scouter.agent.counter.task; -import org.hyperic.sigar.CpuPerc; -import org.hyperic.sigar.FileSystem; -import org.hyperic.sigar.FileSystemUsage; -import org.hyperic.sigar.Mem; -import org.hyperic.sigar.NetStat; -import org.hyperic.sigar.NfsFileSystem; -import org.hyperic.sigar.Sigar; -import org.hyperic.sigar.SigarException; -import org.hyperic.sigar.SigarProxy; -import org.hyperic.sigar.SigarProxyCache; -import org.hyperic.sigar.Swap; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.agent.counter.task; +import org.hyperic.sigar.*; import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.counter.CounterBasket; @@ -36,7 +46,7 @@ public class HostPerf { MeterResource cpuMeter = new MeterResource(); MeterResource sysCpuMeter = new MeterResource(); MeterResource userCpuMeter = new MeterResource(); - + @Counter public void process(CounterBasket pw) { try { @@ -101,6 +111,17 @@ void domain(CounterBasket pw) throws SigarException { p.put(CounterConstants.HOST_TCPSTAT_TIM, new DecimalValue(tcpstat_time)); p.put(CounterConstants.HOST_TCPSTAT_EST, new DecimalValue(tcpstat_est)); + p.put(CounterConstants.HOST_NET_RX_BYTES, new DecimalValue(HostNetDiskPerf.getRxTotalBytesPerSec())); + p.put(CounterConstants.HOST_NET_TX_BYTES, new DecimalValue(HostNetDiskPerf.getTxTotalBytesPerSec())); + + p.put(CounterConstants.HOST_DISK_READ_BYTES, new DecimalValue(HostNetDiskPerf.getReadTotalBytesPerSec())); + p.put(CounterConstants.HOST_DISK_WRITE_BYTES, new DecimalValue(HostNetDiskPerf.getWriteTotalBytesPerSec())); + +// System.out.println("rx:" + HostNetDiskPerf.getRxTotalBytesPerSec()); +// System.out.println("tx:" + HostNetDiskPerf.getTxTotalBytesPerSec()); +// System.out.println("read:" + HostNetDiskPerf.getReadTotalBytesPerSec()); +// System.out.println("write:" + HostNetDiskPerf.getWriteTotalBytesPerSec()); + p = pw.getPack(conf.getObjName(), TimeTypeEnum.FIVE_MIN); p.put(CounterConstants.HOST_CPU, new FloatValue(cpu)); p.put(CounterConstants.HOST_SYSCPU, new FloatValue(sysCpu)); @@ -120,6 +141,7 @@ void domain(CounterBasket pw) throws SigarException { p.put(CounterConstants.HOST_TCPSTAT_FIN, new DecimalValue(tcpstat_fin1 + tcpstat_fin2)); p.put(CounterConstants.HOST_TCPSTAT_TIM, new DecimalValue(tcpstat_time)); p.put(CounterConstants.HOST_TCPSTAT_EST, new DecimalValue(tcpstat_est)); + SigarProxyCache.clear(sigar); } diff --git a/scouter.agent.host/src/scouter/boot/SigarTester.java b/scouter.agent.host/src/scouter/boot/SigarTester.java new file mode 100644 index 000000000..eeefec07b --- /dev/null +++ b/scouter.agent.host/src/scouter/boot/SigarTester.java @@ -0,0 +1,199 @@ +package scouter.boot; + +import org.hyperic.sigar.*; +import scouter.util.ThreadUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Gun Lee (gunlee01@gmail.com) on 2016. 5. 9. + */ +public class SigarTester { + private static Sigar sigar = new Sigar(); + private HashMap previousNetworkStats = new HashMap(); + private HashMap previousDiskStats = new HashMap(); + + + public static void main(String[] args) { + SigarTester tester = new SigarTester(); + tester.run(); + ThreadUtil.sleep(2000); + tester.run(); + ThreadUtil.sleep(2000); + tester.run(); + ThreadUtil.sleep(2000); + tester.run(); + ThreadUtil.sleep(2000); + tester.run(); + ThreadUtil.sleep(2000); + tester.run(); + } + + public void run() { + boolean skip = false; + CpuInfo[] cpuinfo = null; + CpuPerc[] cpuPerc = null; + Mem mem = null; + Swap swap = null; + FileSystem[] fs = null; + String[] netIf = null; + Uptime uptime = null; + double[] loadavg = null; + Map map = new HashMap(); + try { + // CPU utilization + List list = new ArrayList(); + try { + cpuinfo = sigar.getCpuInfoList(); + cpuPerc = sigar.getCpuPercList(); + List cpuList = new ArrayList(); + for (int i = 0; i < cpuinfo.length; i++) { + Map cpuMap = new HashMap(); + cpuMap.putAll(cpuinfo[i].toMap()); + cpuMap.put("combined", cpuPerc[i].getCombined()); + cpuMap.put("user", cpuPerc[i].getUser()); + cpuMap.put("sys", cpuPerc[i].getSys()); + cpuMap.put("idle", cpuPerc[i].getIdle()); + cpuMap.put("wait", cpuPerc[i].getWait()); + cpuMap.put("nice", cpuPerc[i].getNice()); + cpuMap.put("irq", cpuPerc[i].getIrq()); + cpuList.add(cpuMap); + } + sigar.getCpuPerc(); + map.put("cpu", cpuList); + + // Uptime + uptime = sigar.getUptime(); + map.put("uptime", uptime.getUptime()); + + // Load Average + loadavg = sigar.getLoadAverage(); + list.add(loadavg[0]); + list.add(loadavg[1]); + list.add(loadavg[2]); + } catch(SigarException se) { + se.printStackTrace(); +// log.error("SigarException caused during collection of CPU utilization"); +// log.error(ExceptionUtils.getStackTrace(se)); + } finally { + map.put("loadavg", list); + } + + + // Memory Utilization + Map memMap = new HashMap(); + Map swapMap = new HashMap(); + try { + mem = sigar.getMem(); + memMap.putAll(mem.toMap()); + + // Swap Utilization + swap = sigar.getSwap(); + swapMap.putAll(swap.toMap()); + } catch(SigarException se){ + se.printStackTrace(); +// log.error("SigarException caused during collection of Memory utilization"); +// log.error(ExceptionUtils.getStackTrace(se)); + } finally { + map.put("memory", memMap); + map.put("swap", swapMap); + } + + // Network Utilization + List netInterfaces = new ArrayList(); + try { + netIf = sigar.getNetInterfaceList(); + for (int i = 0; i < netIf.length; i++) { + NetInterfaceStat net = new NetInterfaceStat(); + try { + net = sigar.getNetInterfaceStat(netIf[i]); + } catch(SigarException e){ + // Ignore the exception when trying to stat network interface + System.out.println("SigarException trying to stat network device "+netIf[i]); + //log.warn("SigarException trying to stat network device "+netIf[i]); + continue; + } + Map netMap = new HashMap(); + netMap.putAll(net.toMap()); + if(previousNetworkStats.containsKey(netIf[i])) { + Map deltaMap = previousNetworkStats.get(netIf[i]); + deltaMap.put("RxBytes", Long.parseLong(netMap.get("RxBytes").toString()) - Long.parseLong(deltaMap.get("RxBytes").toString())); + deltaMap.put("RxDropped", Long.parseLong(netMap.get("RxDropped").toString()) - Long.parseLong(deltaMap.get("RxDropped").toString())); + deltaMap.put("RxErrors", Long.parseLong(netMap.get("RxErrors").toString()) - Long.parseLong(deltaMap.get("RxErrors").toString())); + deltaMap.put("RxPackets", Long.parseLong(netMap.get("RxPackets").toString()) - Long.parseLong(deltaMap.get("RxPackets").toString())); + deltaMap.put("TxBytes", Long.parseLong(netMap.get("TxBytes").toString()) - Long.parseLong(deltaMap.get("TxBytes").toString())); + deltaMap.put("TxCollisions", Long.parseLong(netMap.get("TxCollisions").toString()) - Long.parseLong(deltaMap.get("TxCollisions").toString())); + deltaMap.put("TxErrors", Long.parseLong(netMap.get("TxErrors").toString()) - Long.parseLong(deltaMap.get("TxErrors").toString())); + deltaMap.put("TxPackets", Long.parseLong(netMap.get("TxPackets").toString()) - Long.parseLong(deltaMap.get("TxPackets").toString())); + netInterfaces.add(deltaMap); + skip = false; + } else { + netInterfaces.add(netMap); + skip = true; + } + previousNetworkStats.put(netIf[i], netMap); + } + } catch(SigarException se){ + se.printStackTrace(); +// log.error("SigarException caused during collection of Network utilization"); +// log.error(ExceptionUtils.getStackTrace(se)); + } finally { + map.put("network", netInterfaces); + } + + // Filesystem Utilization + List fsList = new ArrayList(); + try { + fs = sigar.getFileSystemList(); + for (int i = 0; i < fs.length; i++) { + FileSystemUsage usage = sigar.getFileSystemUsage(fs[i].getDirName()); + Map fsMap = new HashMap(); + fsMap.putAll(fs[i].toMap()); + fsMap.put("ReadBytes", usage.getDiskReadBytes()); + fsMap.put("Reads", usage.getDiskReads()); + fsMap.put("WriteBytes", usage.getDiskWriteBytes()); + fsMap.put("Writes", usage.getDiskWrites()); + if(previousDiskStats.containsKey(fs[i].getDevName())) { + Map deltaMap = previousDiskStats.get(fs[i].getDevName()); + deltaMap.put("ReadBytes", usage.getDiskReadBytes() - (Long) deltaMap.get("ReadBytes")); + deltaMap.put("Reads", usage.getDiskReads() - (Long) deltaMap.get("Reads")); + deltaMap.put("WriteBytes", usage.getDiskWriteBytes() - (Long) deltaMap.get("WriteBytes")); + deltaMap.put("Writes", usage.getDiskWrites() - (Long) deltaMap.get("Writes")); + deltaMap.put("Total", usage.getTotal()); + deltaMap.put("Used", usage.getUsed()); + deltaMap.putAll(fs[i].toMap()); + fsList.add(deltaMap); + skip = false; + } else { + fsList.add(fsMap); + skip = true; + } + previousDiskStats.put(fs[i].getDevName(), fsMap); + } + } catch(SigarException se){ + se.printStackTrace(); +// log.error("SigarException caused during collection of FileSystem utilization"); +// log.error(ExceptionUtils.getStackTrace(se)); + } finally { + map.put("disk", fsList); + } + map.put("timestamp", System.currentTimeMillis()); + + + //byte[] data = map.toString().getBytes(); + +// sendOffset += data.length; +// ChunkImpl c = new ChunkImpl("SystemMetrics", "Sigar", sendOffset, data, systemMetrics); +// if(!skip) { +// receiver.add(c); +// } + } catch (Exception se) { + se.printStackTrace(); + //log.error(ExceptionUtil.getStackTrace(se)); + } + } + +} diff --git a/scouter.agent.java/src/scouter/agent/counter/task/FDInfo.java b/scouter.agent.java/src/scouter/agent/counter/task/FDInfo.java new file mode 100644 index 000000000..5690c8622 --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/counter/task/FDInfo.java @@ -0,0 +1,64 @@ +/* + * 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.agent.counter.task; + +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; + +import com.sun.management.UnixOperatingSystemMXBean; + +import scouter.agent.Logger; +import scouter.agent.counter.CounterBasket; +import scouter.agent.counter.anotation.Counter; +import scouter.lang.TimeTypeEnum; +import scouter.lang.counters.CounterConstants; +import scouter.lang.pack.PerfCounterPack; +import scouter.lang.value.ListValue; + +public class FDInfo { + + public static boolean availableFdInfo = true; + + @Counter + public void process(CounterBasket pw) { + if (availableFdInfo == false) { + return; + } + + // Currently supported only sun jvm on unix platform + try { + OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean(); + if(os instanceof UnixOperatingSystemMXBean){ + UnixOperatingSystemMXBean unixOs = (UnixOperatingSystemMXBean) os; + long max = unixOs.getMaxFileDescriptorCount(); + long open = unixOs.getOpenFileDescriptorCount(); + + ListValue fdUsage = new ListValue(); + fdUsage.add(max); + fdUsage.add(open); + + PerfCounterPack p = pw.getPack(TimeTypeEnum.REALTIME); + p.put(CounterConstants.JAVA_FD_USAGE, fdUsage); + } else { + availableFdInfo = false; + } + } catch (Throwable th) { + Logger.println(th.getMessage()); + availableFdInfo = false; + } + } +} diff --git a/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java b/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java index a29365a6b..c5ffb4aae 100644 --- a/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java +++ b/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java @@ -159,6 +159,13 @@ public static void reset() { apicall.clear(); methodName.clear(); sqlText.clear(); + referer.clear(); + userAgent.clear(); + descTable.clear(); + loginTable.clear(); + webNameTable.clear(); + groupAgent.clear(); + hashMessage.clear(); } public static void sendXLog(XLogPack p) { p.objHash = conf.getObjHash(); diff --git a/scouter.client/icons/refresh.png b/scouter.client/icons/refresh.png new file mode 100644 index 000000000..0de26566d Binary files /dev/null and b/scouter.client/icons/refresh.png differ diff --git a/scouter.client/icons/refresh_auto.png b/scouter.client/icons/refresh_auto.png index b4203bb34..293e3d380 100644 Binary files a/scouter.client/icons/refresh_auto.png and b/scouter.client/icons/refresh_auto.png differ diff --git a/scouter.client/src/scouter/client/Images.java b/scouter.client/src/scouter/client/Images.java index 7236253a4..2ae74a366 100644 --- a/scouter.client/src/scouter/client/Images.java +++ b/scouter.client/src/scouter/client/Images.java @@ -50,7 +50,7 @@ public class Images { public static final Image folder = Activator.getImage("icons/folder.png"); public static final Image folder_star = Activator.getImage("icons/folder_star.png"); - public static final Image refresh = Activator.getImage("icons/refresh.gif"); + public static final Image refresh = Activator.getImage("icons/refresh.png"); public static final Image refresh_auto = Activator.getImage("icons/refresh_auto.png"); public static final Image expand = Activator.getImage("icons/expand.png"); diff --git a/scouter.client/src/scouter/client/util/MenuUtil.java b/scouter.client/src/scouter/client/util/MenuUtil.java index 322e9a4fa..acb82878b 100644 --- a/scouter.client/src/scouter/client/util/MenuUtil.java +++ b/scouter.client/src/scouter/client/util/MenuUtil.java @@ -391,6 +391,7 @@ public static void createCounterContextMenu(final String id, Control control, fi final Counter counterObj = counterEngine.getObjectType(objType).getFamily().getCounter(counter); mgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager mgr) { + if (mgr == null) return; IWorkbenchWindow win = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (counterObj.isAll()) { Action act = new OpenRealTimeAllAction(win, "Current All", objType, counter, Images.all, serverId); @@ -504,6 +505,7 @@ public static void addObjTypeSpecialMenu(IWorkbenchWindow win, IMenuManager mgr, serviceGroupMgr.add(new OpenServiceGroupElapsedAction(win, serverId, objType)); mgr.add(new OpenUniqueTotalVisitorAction(win, serverId, objType)); mgr.add(new OpenTypeSummaryAction(win, serverId, objType)); + mgr.add(new OpenRTPairAllAction(win, "File Descriptor", serverId, objType, CounterConstants.JAVA_FD_USAGE)); } else if (counterEngine.isChildOf(objType, CounterConstants.FAMILY_DATASOURCE)) { mgr.add(new Separator()); mgr.add(new OpenRTPairAllAction2(win, "Pool Chart", serverId, objType, CounterConstants.DATASOURCE_CONN_MAX, CounterConstants.DATASOURCE_CONN_ACTIVE)); diff --git a/scouter.client/src/scouter/client/xlog/ImageCache.java b/scouter.client/src/scouter/client/xlog/ImageCache.java index 878a0a7bf..19a62924f 100644 --- a/scouter.client/src/scouter/client/xlog/ImageCache.java +++ b/scouter.client/src/scouter/client/xlog/ImageCache.java @@ -32,7 +32,6 @@ public class ImageCache { private static ImageCache instance; private Map xLogDotMap = new HashMap(); - private Map objectDotMap = new HashMap(); private Image errorXpDot = null; public synchronized static ImageCache getInstance() { @@ -101,20 +100,6 @@ public synchronized Image getXPErrorImage() { return errorXpDot; } - public synchronized Image getObjectImage(int objHash) { - Color agentColor = AgentColorManager.getInstance().getColor(objHash); - if (agentColor == null) { - agentColor = ColorUtil.getInstance().getColor("gray"); - } - RGB rgb = agentColor.getRGB(); - Image dot = objectDotMap.get(rgb); - if (dot == null) { - dot = createObjectImage(rgb); - objectDotMap.put(rgb, dot); - } - return dot; - } - private Image createObjectImage(RGB rgb) { Image xp = new Image(null, 3, 3); GC gcc = new GC(xp); diff --git a/scouter.common/src/scouter/lang/counters/CounterConstants.java b/scouter.common/src/scouter/lang/counters/CounterConstants.java index 2bd3ef617..ba370ec3c 100644 --- a/scouter.common/src/scouter/lang/counters/CounterConstants.java +++ b/scouter.common/src/scouter/lang/counters/CounterConstants.java @@ -68,6 +68,7 @@ public class CounterConstants { public final static String JAVA_PERM_USED = "PermUsed"; public final static String JAVA_PERM_PERCENT = "PermPercent"; public final static String JAVA_PROCESS_CPU = "ProcCpu"; + public final static String JAVA_FD_USAGE = "FdUsage"; public final static String REQUESTPROCESS_BYTES_RECEIVED = "BytesReceived"; public final static String REQUESTPROCESS_BYTES_SENT = "BytesSent"; @@ -112,6 +113,12 @@ public class CounterConstants { public final static String HOST_TCPSTAT_FIN = "TcpStatFIN"; public final static String HOST_TCPSTAT_EST = "TcpStatEST"; + public final static String HOST_NET_RX_BYTES = "NetRxBytes"; + public final static String HOST_NET_TX_BYTES = "NetTxBytes"; + + public final static String HOST_DISK_READ_BYTES = "DiskReadBytes"; + public final static String HOST_DISK_WRITE_BYTES = "DiskWriteBytes"; + public final static String REAL_TIME_ALL = "rt-all"; public final static String REAL_TIME_TOTAL = "rt-tot"; public final static String TODAY_ALL = "td-all"; diff --git a/scouter.common/src/scouter/lang/counters/counters.xml b/scouter.common/src/scouter/lang/counters/counters.xml index 83cbe13ff..18a58a85c 100644 --- a/scouter.common/src/scouter/lang/counters/counters.xml +++ b/scouter.common/src/scouter/lang/counters/counters.xml @@ -46,6 +46,7 @@ mrhit : MariaDB HitRatio + diff --git a/scouter.common/src/scouter/lang/pack/MapPack.java b/scouter.common/src/scouter/lang/pack/MapPack.java index f1ac49070..cbd85567c 100644 --- a/scouter.common/src/scouter/lang/pack/MapPack.java +++ b/scouter.common/src/scouter/lang/pack/MapPack.java @@ -112,6 +112,10 @@ public Value put(String key, String value) { public Value put(String key, long value) { return put(key, new DecimalValue(value)); } + + public Value put(String key, boolean value) { + return put(key, new BooleanValue(value)); + } public Value remove(String key) { return (Value) table.remove(key); diff --git a/scouter.document/main/Plugin-Guide.md b/scouter.document/main/Plugin-Guide.md index b3742cb05..e6b8269b5 100644 --- a/scouter.document/main/Plugin-Guide.md +++ b/scouter.document/main/Plugin-Guide.md @@ -16,6 +16,7 @@ Scouter의 프로파일은 collector server에 적용 가능한 **server plugin* * **[scouter-plugin-server-null](https://github.com/scouter-project/scouter-plugin-server-null)** : 수집데이터를 단순히 출력해 주는 sample plugin * **[scouter-plugin-server-email](https://github.com/scouter-project/scouter-plugin-server-alert-email)** : Scouter에서 발생하는 alert를 email로 전송하는 plugin * **[scouter-plugin-server-telegram](https://github.com/scouter-project/scouter-plugin-server-alert-telegram)** : Scouter에서 발생하는 alert를 telegram으로 전송하는 plugin +* **[scouter-plugin-server-slack](https://github.com/scouter-project/scouter-plugin-server-alert-slack)** : Scouter에서 발생하는 alert를 slack으로 전송하는 plugin * **[scouter-plugin-server-influxdb](https://github.com/scouter-project/scouter-plugin-server-influxdb)** : Scouter의 성능 counter 데이터를 시계열 DB인 influxDB로 연동하는 plugin #### 2. agent plugins diff --git a/scouter.document/main/Plugin-Guide_kr.md b/scouter.document/main/Plugin-Guide_kr.md index cbd92cc89..d700281f9 100644 --- a/scouter.document/main/Plugin-Guide_kr.md +++ b/scouter.document/main/Plugin-Guide_kr.md @@ -16,6 +16,7 @@ Scouter의 프로파일은 collector server에 적용 가능한 **server plugin* * **[scouter-plugin-server-null](https://github.com/scouter-project/scouter-plugin-server-null)** : 수집데이터를 단순히 출력해 주는 sample plugin * **[scouter-plugin-server-email](https://github.com/scouter-project/scouter-plugin-server-alert-email)** : Scouter에서 발생하는 alert를 email로 전송하는 plugin * **[scouter-plugin-server-telegram](https://github.com/scouter-project/scouter-plugin-server-alert-telegram)** : Scouter에서 발생하는 alert를 telegram으로 전송하는 plugin +* **[scouter-plugin-server-slack](https://github.com/scouter-project/scouter-plugin-server-alert-slack)** : Scouter에서 발생하는 alert를 slack으로 전송하는 plugin * **[scouter-plugin-server-influxdb](https://github.com/scouter-project/scouter-plugin-server-influxdb)** : Scouter의 성능 counter 데이터를 시계열 DB인 influxDB로 연동하는 plugin #### 2. agent plugins diff --git a/scouter.document/main/What-special-in-SCOUTER_kr.md b/scouter.document/main/What-special-in-SCOUTER_kr.md index 3a34d866a..5d17f25c6 100644 --- a/scouter.document/main/What-special-in-SCOUTER_kr.md +++ b/scouter.document/main/What-special-in-SCOUTER_kr.md @@ -1,4 +1,4 @@ -# What special in SOUTER +# SCOUTER가 특별한 이유 [![Englsh](https://img.shields.io/badge/language-English-red.svg)](What-special-in-SCOUTER.md) ![Korean](https://img.shields.io/badge/language-Korean-blue.svg) Scouter 는 무엇인가? @@ -14,16 +14,15 @@ SaaS 형은 설치가 필요없기에 쉽게 사용할 수 있는 반면, Scoute Scouter Client 는 Eclipse RCP Platform 으로 만들어지 독립 클라이언트이다. 그래서 웹형 뷰어보다 많은 성능 데이터를 제어할 수 있다. ## Scouter 파일 DB에 성능 데이터를 저장 - -Scouter wants to collect bigger data and analyze each service transaction(request). -so Scouter should control a lot of data. That’s why SCOUTER save service performance and profile data on compressed files. +Scouter는 빅 데이터 를 수집하고 각 서비스의 트랜잭션(요청)을 분석하기를 원합니다. +그래서 Scouter는 대량의 데이터를 제어 해야 합니다. Scouter가 압축된 파일 서비스 성능 및 프로파일 데이터 를 저장 하는 이유 입니다. ## 타겟 시스템에 대한 개별 요청을 추적 -Every service call is individually traced(profiled) and saved it. -It is possible with the compressed archiving and standalone clients. +모든 서비스 콜은 개별적으로 추적(프로파일링)하고 그것을 저장 합니다. +이것은 압축된 아카이브 및 독립 클라이언트에서 가능합니다. ## Scouter 진행중인 스택덤프를 분석한다. -Sometimes it is not clear to understand the performance problem in a separate thread information. -At that time, we have to think about different way. If we collect full thread stacks in many times and analyze the stacks together, we could get an another chance to solve the performance problem. -(coming soon) +때로는 다른 스레드 정보에서 성능 문제를 이해하는 것은 분명 아닙니다. +그 때는 다른 방법을 생각해야 합니다. 여러 번 전체 스레드 스택을 수집하고 함께 스택을 분석 할 경우, +우리는 성능 문제를 해결 하기위한 또 다른 기회를 얻을 수 있습니다.(출시 예정) diff --git a/scouter.server/src/scouter/server/core/PerfCountCore.scala b/scouter.server/src/scouter/server/core/PerfCountCore.scala index ce1af2cd0..bddc88343 100644 --- a/scouter.server/src/scouter/server/core/PerfCountCore.scala +++ b/scouter.server/src/scouter/server/core/PerfCountCore.scala @@ -43,8 +43,8 @@ object PerfCountCore { PlugInManager.counter(counterPack); if (counterPack.timetype == TimeTypeEnum.REALTIME) { - counterPack.data.put(CounterConstants.COMMON_OBJHASH, new DecimalValue(objHash)) //add objHash into datafile - counterPack.data.put(CounterConstants.COMMON_TIME, new DecimalValue(counterPack.time)) //add objHash into datafile + //counterPack.data.put(CounterConstants.COMMON_OBJHASH, new DecimalValue(objHash)) //add objHash into datafile + //counterPack.data.put(CounterConstants.COMMON_TIME, new DecimalValue(counterPack.time)) //add objHash into datafile RealtimeCounterWR.add(counterPack); EnumerScala.foreach(counterPack.data.keySet().iterator(), (k: String) => { @@ -67,13 +67,6 @@ object PerfCountCore { } def add(p: PerfCounterPack) { - if (p.time == 0) { - p.time = System.currentTimeMillis(); - } - if (p.timetype == 0) { - p.timetype = TimeTypeEnum.REALTIME; - } - val ok = queue.put(p); if (!ok) { Logger.println("S109", 10, "queue exceeded!!"); diff --git a/scouter.server/src/scouter/server/netio/data/NetDataProcessor.scala b/scouter.server/src/scouter/server/netio/data/NetDataProcessor.scala index 3c5945886..687b343af 100644 --- a/scouter.server/src/scouter/server/netio/data/NetDataProcessor.scala +++ b/scouter.server/src/scouter/server/netio/data/NetDataProcessor.scala @@ -17,8 +17,10 @@ */ package scouter.server.netio.data import java.net.InetAddress + import scouter.io.DataInputX -import scouter.lang.TextTypes +import scouter.lang.{TextTypes, TimeTypeEnum} +import scouter.lang.counters.CounterConstants import scouter.lang.pack.AlertPack import scouter.lang.pack.ObjectPack import scouter.lang.pack.Pack @@ -42,12 +44,11 @@ import scouter.server.core.StatusCore import scouter.server.core.TextCore import scouter.server.core.cache.TextCache import scouter.server.util.ThreadScala -import scouter.util.BytesUtil -import scouter.util.RequestQueue -import scouter.util.StringUtil +import scouter.util.{BytesUtil, HashUtil, RequestQueue, StringUtil} import scouter.server.core.SummaryCore import scouter.lang.pack.SummaryPack import scouter.lang.pack.SummaryPack +import scouter.lang.value.DecimalValue object NetDataProcessor { class NetData(_data: Array[Byte], _addr: InetAddress) { val addr = _addr @@ -142,7 +143,18 @@ object NetDataProcessor { } p.getPackType() match { case PackEnum.PERF_COUNTER => - PerfCountCore.add(p.asInstanceOf[PerfCounterPack]) + val counterPack = p.asInstanceOf[PerfCounterPack] + val objHash = HashUtil.hash(counterPack.objName) + if (counterPack.time == 0) { + counterPack.time = System.currentTimeMillis(); + } + if (counterPack.timetype == 0) { + counterPack.timetype = TimeTypeEnum.REALTIME; + } + counterPack.data.put(CounterConstants.COMMON_OBJHASH, new DecimalValue(objHash)) //add objHash into datafile + counterPack.data.put(CounterConstants.COMMON_TIME, new DecimalValue(counterPack.time)) //add objHash into datafile + + PerfCountCore.add(counterPack) if (conf.log_udp_counter) { System.out.println("DEBUG UDP COUNTER: " + p) }