diff --git a/README.md b/README.md index fbd176937..c39af958f 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,9 @@ Scouter has three modules: ## How to contribute - **Notice** : Pull request to **dev branch** only allowed. - - Please check the development guide below + - Refer to the development guide below. - [Scouter developer guide](./scouter.document/tech/Developer-Guide.md) - + - Please note that you will have to complete a [CLA](http://goo.gl/forms/xSmYs8qM9J) for your first pull-request. ## Q&A diff --git a/README_kr.md b/README_kr.md index 2ffa246d3..92af1a915 100644 --- a/README_kr.md +++ b/README_kr.md @@ -70,6 +70,7 @@ APM은 Application performance montoring 또는 application performance manageme - **Pull request**는 반드시 **dev branch**로 요청하여야 합니다. - 상세한 내용은 개발자 가이드를 참조하시기 바랍니다. - [Scouter 개발자 가이드](./scouter.document/tech/Developer-Guide_kr.md) + - 최초 Pull-Request시 다음 [CLA](http://goo.gl/forms/xSmYs8qM9J)(Contributor License Agreement)에 서명하여 제출하여야 합니다. ## Q&A - [Google Groups](https://groups.google.com/forum/#!forum/scouter-project) diff --git a/scouter.agent.host/src/scouter/agent/Configure.java b/scouter.agent.host/src/scouter/agent/Configure.java index d30ecdb58..5f29ecda2 100644 --- a/scouter.agent.host/src/scouter/agent/Configure.java +++ b/scouter.agent.host/src/scouter/agent/Configure.java @@ -92,7 +92,7 @@ public final static synchronized Configure getInstance() { public int cpu_fatal_history = 3; //Memory - public boolean mem_alert_enabled = true; + public boolean mem_alert_enabled = false; public long mem_alert_interval_ms = 30000; public int mem_warning_pct = 80; public int mem_fatal_pct = 90; @@ -216,7 +216,7 @@ private void apply() { this.cpu_warning_history = getInt("cpu_warning_history", 3); this.cpu_fatal_history = getInt("cpu_fatal_history", 3); - this.mem_alert_enabled = getBoolean("mem_alert_enabled", true); + this.mem_alert_enabled = getBoolean("mem_alert_enabled", false); this.mem_alert_interval_ms = getLong("mem_alert_interval_ms", 30000); this.mem_warning_pct = getInt("mem_warning_pct", 80); this.mem_fatal_pct = getInt("mem_fatal_pct", 90); 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/Configure.java b/scouter.agent.java/src/scouter/agent/Configure.java index 84a86acbb..b4b8c5571 100644 --- a/scouter.agent.java/src/scouter/agent/Configure.java +++ b/scouter.agent.java/src/scouter/agent/Configure.java @@ -156,8 +156,8 @@ public final static synchronized Configure getInstance() { public String log_dir =""; public boolean log_rotation_enabled =true; public int log_keep_days =7; - public boolean _log_trace_enabled = false; - public boolean _log_trace_use_logger = false; + public boolean _trace = false; + public boolean _trace_use_logger = false; //Hook public String hook_args_patterns = ""; @@ -168,6 +168,7 @@ public final static synchronized Configure getInstance() { public String hook_method_patterns = ""; public String hook_method_ignore_prefixes = "get,set"; public String hook_method_ignore_classes = ""; + public String hook_method_exclude_patterns = ""; private StringSet _hook_method_ignore_classes = new StringSet(); public boolean hook_method_access_public_enabled = true; public boolean hook_method_access_private_enabled = false; @@ -376,6 +377,7 @@ private void apply() { this.profile_connection_open_enabled = getBoolean("profile_connection_open_enabled", true); this._summary_connection_leak_fullstack_enabled = getBoolean("_summary_connection_leak_fullstack_enabled", false); this.hook_method_patterns = getValue("hook_method_patterns", ""); + this.hook_method_exclude_patterns = getValue("hook_method_exclude_patterns", ""); this.hook_method_access_public_enabled = getBoolean("hook_method_access_public_enabled", true); this.hook_method_access_protected_enabled = getBoolean("hook_method_access_protected_enabled", false); this.hook_method_access_private_enabled = getBoolean("hook_method_access_private_enabled", false); @@ -503,8 +505,8 @@ private void apply() { this.log_dir = getValue("log_dir", ""); this.log_rotation_enabled = getBoolean("log_rotation_enabled", true); this.log_keep_days = getInt("log_keep_days", 7); - this._log_trace_enabled = getBoolean("_log_trace_enabled", false); - this._log_trace_use_logger = getBoolean("_log_trace_use_logger", false); + this._trace = getBoolean("_trace", false); + this._trace_use_logger = getBoolean("_trace_use_logger", false); this.enduser_trace_endpoint_url = getValue("enduser_trace_endpoint_url", "_scouter_browser.jsp"); this.enduser_perf_endpoint_hash = HashUtil.hash(this.enduser_trace_endpoint_url); diff --git a/scouter.agent.java/src/scouter/agent/Logger.java b/scouter.agent.java/src/scouter/agent/Logger.java index 7beec9f43..5a98cb7b7 100644 --- a/scouter.agent.java/src/scouter/agent/Logger.java +++ b/scouter.agent.java/src/scouter/agent/Logger.java @@ -45,8 +45,8 @@ public static void println(String id, String message, Throwable t) { } public static void trace(Object message) { - if(conf._log_trace_enabled) { - if(conf._log_trace_use_logger) { + if(conf._trace) { + if(conf._trace_use_logger) { println(build("SCOUTER-TRC", toString(message)), true); } else { System.out.println(build("SCOUTER-TRC", toString(message))); diff --git a/scouter.agent.java/src/scouter/agent/asm/MethodASM.java b/scouter.agent.java/src/scouter/agent/asm/MethodASM.java index 758321fe3..ed8a45dfb 100644 --- a/scouter.agent.java/src/scouter/agent/asm/MethodASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/MethodASM.java @@ -17,20 +17,25 @@ package scouter.agent.asm; +import java.util.List; + import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.asm.util.AsmUtil; import scouter.agent.asm.util.HookingSet; import scouter.agent.netio.data.DataProxy; import scouter.agent.trace.TraceMain; -import scouter.org.objectweb.asm.*; +import scouter.org.objectweb.asm.ClassVisitor; +import scouter.org.objectweb.asm.Label; +import scouter.org.objectweb.asm.MethodVisitor; +import scouter.org.objectweb.asm.Opcodes; +import scouter.org.objectweb.asm.Type; import scouter.org.objectweb.asm.commons.LocalVariablesSorter; -import java.util.List; - public class MethodASM implements IASM, Opcodes { private List target = HookingSet.getHookingMethodSet(Configure.getInstance().hook_method_patterns); + private List excludeTarget = HookingSet.getHookingMethodSet(Configure.getInstance().hook_method_exclude_patterns); Configure conf = Configure.getInstance(); @@ -47,7 +52,7 @@ public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc class for (int i = 0; i < target.size(); i++) { HookingSet mset = target.get(i); if (mset.classMatch.include(className)) { - return new MethodCV(cv, mset, className); + return new MethodCV(cv, mset, excludeTarget, className); } } return cv; @@ -58,10 +63,12 @@ class MethodCV extends ClassVisitor implements Opcodes { public String className; private HookingSet mset; + private List excludeTarget; - public MethodCV(ClassVisitor cv, HookingSet mset, String className) { + public MethodCV(ClassVisitor cv, HookingSet mset, List excludeTarget, String className) { super(ASM4, cv); this.mset = mset; + this.excludeTarget = excludeTarget; this.className = className; } @@ -74,6 +81,16 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si if (AsmUtil.isSpecial(name)) { return mv; } + + // check exclude method set + for (int i = 0; i < excludeTarget.size(); i++) { + HookingSet excludeSet = excludeTarget.get(i); + if (excludeSet.classMatch.include(className)) { + if (excludeSet.isA(name, desc)) { + return mv; + } + } + } Configure conf = Configure.getInstance(); boolean isPublic = conf.hook_method_access_public_enabled; diff --git a/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java b/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java index 8c3a1fa6f..1436be71f 100644 --- a/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java +++ b/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java @@ -79,7 +79,7 @@ public int get(String method, String desc) { public static Map getHookingSet(String arg) { String[] c = StringUtil.split(arg, ','); - Map classSet = new HashMap(); + Map classMap = new HashMap(); for (int i = 0; i < c.length; i++) { String s = c[i]; int x = s.lastIndexOf("."); @@ -88,14 +88,14 @@ public static Map getHookingSet(String arg) { String cname = s.substring(0, x).replace('.', '/'); String mname = s.substring(x + 1); - HookingSet methodSet = classSet.get(cname); + HookingSet methodSet = classMap.get(cname); if (methodSet == null) { methodSet = new HookingSet(); - classSet.put(cname, methodSet); + classMap.put(cname, methodSet); } methodSet.add(mname); } - return classSet; + return classMap; } public static List getHookingMethodSet(String patterns) { 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/counter/task/ServicePerf.java b/scouter.agent.java/src/scouter/agent/counter/task/ServicePerf.java index 383c30030..eeae65e49 100644 --- a/scouter.agent.java/src/scouter/agent/counter/task/ServicePerf.java +++ b/scouter.agent.java/src/scouter/agent/counter/task/ServicePerf.java @@ -40,6 +40,7 @@ public class ServicePerf { private MeterResource activeCounter = new MeterResource(); + private Configure conf = Configure.getInstance(); @Counter public void getServicePerf(CounterBasket pw) { @@ -108,6 +109,11 @@ public void getServicePerf(CounterBasket pw) { public void summay(CounterBasket pw) { long time = System.currentTimeMillis(); long now = DateUtil.getMinUnit(time) / 5; + + if(conf.getBoolean("_dev_summary_test", false)) { + now = time / 1000 / 15; + } + if (now == last_sent) return; last_sent = now; diff --git a/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java b/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java index 22140dcf6..3f80f2996 100644 --- a/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java +++ b/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java @@ -21,8 +21,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; + import javax.management.MBeanServer; import javax.management.ObjectName; + import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.ObjTypeDetector; @@ -85,7 +87,6 @@ public boolean equals(Object obj) { } } private MBeanServer server; - private String version; List beanList = new ArrayList(); public long collectCnt = 0; @Counter @@ -147,18 +148,6 @@ private void getMBeanList() { if (type == null) { continue; } - if (StringUtil.isEmpty(version) && "Server".equals(type)) { // Server - // Bean - try { - Object value = server.getAttribute(mbean, "serverInfo"); - if (value != null) { - version = value.toString().split("/")[1]; - Logger.println("Tomcat version = " + version); - } - } catch (Exception e) { - e.printStackTrace(); - } - } if ("GlobalRequestProcessor".equals(type)) { String port = mbean.getKeyProperty("name"); try { 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.agent.java/src/scouter/agent/trace/TraceSQL.java b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java index 7fd5e944f..266d86f86 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java @@ -243,7 +243,7 @@ public static void end(Object stat, Throwable thr, int updatedCount) { LocalContext lCtx = (LocalContext) stat; TraceContext tCtx = lCtx.context; - Logger.trace("affected row = " + updatedCount); + //Logger.trace("affected row = " + updatedCount); SqlStep3 step = (SqlStep3) lCtx.stepSingle; tCtx.lastSqlStep = step; diff --git a/scouter.agent.java/src/scouter/agent/util/AsyncRunner.java b/scouter.agent.java/src/scouter/agent/util/AsyncRunner.java index a352753a0..d10da3faf 100644 --- a/scouter.agent.java/src/scouter/agent/util/AsyncRunner.java +++ b/scouter.agent.java/src/scouter/agent/util/AsyncRunner.java @@ -146,7 +146,7 @@ private void alert(LeakInfo2 leakInfo2) { } DataProxy.sendAlert(AlertLevel.WARN, "CONNECTION_NOT_CLOSE", "Connection may not closed", mv); - if(conf._log_trace_enabled) Logger.trace("[Force-Close-InnerObject]" + System.identityHashCode(leakInfo2.innerObject)); + if(conf._trace) Logger.trace("[Force-Close-InnerObject]" + System.identityHashCode(leakInfo2.innerObject)); boolean closeResult = leakInfo2.closeManager.close(leakInfo2.innerObject); //Logger.println("G003", "connection auto closed:" + closeResult); 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/ApplicationWorkbenchWindowAdvisor.java b/scouter.client/src/scouter/client/ApplicationWorkbenchWindowAdvisor.java index b8ae1d555..cb6fb4e3e 100644 --- a/scouter.client/src/scouter/client/ApplicationWorkbenchWindowAdvisor.java +++ b/scouter.client/src/scouter/client/ApplicationWorkbenchWindowAdvisor.java @@ -33,6 +33,7 @@ import scouter.Version; import scouter.client.net.LoginMgr; +import scouter.client.net.LoginResult; import scouter.client.popup.LoginDialog; import scouter.client.popup.LoginDialog.ILoginDialog; import scouter.client.preferences.PreferenceConstants; @@ -119,8 +120,8 @@ public void preWindowOpen() { if (index > -1) { String id = accountInfo.substring(0, index); String pwd = accountInfo.substring(index + 1, accountInfo.length()); - boolean result = LoginMgr.silentLogin(server, id, pwd); - if (result) { + LoginResult result = LoginMgr.silentLogin(server, id, pwd); + if (result.success) { autoLogined = true; } } 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/context/actions/OpenServerAction.java b/scouter.client/src/scouter/client/context/actions/OpenServerAction.java index 4fa2a0fd8..dffef611e 100644 --- a/scouter.client/src/scouter/client/context/actions/OpenServerAction.java +++ b/scouter.client/src/scouter/client/context/actions/OpenServerAction.java @@ -21,13 +21,12 @@ import org.eclipse.jface.action.Action; import org.eclipse.swt.widgets.Display; -import scouter.client.Images; import scouter.client.net.LoginMgr; +import scouter.client.net.LoginResult; import scouter.client.popup.LoginDialog; import scouter.client.server.Server; import scouter.client.server.ServerManager; import scouter.client.util.ConsoleProxy; -import scouter.client.util.ImageUtil; import scouter.util.StringUtil; @@ -44,9 +43,9 @@ public OpenServerAction(int serverId) { public void run() { Server server = ServerManager.getInstance().getServer(serverId); if (StringUtil.isNotEmpty(server.getUserId()) && StringUtil.isNotEmpty(server.getPassword())) { - boolean result = LoginMgr.silentLogin(server, server.getUserId(), server.getPassword()); - if (result == false) { - ConsoleProxy.errorSafe("Failed opening server"); + LoginResult result = LoginMgr.silentLogin(server, server.getUserId(), server.getPassword()); + if (result.success == false) { + ConsoleProxy.errorSafe(result.getErrorMessage()); } } else { LoginDialog dialog = new LoginDialog(Display.getDefault(), null, LoginDialog.TYPE_OPEN_SERVER, server.getIp() + ":" + server.getPort()); diff --git a/scouter.client/src/scouter/client/net/LoginMgr.java b/scouter.client/src/scouter/client/net/LoginMgr.java index 40e4fa312..73bbfebee 100644 --- a/scouter.client/src/scouter/client/net/LoginMgr.java +++ b/scouter.client/src/scouter/client/net/LoginMgr.java @@ -31,13 +31,14 @@ import scouter.util.SysJMX; public class LoginMgr{ - public static boolean login(int serverId, String user, String password){ + public static LoginResult login(int serverId, String user, String password){ Server server = ServerManager.getInstance().getServer(serverId); - String encrypted = CipherUtil.md5(password); + String encrypted = CipherUtil.sha256(password); return silentLogin(server, user, encrypted); } - public static boolean silentLogin(Server server, String user, String encryptedPwd){ + public static LoginResult silentLogin(Server server, String user, String encryptedPwd){ + LoginResult result = new LoginResult(); try { MapPack param = new MapPack(); param.put("id", user); @@ -46,12 +47,16 @@ public static boolean silentLogin(Server server, String user, String encryptedPw param.put("hostname", SysJMX.getHostName()); MapPack out = TcpProxy.loginProxy(server.getId(), param); - - if (out != null) { + if (out == null) { + result.success = false; + result.errorMessage = "Network connection failed"; + } else { long session = out.getLong("session"); String error = out.getText("error"); if(error != null && session == 0L){ - return false; + result.success = false; + result.errorMessage = "Authentication failed"; + return result; } server.setOpen(true); long time = out.getLong("time"); @@ -93,12 +98,14 @@ public static boolean silentLogin(Server server, String user, String encryptedPw counterEngine.parse(((BlobValue)v1).value); } } - return true; + result.success = true; } } catch(Exception e){ e.printStackTrace(); + result.success = false; + result.errorMessage = "Network connection failed : " + e.getMessage(); } - return false; + return result; } public static MapPack getCounterXmlServer(int serverId) { diff --git a/scouter.client/src/scouter/client/net/LoginResult.java b/scouter.client/src/scouter/client/net/LoginResult.java new file mode 100644 index 000000000..f3e680f95 --- /dev/null +++ b/scouter.client/src/scouter/client/net/LoginResult.java @@ -0,0 +1,17 @@ +package scouter.client.net; + +import scouter.util.StringUtil; + +public class LoginResult { + + public boolean success; + public String errorMessage; + + public String getErrorMessage() { + if (!success && StringUtil.isEmpty(errorMessage)) { + return "Failure to unknown causes"; + } + return errorMessage; + } + +} diff --git a/scouter.client/src/scouter/client/popup/AccountDialog.java b/scouter.client/src/scouter/client/popup/AccountDialog.java index 335262915..b9dc76d16 100644 --- a/scouter.client/src/scouter/client/popup/AccountDialog.java +++ b/scouter.client/src/scouter/client/popup/AccountDialog.java @@ -317,7 +317,7 @@ public void run() { try { MapPack param = new MapPack(); param.put("id", id); - param.put("pass", CipherUtil.md5(password)); + param.put("pass", CipherUtil.sha256(password)); param.put("email", email); param.put("group", selectedGroup); MapPack p = (MapPack) tcp.getSingle(RequestCmd.ADD_ACCOUNT, param); @@ -355,7 +355,7 @@ public void run() { try { MapPack param = new MapPack(); param.put("id", id); - param.put("pass", CipherUtil.md5(password)); + param.put("pass", CipherUtil.sha256(password)); param.put("email", email); param.put("group", selectedGroup); MapPack p = (MapPack) tcp.getSingle(RequestCmd.EDIT_ACCOUNT, param); diff --git a/scouter.client/src/scouter/client/popup/LoginDialog.java b/scouter.client/src/scouter/client/popup/LoginDialog.java index 2b1db71ac..e67eca326 100644 --- a/scouter.client/src/scouter/client/popup/LoginDialog.java +++ b/scouter.client/src/scouter/client/popup/LoginDialog.java @@ -46,12 +46,12 @@ import scouter.Version; import scouter.client.Activator; import scouter.client.net.LoginMgr; +import scouter.client.net.LoginResult; import scouter.client.preferences.ServerPrefUtil; import scouter.client.server.Server; import scouter.client.server.ServerManager; import scouter.client.util.UIUtil; import scouter.net.NetConstants; -import scouter.util.CipherUtil; import scouter.util.StringUtil; public class LoginDialog { @@ -320,7 +320,7 @@ public boolean loginInToServer(String address) { String addr[] = address.split(":"); ip = addr[0]; port = addr[1]; - msg("Logging in..." + address); + msg("Log in..." + address); ServerManager srvMgr = ServerManager.getInstance(); if (this.openType != TYPE_EDIT_SERVER && srvMgr.isRunningServer(ip, port)) { @@ -336,12 +336,12 @@ public boolean loginInToServer(String address) { existServer = true; } - boolean success = LoginMgr.login(server.getId(), id.getText(), pass.getText()); - if (success) { + LoginResult result = LoginMgr.login(server.getId(), id.getText(), pass.getText()); + if (result.success) { msg("Successfully log in to " + address); ServerPrefUtil.addServerAddr(address); if (autoLogin) { - ServerPrefUtil.addAutoLoginServer(address, id.getText(), CipherUtil.md5(pass.getText())); + ServerPrefUtil.addAutoLoginServer(address, id.getText(), server.getPassword()); } else { ServerPrefUtil.removeAutoLoginServer(address); } @@ -360,7 +360,7 @@ public boolean loginInToServer(String address) { if (existServer == false) { ServerManager.getInstance().removeServer(server.getId()); } - errMsg("Please check your ID/Password or network."); + errMsg(result.getErrorMessage()); msg(""); return false; } diff --git a/scouter.client/src/scouter/client/threads/SessionObserver.java b/scouter.client/src/scouter/client/threads/SessionObserver.java index 478d97aa4..92b4f1322 100644 --- a/scouter.client/src/scouter/client/threads/SessionObserver.java +++ b/scouter.client/src/scouter/client/threads/SessionObserver.java @@ -20,6 +20,7 @@ import java.util.Set; import scouter.client.net.LoginMgr; +import scouter.client.net.LoginResult; import scouter.client.server.Server; import scouter.client.server.ServerManager; import scouter.client.util.ConsoleProxy; @@ -53,11 +54,11 @@ public void run() { server.setSession(0); // reset session } if (/*server.isConnected() &&*/ server.getSession() == 0) { - boolean success = LoginMgr.silentLogin(server, server.getUserId(), server.getPassword()); - if (success) { + LoginResult result = LoginMgr.silentLogin(server, server.getUserId(), server.getPassword()); + if (result.success) { ConsoleProxy.infoSafe("Success re-login to " + server.getName()); } else { - ConsoleProxy.errorSafe("Failed re-login to " + server.getName()); + ConsoleProxy.errorSafe("Failed re-login to " + server.getName() + " : " + result.getErrorMessage()); } } } diff --git a/scouter.client/src/scouter/client/util/MenuUtil.java b/scouter.client/src/scouter/client/util/MenuUtil.java index 322e9a4fa..7bd57103a 100644 --- a/scouter.client/src/scouter/client/util/MenuUtil.java +++ b/scouter.client/src/scouter/client/util/MenuUtil.java @@ -113,6 +113,7 @@ import scouter.client.xlog.actions.OpenXLogLoadTimeAction; import scouter.client.xlog.actions.OpenXLogRealTimeAction; import scouter.lang.Counter; +import scouter.lang.ObjectType; import scouter.lang.counters.CounterConstants; import scouter.lang.counters.CounterEngine; import scouter.util.DateUtil; @@ -388,9 +389,12 @@ public static void createCounterContextMenu(final String id, Control control, fi MenuManager mgr = new MenuManager(); mgr.setRemoveAllWhenShown(true); final CounterEngine counterEngine = ServerManager.getInstance().getServer(serverId).getCounterEngine(); - final Counter counterObj = counterEngine.getObjectType(objType).getFamily().getCounter(counter); + ObjectType objectType = counterEngine.getObjectType(objType); + if (objectType == null) return; + final Counter counterObj = objectType.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 +508,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.common/src/scouter/util/CipherUtil.java b/scouter.common/src/scouter/util/CipherUtil.java index 65fa7c7ac..ecb968b8a 100644 --- a/scouter.common/src/scouter/util/CipherUtil.java +++ b/scouter.common/src/scouter/util/CipherUtil.java @@ -55,6 +55,32 @@ public static String md5(String plainText) { } return md5Text; + } + + public static String sha256(String plainText) { + String salt = "qwertyuiop!@#$%^&*()zxcvbnm,."; + String sha256Text = null; + if (plainText != null) { + try { + MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); + sha256.update(salt.getBytes()); + byte[] byteArray = plainText.getBytes(); + byte[] sha256Bytes = sha256.digest(byteArray); + StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < sha256Bytes.length; i++) { + if ((sha256Bytes[i] & 0xff) < 0x10) { + buf.append("0"); + } + buf.append(Long.toString(sha256Bytes[i] & 0xff, 16)); + } + + sha256Text = buf.toString(); + } catch (Throwable t) { + return plainText; + } + } + return sha256Text; } private static Key genKey() throws GeneralSecurityException { @@ -105,13 +131,15 @@ private static byte[] padding(byte[] src) { } public static void main(String[] args) { - String pwd = "admin"; + String pwd = "guest"; String md5 = md5(pwd); String cnd = encode(pwd); - String rtn = decode(cnd); + String rtn = decode(cnd); + String sha256 = sha256(pwd); System.out.println("'" + pwd + "'"); System.out.println("'" + md5 + "'"); System.out.println("'" + cnd + "'"); - System.out.println("'" + rtn + "'"); + System.out.println("'" + rtn + "'"); + System.out.println("'" + sha256 + "'"); } } \ No newline at end of file diff --git a/scouter.deploy/build.xml b/scouter.deploy/build.xml index d4b7cc69e..47b0ebfdf 100644 --- a/scouter.deploy/build.xml +++ b/scouter.deploy/build.xml @@ -4,7 +4,7 @@ - + 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/account/account.xml b/scouter.server/src/scouter/server/account/account.xml index f4adc2943..fc8a99632 100644 --- a/scouter.server/src/scouter/server/account/account.xml +++ b/scouter.server/src/scouter/server/account/account.xml @@ -1,10 +1,10 @@ - + admin@scouter.com - + guest@scouter.com \ No newline at end of file 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) }