diff --git a/scouter.agent.host/src/scouter/agent/Configure.java b/scouter.agent.host/src/scouter/agent/Configure.java index f04965641..33dab849a 100644 --- a/scouter.agent.host/src/scouter/agent/Configure.java +++ b/scouter.agent.host/src/scouter/agent/Configure.java @@ -26,7 +26,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Properties; -import java.util.Set; import scouter.Version; import scouter.agent.netio.data.DataProxy; @@ -39,7 +38,6 @@ import scouter.util.DateUtil; import scouter.util.FileUtil; import scouter.util.HashUtil; -import scouter.util.IntSet; import scouter.util.StringEnumer; import scouter.util.StringKeyLinkedMap; import scouter.util.StringSet; @@ -107,9 +105,9 @@ public final static synchronized Configure getInstance() { public int cpu_fatal_history = 3; public boolean mem_alert_enabled = true; - public long mem_alert_interval; - public int mem_warning_pct; - public int mem_fatal_pct; + public long mem_alert_interval = 30000; + public int mem_warning_pct = 80; + public int mem_fatal_pct = 90; private Configure() { Properties p = new Properties(); @@ -229,7 +227,7 @@ private void apply() { this.mem_alert_enabled = getBoolean("mem_alert_enabled", true); this.mem_alert_interval = getLong("mem_alert_interval", 30000); - this.mem_warning_pct = getInt("mem_warning_pct", 70); + 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/HostPerf.java b/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java index 57c47911a..616f72349 100644 --- a/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java +++ b/scouter.agent.host/src/scouter/agent/counter/task/HostPerf.java @@ -24,9 +24,7 @@ import scouter.lang.value.FloatValue; import scouter.util.FormatUtil; import scouter.util.LongEnumer; -import scouter.util.LongIntMap; import scouter.util.LongKeyLinkedMap; -import scouter.util.StringUtil; public class HostPerf { static int SLEEP_TIME = 2000; @@ -54,15 +52,16 @@ void domain(CounterBasket pw) throws SigarException { alertMem(m); long tmem = m.getTotal(); - long fmem = m.getFree(); - long umem = m.getUsed(); - float memrate = umem * 100.0f / tmem; + long fmem = m.getActualFree(); + long umem = m.getActualUsed(); + float memrate = (float) m.getUsedPercent(); Swap sw = sigar.getSwap(); long pagein = sw.getPageIn(); long pageout = sw.getPageOut(); long tswap = sw.getTotal(); long uswap = sw.getUsed(); + float swaprate = uswap * 100.0f / tswap; PerfCounterPack p = pw.getPack(conf.objName, TimeTypeEnum.REALTIME); p.put(CounterConstants.HOST_CPU, new FloatValue(cpu)); @@ -72,6 +71,7 @@ void domain(CounterBasket pw) throws SigarException { p.put(CounterConstants.HOST_MEM_AVALIABLE, new DecimalValue(fmem / 1024 / 1024)); p.put(CounterConstants.HOST_SWAP_PAGE_IN, new DecimalValue(pagein)); p.put(CounterConstants.HOST_SWAP_PAGE_OUT, new DecimalValue(pageout)); + p.put(CounterConstants.HOST_SWAP, new FloatValue(swaprate)); p.put(CounterConstants.HOST_SWAP_TOTAL, new DecimalValue(tswap / 1024 / 1024)); p.put(CounterConstants.HOST_SWAP_USED, new DecimalValue(uswap / 1024 / 1024)); @@ -109,10 +109,8 @@ private void alertMem(Mem m) { if(conf.mem_alert_enabled==false) return; - long tmem = m.getTotal(); - long fmem = m.getFree(); - long umem = m.getUsed(); - float memrate = umem * 100.0f / tmem; + long fmem = m.getActualFree(); + float memrate = (float) m.getUsedPercent(); long now = System.currentTimeMillis(); diff --git a/scouter.agent.java/src/scouter/agent/AgentBoot.java b/scouter.agent.java/src/scouter/agent/AgentBoot.java index bd8c7cfd9..715e06354 100644 --- a/scouter.agent.java/src/scouter/agent/AgentBoot.java +++ b/scouter.agent.java/src/scouter/agent/AgentBoot.java @@ -17,7 +17,7 @@ import scouter.agent.counter.CounterExecutingManager; import scouter.agent.netio.request.ReqestHandlingProxy; -import scouter.agent.plugin.PlugInLoader; +import scouter.agent.plugin.PluginLoader; import scouter.util.Hexa32; import scouter.util.KeyGen; import scouter.util.SysJMX; @@ -42,7 +42,7 @@ public synchronized static void boot() { long seed =System.currentTimeMillis() ^ (((long)SysJMX.getProcessPID())<<32); KeyGen.setSeed(seed); Logger.println("A100", "agent boot seed="+Hexa32.toString32(seed)); - PlugInLoader.getInstance(); + PluginLoader.getInstance(); } public static void main(String[] args) { boot(); diff --git a/scouter.agent.java/src/scouter/agent/Configure.java b/scouter.agent.java/src/scouter/agent/Configure.java index dafcd3c37..aff53bbc1 100644 --- a/scouter.agent.java/src/scouter/agent/Configure.java +++ b/scouter.agent.java/src/scouter/agent/Configure.java @@ -134,6 +134,7 @@ public final static synchronized Configure getInstance() { public int alert_message_length = 3000; public long alert_send_interval = 3000; + public int jdbc_fetch_max = 10000; public int sql_time_max = 30000; diff --git a/scouter.agent.java/src/scouter/agent/asm/CapArgsASM.java b/scouter.agent.java/src/scouter/agent/asm/CapArgsASM.java index 70f0a8426..bd1b0a622 100644 --- a/scouter.agent.java/src/scouter/agent/asm/CapArgsASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/CapArgsASM.java @@ -68,7 +68,8 @@ public CapArgsCV(ClassVisitor cv, MethodSet mset, String className) { } @Override - public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) { + public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, + String[] exceptions) { MethodVisitor mv = super.visitMethod(access, methodName, desc, signature, exceptions); if (mv == null || mset.isA(methodName, desc) == false) { return mv; @@ -85,7 +86,7 @@ public MethodVisitor visitMethod(int access, String methodName, String desc, Str class CapArgsMV extends LocalVariablesSorter implements Opcodes { private static final String CLASS = TraceMain.class.getName().replace('.', '/'); private static final String METHOD = "capArgs"; - private static final String SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V"; + private static final String SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V"; private Type[] paramTypes; private boolean isStatic; @@ -114,7 +115,6 @@ public void visitCode() { mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitVarInsn(Opcodes.ASTORE, arrVarIdx); - for (int i = 0; i < paramTypes.length; i++) { Type type = paramTypes[i]; mv.visitVarInsn(Opcodes.ALOAD, arrVarIdx); @@ -123,35 +123,38 @@ public void visitCode() { switch (type.getSort()) { case Type.BOOLEAN: mv.visitVarInsn(Opcodes.ILOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", + false); break; case Type.BYTE: mv.visitVarInsn(Opcodes.ILOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); break; case Type.CHAR: mv.visitVarInsn(Opcodes.ILOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", + false); break; case Type.SHORT: mv.visitVarInsn(Opcodes.ILOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); break; case Type.INT: mv.visitVarInsn(Opcodes.ILOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", + false); break; case Type.LONG: mv.visitVarInsn(Opcodes.LLOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); break; case Type.FLOAT: mv.visitVarInsn(Opcodes.FLOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); break; case Type.DOUBLE: mv.visitVarInsn(Opcodes.DLOAD, sidx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;",false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); break; default: mv.visitVarInsn(Opcodes.ALOAD, sidx); @@ -162,9 +165,14 @@ public void visitCode() { AsmUtil.PUSH(mv, className); AsmUtil.PUSH(mv, methodName); AsmUtil.PUSH(mv, methodDesc); + if (isStatic) { + AsmUtil.PUSHNULL(mv); + } else { + mv.visitVarInsn(Opcodes.ALOAD, 0); + } mv.visitVarInsn(Opcodes.ALOAD, arrVarIdx); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, CLASS, METHOD, SIGNATURE,false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, CLASS, METHOD, SIGNATURE, false); mv.visitCode(); } } \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/asm/CapReturnASM.java b/scouter.agent.java/src/scouter/agent/asm/CapReturnASM.java index 25517290c..ddb7226a9 100644 --- a/scouter.agent.java/src/scouter/agent/asm/CapReturnASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/CapReturnASM.java @@ -79,7 +79,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si return mv; } - return new CapReturnMV(access, desc, mv, className, name, desc); + return new CapReturnMV(access, desc, mv, className, name, desc,(access & ACC_STATIC) != 0); } } @@ -87,22 +87,24 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si class CapReturnMV extends LocalVariablesSorter implements Opcodes { private static final String CLASS = TraceMain.class.getName().replace('.', '/'); private static final String METHOD = "capReturn"; - private static final String SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"; + private static final String SIGNATURE = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"; private Type returnType; private String className; private String methodName; private String methodDesc; + private boolean isStatic; public CapReturnMV(int access, String desc, MethodVisitor mv, String classname, String methodname, - String methoddesc) { + String methoddesc, boolean isStatic) { super(ASM4, access, desc, mv); this.returnType = Type.getReturnType(desc); this.className = classname; this.methodName = methodname; this.methodDesc = methoddesc; + this.isStatic = isStatic; } @@ -118,9 +120,7 @@ private void capReturn() { Type tp = returnType; if (tp == null || tp.equals(Type.VOID_TYPE)) { - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); + pushCommon(); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CLASS, METHOD, SIGNATURE,false); return; @@ -131,10 +131,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ISTORE, i); mv.visitVarInsn(Opcodes.ILOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ILOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;",false); break; @@ -142,10 +139,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ISTORE, i); mv.visitVarInsn(Opcodes.ILOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ILOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;",false); break; @@ -153,10 +147,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ISTORE, i); mv.visitVarInsn(Opcodes.ILOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ILOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",false); break; @@ -164,10 +155,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ISTORE, i); mv.visitVarInsn(Opcodes.ILOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ILOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;",false); break; @@ -175,10 +163,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ISTORE, i); mv.visitVarInsn(Opcodes.ILOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ILOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;",false); break; @@ -186,10 +171,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.LSTORE, i); mv.visitVarInsn(Opcodes.LLOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.LLOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;",false); break; @@ -197,10 +179,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.FSTORE, i); mv.visitVarInsn(Opcodes.FLOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.FLOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;",false); @@ -209,10 +188,7 @@ private void capReturn() { mv.visitVarInsn(Opcodes.DSTORE, i); mv.visitVarInsn(Opcodes.DLOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.DLOAD, i); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;",false); break; @@ -220,13 +196,21 @@ private void capReturn() { mv.visitVarInsn(Opcodes.ASTORE, i); mv.visitVarInsn(Opcodes.ALOAD, i); - AsmUtil.PUSH(mv, className); - AsmUtil.PUSH(mv, methodName); - AsmUtil.PUSH(mv, methodDesc); - + pushCommon(); mv.visitVarInsn(Opcodes.ALOAD, i); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, CLASS, METHOD, SIGNATURE,false); } + + private void pushCommon() { + AsmUtil.PUSH(mv, className); + AsmUtil.PUSH(mv, methodName); + AsmUtil.PUSH(mv, methodDesc); + if (isStatic) { + AsmUtil.PUSHNULL(mv); + } else { + mv.visitVarInsn(Opcodes.ALOAD, 0); + } + } } \ No newline at end of file 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 0abf310d0..894d90bbe 100644 --- a/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java +++ b/scouter.agent.java/src/scouter/agent/counter/task/TomcatJMXPerf.java @@ -152,7 +152,7 @@ public void process(CounterBasket pw) { } catch (Exception e) { errors.add(ctx.attrName); collectCnt = 0; - e.printStackTrace(); + Logger.println("COUNTER", e); } } } @@ -287,7 +287,8 @@ class CtxObj { public String attrName; public String counter; - public CtxObj(String objName, ObjectName mbean, String objType, byte valueType, String attrName, String counter) { + public CtxObj(String objName, ObjectName mbean, String objType, byte valueType, String attrName, + String counter) { this.objName = objName; this.mbean = mbean; 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 382d15758..3c4edfe07 100644 --- a/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java +++ b/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java @@ -294,5 +294,15 @@ public static int sendWebName( String web) { return hash; } + private static IntLinkedSet groupAgent = new IntLinkedSet().setMax(500); + public static int sendGroup(String text) { + int hash = HashUtil.hash(text); + if (groupAgent.contains(hash)) { + return hash; + } + groupAgent.put(hash); + udpCollect.add(new TextPack(TextTypes.GROUP, hash, text)); + return hash; + } } \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/plugin/IServiceTrace.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractAppService.java similarity index 79% rename from scouter.agent.java/src/scouter/agent/plugin/IServiceTrace.java rename to scouter.agent.java/src/scouter/agent/plugin/AbstractAppService.java index d6888df55..2af1bc9d7 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/IServiceTrace.java +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractAppService.java @@ -15,12 +15,15 @@ * limitations under the License. */ package scouter.agent.plugin; -import scouter.agent.trace.HookPoint; + +import scouter.agent.trace.HookArgs; import scouter.lang.pack.XLogPack; -abstract public class IServiceTrace extends IPlugIn{ - public void start(ContextWrapper ctx, HookPoint p) { + +abstract public class AbstractAppService extends AbstractPlugin { + public void start(WrContext ctx, HookArgs p) { } - public void end(ContextWrapper ctx, XLogPack p) { + + public void end(WrContext ctx) { } - + } diff --git a/scouter.agent.java/src/scouter/agent/plugin/ICapture.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractCapture.java similarity index 64% rename from scouter.agent.java/src/scouter/agent/plugin/ICapture.java rename to scouter.agent.java/src/scouter/agent/plugin/AbstractCapture.java index c99858b0c..7d32879cf 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/ICapture.java +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractCapture.java @@ -16,13 +16,14 @@ */ package scouter.agent.plugin; -abstract public class ICapture extends IPlugIn { +import scouter.agent.trace.HookArgs; +import scouter.agent.trace.HookReturn; - abstract public void capArgs(ContextWrapper ctx, String className, String methodName, String methodDesc, - Object[] arg); +abstract public class AbstractCapture extends AbstractPlugin { - abstract public void capReturn(ContextWrapper ctx, String className, String methodName, String methodDesc, - Object rtn); + abstract public void capArgs(WrContext ctx, HookArgs hook); - abstract public void capThis(ContextWrapper ctx, String className, String methodDesc, Object this1); + abstract public void capReturn(WrContext ctx, HookReturn hook); + + abstract public void capThis(WrContext ctx, String className, String methodDesc, Object this1); } diff --git a/scouter.agent.java/src/scouter/agent/trace/HookPoint.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractHttpCall.java similarity index 61% rename from scouter.agent.java/src/scouter/agent/trace/HookPoint.java rename to scouter.agent.java/src/scouter/agent/plugin/AbstractHttpCall.java index cd4cc0936..4ce320c12 100644 --- a/scouter.agent.java/src/scouter/agent/trace/HookPoint.java +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractHttpCall.java @@ -14,22 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package scouter.agent.trace; +package scouter.agent.plugin; -public class HookPoint { - public String className; - public String methodName; - public String methodDesc; - public Object _this; - public Object[] arg; +abstract public class AbstractHttpCall extends AbstractPlugin { + abstract public void call(WrContext ctx, WrHttpCallRequest p) ; - public HookPoint(String className, String methodName, String methodDesc, Object _this, Object[] arg) { - super(); - this.className = className; - this.methodName = methodName; - this.methodDesc = methodDesc; - this._this = _this; - this.arg = arg; - } - -} \ No newline at end of file +} diff --git a/scouter.agent.java/src/scouter/agent/plugin/IHttpService.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractHttpService.java similarity index 68% rename from scouter.agent.java/src/scouter/agent/plugin/IHttpService.java rename to scouter.agent.java/src/scouter/agent/plugin/AbstractHttpService.java index 272154481..a960bf248 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/IHttpService.java +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractHttpService.java @@ -16,15 +16,12 @@ */ package scouter.agent.plugin; -import scouter.lang.pack.XLogPack; +abstract public class AbstractHttpService extends AbstractPlugin { -abstract public class IHttpService extends IPlugIn{ + abstract public void start(WrContext ctx, WrRequest req, WrResponse res); - abstract public void start(ContextWrapper ctx, RequestWrapper req, ResponseWrapper res); + abstract public void end(WrContext ctx, WrRequest req, WrResponse res); - abstract public void end(ContextWrapper ctx, XLogPack p); + abstract public boolean reject(WrContext ctx, WrRequest req, WrResponse res); - abstract public boolean reject(ContextWrapper ctx, RequestWrapper req, ResponseWrapper res); - - } diff --git a/scouter.agent.java/src/scouter/agent/plugin/AbstractJdbcPool.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractJdbcPool.java new file mode 100644 index 000000000..6268e20d7 --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractJdbcPool.java @@ -0,0 +1,21 @@ +/* + * 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.plugin; + +abstract public class AbstractJdbcPool extends AbstractPlugin { + abstract public String url(WrContext ctx, String classMethod, Object datasource); +} diff --git a/scouter.agent.java/src/scouter/agent/plugin/IPlugIn.java b/scouter.agent.java/src/scouter/agent/plugin/AbstractPlugin.java similarity index 50% rename from scouter.agent.java/src/scouter/agent/plugin/IPlugIn.java rename to scouter.agent.java/src/scouter/agent/plugin/AbstractPlugin.java index d4e2229ef..a0b508ea1 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/IPlugIn.java +++ b/scouter.agent.java/src/scouter/agent/plugin/AbstractPlugin.java @@ -1,10 +1,13 @@ package scouter.agent.plugin; +import java.lang.reflect.Field; import java.lang.reflect.Method; import scouter.agent.Logger; +import scouter.agent.trace.AlertProxy; +import scouter.lang.AlertLevel; -public class IPlugIn { +public class AbstractPlugin { long lastModified; public void log(Object c) { @@ -19,7 +22,9 @@ public Object field(Object o, String field) { if (o == null) return null; try { - return o.getClass().getField(field).get(o); + Field f = o.getClass().getField(field); + f.setAccessible(true); + return f.get(o); } catch (Throwable e) { } return null; @@ -30,19 +35,31 @@ public Object method(Object o, String method) { return null; try { Method m = o.getClass().getMethod(method, Wrapper.arg_c); + m.setAccessible(true); return m.invoke(o, Wrapper.arg_o); - } catch (Exception e) { + } catch (Throwable e) { } return null; } + public Object method1(Object o, String method) { + if (o == null) + return null; + try { + Method m = o.getClass().getMethod(method, Wrapper.arg_c); + return m.invoke(o, Wrapper.arg_o); + } catch (Throwable e) { + return e.toString(); + } + } + public Object method(Object o, String method, String param) { if (o == null) return null; try { Method m = o.getClass().getMethod(method, Wrapper.arg_c_s); return m.invoke(o, new Object[] { param }); - } catch (Exception e) { + } catch (Throwable e) { } return null; } @@ -54,4 +71,24 @@ public String toString(Object o) { public String toString(Object o, String def) { return o == null ? def : o.toString(); } + + public void alert(char level, String title, String message) { + switch (level) { + case 'i': + case 'I': + AlertProxy.sendAlert(AlertLevel.INFO, title, message); + case 'w': + case 'W': + AlertProxy.sendAlert(AlertLevel.WARN, title, message); + break; + case 'e': + case 'E': + AlertProxy.sendAlert(AlertLevel.ERROR, title, message); + break; + case 'f': + case 'F': + AlertProxy.sendAlert(AlertLevel.FATAL, title, message); + break; + } + } } diff --git a/scouter.agent.java/src/scouter/agent/plugin/PlugInLoader.java b/scouter.agent.java/src/scouter/agent/plugin/PlugInLoader.java deleted file mode 100644 index 6387cb1ea..000000000 --- a/scouter.agent.java/src/scouter/agent/plugin/PlugInLoader.java +++ /dev/null @@ -1,541 +0,0 @@ -/* - * 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.plugin; - -import java.io.BufferedReader; -import java.io.File; -import java.io.StringReader; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; - -import scouter.agent.Configure; -import scouter.agent.Logger; -import scouter.agent.trace.HookPoint; -import scouter.javassist.CannotCompileException; -import scouter.javassist.ClassPool; -import scouter.javassist.CtClass; -import scouter.javassist.CtMethod; -import scouter.javassist.CtNewMethod; -import scouter.lang.pack.XLogPack; -import scouter.util.FileUtil; -import scouter.util.Hexa32; -import scouter.util.StringUtil; -import scouter.util.ThreadUtil; - -public class PlugInLoader extends Thread { - private static PlugInLoader instance; - - public synchronized static PlugInLoader getInstance() { - if (instance == null) { - instance = new PlugInLoader(); - instance.setDaemon(true); - instance.setName("PlugInLoader"); - instance.start(); - } - return instance; - } - - public void run() { - while (true) { - try { - File root = Configure.getInstance().plugin_dir; - cleckPluginModified(root); - } catch (Throwable t) { - Logger.println("A160", t.toString()); - } - ThreadUtil.sleep(5000); - } - } - - private void cleckPluginModified(File root) { - File script = new File(root, "service.plug"); - if (script.canRead() == false) { - ServiceTracePlugIn.plugIn = null; - } else { - if (ServiceTracePlugIn.plugIn == null || ServiceTracePlugIn.plugIn.lastModified != script.lastModified()) { - ServiceTracePlugIn.plugIn = createIServiceTrace(script); - } - } - script = new File(root, "httpservice.plug"); - if (script.canRead() == false) { - HttpServiceTracePlugIn.plugIn = null; - } else { - if (HttpServiceTracePlugIn.plugIn == null - || HttpServiceTracePlugIn.plugIn.lastModified != script.lastModified()) { - HttpServiceTracePlugIn.plugIn = createIHttpService(script); - } - } - script = new File(root, "capture.plug"); - if (script.canRead() == false) { - CapturePlugIn.plugIn = null; - } else { - if (CapturePlugIn.plugIn == null || CapturePlugIn.plugIn.lastModified != script.lastModified()) { - CapturePlugIn.plugIn = createICaptureTrace(script); - } - } - } - - private long IHttpServiceCompile; - - private IHttpService createIHttpService(File script) { - if (IHttpServiceCompile == script.lastModified()) - return null; - IHttpServiceCompile = script.lastModified(); - try { - HashMap bodyTable = loadFileText(script); - String superName = IHttpService.class.getName(); - String className = "scouter.agent.plugin.impl.HttpServiceImpl"; - String START = "start"; - String START_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(RequestWrapper.class) - + nativeName(ResponseWrapper.class) + ")V"; - String START_P1 = ContextWrapper.class.getName(); - String START_P2 = RequestWrapper.class.getName(); - String START_P3 = ResponseWrapper.class.getName(); - StringBuffer START_BODY = bodyTable.get(START); - if (START_BODY == null) - throw new CannotCompileException("no method body: " + START); - String END = "end"; - String END_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(XLogPack.class) + ")V"; - String END_P1 = ContextWrapper.class.getName(); - String END_P2 = XLogPack.class.getName(); - StringBuffer END_BODY = bodyTable.get(END); - if (END_BODY == null) - throw new CannotCompileException("no method body: " + END); - String REJECT = "reject"; - String REJECT_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(RequestWrapper.class) - + nativeName(ResponseWrapper.class) + ")Z"; - String REJECT_P1 = ContextWrapper.class.getName(); - String REJECT_P2 = RequestWrapper.class.getName(); - String REJECT_P3 = ResponseWrapper.class.getName(); - StringBuffer REJECT_BODY = bodyTable.get(REJECT); - if (REJECT_BODY == null) - throw new CannotCompileException("no method body: " + REJECT); - ClassPool cp = ClassPool.getDefault(); - String jar = FileUtil.getJarFileName(PlugInLoader.class); - if (jar != null) { - cp.appendClassPath(jar); - } - CtClass cc = cp.get(superName); - CtClass impl = null; - StringBuffer sb = null; - try { - impl = cp.get(className); - impl.defrost(); - // START METHOD - CtMethod method = impl.getMethod(START, START_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(START_P1).append(" $ctx=$1;"); - sb.append(START_P2).append(" $req=$2;"); - sb.append(START_P3).append(" $res=$3;"); - sb.append(START_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // END METHOD - method = impl.getMethod(END, END_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(END_P1).append(" $ctx=$1;"); - sb.append(END_P2).append(" $pack=$2;"); - sb.append(END_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // REJECT METHOD - method = impl.getMethod(REJECT, REJECT_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(REJECT_P1).append(" $ctx=$1;"); - sb.append(REJECT_P2).append(" $req=$2;"); - sb.append(REJECT_P3).append(" $res=$3;"); - sb.append(REJECT_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - } catch (scouter.javassist.NotFoundException e) { - impl = cp.makeClass(className, cc); - // START METHOD - sb = new StringBuffer(); - sb.append("public void ").append(START).append("("); - sb.append(START_P1).append(" p1").append(","); - sb.append(START_P2).append(" p2").append(","); - sb.append(START_P3).append(" p3"); - sb.append("){}"); - CtMethod method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(START_P1).append(" $ctx=$1;"); - sb.append(START_P2).append(" $req=$2;"); - sb.append(START_P3).append(" $res=$3;"); - sb.append(START_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // END METHOD - sb = new StringBuffer(); - sb.append("public void ").append(END).append("("); - sb.append(END_P1).append(" p1").append(","); - sb.append(END_P2).append(" p2"); - sb.append("){}"); - method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(END_P1).append(" $ctx=$1;"); - sb.append(END_P2).append(" $pack=$2;"); - sb.append(END_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // REJECT METHOD - sb = new StringBuffer(); - sb.append("public boolean ").append(REJECT).append("("); - sb.append(REJECT_P1).append(" p1").append(","); - sb.append(REJECT_P2).append(" p2").append(","); - sb.append(REJECT_P3).append(" p3"); - sb.append("){return false;}"); - method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(REJECT_P1).append(" $ctx=$1;"); - sb.append(REJECT_P2).append(" $req=$2;"); - sb.append(REJECT_P3).append(" $res=$3;"); - sb.append(REJECT_BODY); - sb.append("}"); - method.setBody(sb.toString()); - } - Class c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); - IHttpService plugin = (IHttpService) c.newInstance(); - plugin.lastModified = script.lastModified(); - Logger.info( - "PLUG-IN : " + IHttpService.class.getName() + " loaded #" + Hexa32.toString32(plugin.hashCode())); - return plugin; - } catch (scouter.javassist.CannotCompileException ee) { - Logger.info(ee.getMessage()); - } catch (Throwable e) { - Logger.println("A161", e); - } - return null; - } - - private HashMap loadFileText(File script) { - StringBuffer sb = new StringBuffer(); - HashMap result = new HashMap(); - String txt = new String(FileUtil.readAll(script)); - try { - BufferedReader r = new BufferedReader(new StringReader(txt)); - while (true) { - String line = StringUtil.trim(r.readLine()); - if (line == null) - break; - if (line.startsWith("[") && line.endsWith("]")) { - sb = new StringBuffer(); - result.put(line.substring(1, line.length() - 1), sb); - } else { - sb.append(line).append("\n"); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return result; - } - - private long IServiceTraceCompile; - - private IServiceTrace createIServiceTrace(File script) { - if (IServiceTraceCompile == script.lastModified()) - return null; - IServiceTraceCompile = script.lastModified(); - try { - HashMap bodyTable = loadFileText(script); - String superName = IServiceTrace.class.getName(); - String className = "scouter.agent.plugin.impl.ServiceTraceImpl"; - String START = "start"; - String START_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(HookPoint.class) + ")V"; - String START_P1 = ContextWrapper.class.getName(); - String START_P2 = HookPoint.class.getName(); - StringBuffer START_BODY = bodyTable.get(START); - if (START_BODY == null) - throw new CannotCompileException("no method body: " + START); - - String END = "end"; - String END_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(XLogPack.class) + ")V"; - String END_P1 = ContextWrapper.class.getName(); - String END_P2 = XLogPack.class.getName(); - StringBuffer END_BODY = bodyTable.get(END); - if (END_BODY == null) - throw new CannotCompileException("no method body: " + END); - - ClassPool cp = ClassPool.getDefault(); - String jar = FileUtil.getJarFileName(PlugInLoader.class); - if (jar != null) { - cp.appendClassPath(jar); - } - Class c = null; - CtClass cc = cp.get(superName); - CtClass impl = null; - StringBuffer sb; - try { - impl = cp.get(className); - impl.defrost(); - // START METHOD - CtMethod method = impl.getMethod(START, START_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(START_P1).append(" $ctx=$1;"); - sb.append(START_P2).append(" $hook=$2;"); - sb.append(START_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // END METHOD - method = impl.getMethod(END, END_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(END_P1).append(" $ctx=$1;"); - sb.append(END_P2).append(" $pack=$2;"); - sb.append(END_BODY); - sb.append("}"); - method.setBody(sb.toString()); - } catch (scouter.javassist.NotFoundException e) { - impl = cp.makeClass(className, cc); - // START METHOD - sb = new StringBuffer(); - sb.append("public void ").append(START).append("("); - sb.append(START_P1).append(" p1 ").append(","); - sb.append(START_P2).append(" p2"); - sb.append("){}"); - CtMethod method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(START_P1).append(" $ctx=$1;"); - sb.append(START_P2).append(" $hook=$2;"); - sb.append(START_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // END METHOD - sb = new StringBuffer(); - sb.append("public void ").append(END).append("("); - sb.append(END_P1).append(" p1 ").append(","); - sb.append(END_P2).append(" p2"); - sb.append("){}"); - method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(END_P1).append(" $ctx=$1;"); - sb.append(END_P2).append(" $pack=$2;"); - sb.append(END_BODY); - sb.append("}"); - method.setBody(sb.toString()); - } - c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); - IServiceTrace plugin = (IServiceTrace) c.newInstance(); - plugin.lastModified = script.lastModified(); - Logger.info( - "PLUG-IN : " + IServiceTrace.class.getName() + " loaded #" + Hexa32.toString32(plugin.hashCode())); - return plugin; - } catch (scouter.javassist.CannotCompileException ee) { - Logger.info("PLUG-IN : " + ee.getMessage()); - } catch (Exception e) { - Logger.println("A162", e); - } - return null; - } - - private long ICaptureCompile; - - private ICapture createICaptureTrace(File script) { - if (ICaptureCompile == script.lastModified()) - return null; - ICaptureCompile = script.lastModified(); - try { - HashMap bodyTable = loadFileText(script); - String superName = ICapture.class.getName(); - String className = "scouter.agent.plugin.impl.CaptureImpl"; - String ARG = "capArgs"; - String ARG_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(String.class) - + nativeName(String.class) + nativeName(String.class) + "[" + nativeName(Object.class) + ")V"; - String ARG_P1 = ContextWrapper.class.getName(); - String ARG_P2 = String.class.getName(); - String ARG_P3 = String.class.getName(); - String ARG_P4 = String.class.getName(); - String ARG_P5 = "Object[]"; - StringBuffer ARG_BODY = bodyTable.get("args"); - - String RTN = "capReturn"; - String RTN_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(String.class) - + nativeName(String.class) + nativeName(String.class) + nativeName(Object.class) + ")V"; - String RTN_P1 = ContextWrapper.class.getName(); - String RTN_P2 = String.class.getName(); - String RTN_P3 = String.class.getName(); - String RTN_P4 = String.class.getName(); - String RTN_P5 = "Object"; - StringBuffer RTN_BODY = bodyTable.get("return"); - - String THIS = "capThis"; - String THIS_SIG = "(" + nativeName(ContextWrapper.class) + nativeName(String.class) - + nativeName(String.class) + nativeName(Object.class) + ")V"; - String THIS_P1 = ContextWrapper.class.getName(); - String THIS_P2 = String.class.getName(); - String THIS_P3 = String.class.getName(); - String THIS_P4 = "Object"; - StringBuffer THIS_BODY = bodyTable.get("this"); - - ClassPool cp = ClassPool.getDefault(); - String jar = FileUtil.getJarFileName(PlugInLoader.class); - if (jar != null) { - cp.appendClassPath(jar); - } - Class c = null; - CtClass cc = cp.get(superName); - CtClass impl = null; - try { - impl = cp.get(className); - impl.defrost(); - // ARG METHOD - CtMethod method = impl.getMethod(ARG, ARG_SIG); - StringBuffer sb = new StringBuffer(); - sb.append("{"); - sb.append(ARG_P1).append(" $ctx=$1;"); - sb.append(ARG_P2).append(" $class=$2;"); - sb.append(ARG_P3).append(" $method=$3;"); - sb.append(ARG_P4).append(" $desc=$4;"); - sb.append(ARG_P5).append(" $data=$5;"); - sb.append(ARG_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // RETURN METHOD - method = impl.getMethod(RTN, RTN_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(RTN_P1).append(" $ctx=$1;"); - sb.append(RTN_P2).append(" $class=$2;"); - sb.append(RTN_P3).append(" $method=$3;"); - sb.append(RTN_P4).append(" $desc=$4;"); - sb.append(RTN_P5).append(" $data=$5;"); - sb.append(RTN_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // THIS METHOD - method = impl.getMethod(THIS, THIS_SIG); - sb = new StringBuffer(); - sb.append("{"); - sb.append(THIS_P1).append(" $ctx=$1;"); - sb.append(THIS_P2).append(" $class=$2;"); - sb.append(THIS_P3).append(" $desc=$3;"); - sb.append(THIS_P4).append(" $data=$4;"); - sb.append(THIS_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - } catch (scouter.javassist.NotFoundException e) { - impl = cp.makeClass(className, cc); - // ARG METHOD - StringBuffer sb = new StringBuffer(); - sb.append("public void ").append(ARG).append("("); - sb.append(ARG_P1).append(" p1 ").append(","); - sb.append(ARG_P2).append(" p2 ").append(","); - sb.append(ARG_P3).append(" p3 ").append(","); - sb.append(ARG_P4).append(" p4 ").append(","); - sb.append(ARG_P5).append(" p5 "); - sb.append("){}"); - - CtMethod method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(ARG_P1).append(" $ctx=$1;"); - sb.append(ARG_P2).append(" $class=$2;"); - sb.append(ARG_P3).append(" $method=$3;"); - sb.append(ARG_P4).append(" $desc=$4;"); - sb.append(ARG_P5).append(" $data=$5;"); - sb.append(ARG_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // RTN METHOD - sb = new StringBuffer(); - sb.append("public void ").append(RTN).append("("); - sb.append(RTN_P1).append(" p1 ").append(","); - sb.append(RTN_P2).append(" p2 ").append(","); - sb.append(RTN_P3).append(" p3 ").append(","); - sb.append(RTN_P4).append(" p4 ").append(","); - sb.append(RTN_P5).append(" p5 "); - sb.append("){}"); - method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(RTN_P1).append(" $ctx=$1;"); - sb.append(RTN_P2).append(" $class=$2;"); - sb.append(RTN_P3).append(" $method=$3;"); - sb.append(RTN_P4).append(" $desc=$4;"); - sb.append(RTN_P5).append(" $data=$5;"); - sb.append(RTN_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - // THIS METHOD - sb = new StringBuffer(); - sb.append("public void ").append(THIS).append("("); - sb.append(THIS_P1).append(" p1 ").append(","); - sb.append(THIS_P2).append(" p2 ").append(","); - sb.append(THIS_P3).append(" p3 ").append(","); - sb.append(THIS_P4).append(" p4 "); - sb.append("){}"); - method = CtNewMethod.make(sb.toString(), impl); - impl.addMethod(method); - sb = new StringBuffer(); - sb.append("{"); - sb.append(THIS_P1).append(" $ctx=$1;"); - sb.append(THIS_P2).append(" $class=$2;"); - sb.append(THIS_P3).append(" $desc=$3;"); - sb.append(THIS_P4).append(" $data=$4;"); - sb.append(THIS_BODY); - sb.append("}"); - method.setBody(sb.toString()); - - } - c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); - ICapture plugin = (ICapture) c.newInstance(); - plugin.lastModified = script.lastModified(); - Logger.info( - "PLUG-IN : " + IServiceTrace.class.getName() + " loaded #" + Hexa32.toString32(plugin.hashCode())); - return plugin; - } catch (scouter.javassist.CannotCompileException ee) { - Logger.info("PLUG-IN : " + ee.getMessage()); - } catch (Exception e) { - Logger.println("A162", e); - } - return null; - } - - private String nativeName(Class class1) { - return "L" + class1.getName().replace('.', '/') + ";"; - } -} diff --git a/scouter.agent.java/src/scouter/agent/plugin/ServiceTracePlugIn.java b/scouter.agent.java/src/scouter/agent/plugin/PluginAppServiceTrace.java similarity index 70% rename from scouter.agent.java/src/scouter/agent/plugin/ServiceTracePlugIn.java rename to scouter.agent.java/src/scouter/agent/plugin/PluginAppServiceTrace.java index a07022404..65dc7359a 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/ServiceTracePlugIn.java +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginAppServiceTrace.java @@ -17,31 +17,30 @@ package scouter.agent.plugin; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; -import scouter.lang.pack.XLogPack; -public class ServiceTracePlugIn { +public class PluginAppServiceTrace { - static IServiceTrace plugIn; + static AbstractAppService plugIn; static { - PlugInLoader.getInstance(); + PluginLoader.getInstance(); } - public static void start(TraceContext ctx, HookPoint hookPoint) { + public static void start(TraceContext ctx, HookArgs hook) { if (plugIn != null) { try { - plugIn.start(new ContextWrapper(ctx), hookPoint); + plugIn.start(new WrContext(ctx), hook); } catch (Throwable t) { } } } - public static void end(TraceContext ctx, XLogPack p) { + public static void end(TraceContext ctx) { if (plugIn != null) { try { - plugIn.end(new ContextWrapper(ctx), p); + plugIn.end(new WrContext(ctx)); } catch (Throwable t) { } } diff --git a/scouter.agent.java/src/scouter/agent/plugin/CapturePlugIn.java b/scouter.agent.java/src/scouter/agent/plugin/PluginCaptureTrace.java similarity index 65% rename from scouter.agent.java/src/scouter/agent/plugin/CapturePlugIn.java rename to scouter.agent.java/src/scouter/agent/plugin/PluginCaptureTrace.java index 2b60328ab..7b9825a5c 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/CapturePlugIn.java +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginCaptureTrace.java @@ -16,29 +16,31 @@ */ package scouter.agent.plugin; +import scouter.agent.trace.HookArgs; +import scouter.agent.trace.HookReturn; import scouter.agent.trace.TraceContext; -public class CapturePlugIn { +public class PluginCaptureTrace { - static ICapture plugIn; + static AbstractCapture plugIn; static { - PlugInLoader.getInstance(); + PluginLoader.getInstance(); } - public static void capArgs(TraceContext ctx, String className, String methodName, String methodDesc, Object[] arg) { + public static void capArgs(TraceContext ctx, HookArgs hook) { if (plugIn != null) { try { - plugIn.capArgs(new ContextWrapper(ctx), className, methodName, methodDesc, arg); + plugIn.capArgs(new WrContext(ctx), hook); } catch (Throwable t) { } } } - public static void capReturn(TraceContext ctx, String className, String methodName, String methodDesc, Object data) { + public static void capReturn(TraceContext ctx, HookReturn hook) { if (plugIn != null) { try { - plugIn.capReturn(new ContextWrapper(ctx), className, methodName, methodDesc, data); + plugIn.capReturn(new WrContext(ctx), hook); } catch (Throwable t) { } } @@ -47,7 +49,7 @@ public static void capReturn(TraceContext ctx, String className, String methodNa public static void capThis(TraceContext ctx, String className, String methodDesc, Object data) { if (plugIn != null) { try { - plugIn.capThis(new ContextWrapper(ctx), className, methodDesc, data); + plugIn.capThis(new WrContext(ctx),className, methodDesc, data); } catch (Throwable t) { } } diff --git a/scouter.agent.java/src/scouter/agent/plugin/PluginHttpCallTrace.java b/scouter.agent.java/src/scouter/agent/plugin/PluginHttpCallTrace.java new file mode 100644 index 000000000..7c83eaf1b --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginHttpCallTrace.java @@ -0,0 +1,59 @@ +/* + * 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.plugin; + +import java.net.HttpURLConnection; + +import scouter.agent.proxy.IHttpClient; +import scouter.agent.trace.TraceContext; + +public class PluginHttpCallTrace { + + static AbstractHttpCall plugIn; + + static { + PluginLoader.getInstance(); + } + public static void call(TraceContext ctx, HttpURLConnection req) { + if (plugIn != null) { + try { + plugIn.call(new WrContext(ctx), new WrHttpCallRequest(req)); + } catch (Throwable t) { + } + } + } + public static void call(TraceContext ctx, Object req) { + if (plugIn != null) { + try { + plugIn.call(new WrContext(ctx), new WrHttpCallRequest(req)); + } catch (Throwable t) { + } + } + } + public static void call(TraceContext ctx, IHttpClient httpclient, Object req) { + if (plugIn != null) { + try { + plugIn.call(new WrContext(ctx), new WrHttpCallRequest(httpclient, req)); + } catch (Throwable t) { + } + } + } + + + +} \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/plugin/HttpServiceTracePlugIn.java b/scouter.agent.java/src/scouter/agent/plugin/PluginHttpServiceTrace.java similarity index 72% rename from scouter.agent.java/src/scouter/agent/plugin/HttpServiceTracePlugIn.java rename to scouter.agent.java/src/scouter/agent/plugin/PluginHttpServiceTrace.java index 0706ed645..b48e029d4 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/HttpServiceTracePlugIn.java +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginHttpServiceTrace.java @@ -17,29 +17,28 @@ package scouter.agent.plugin; import scouter.agent.trace.TraceContext; -import scouter.lang.pack.XLogPack; -public class HttpServiceTracePlugIn { +public class PluginHttpServiceTrace { - static IHttpService plugIn; + static AbstractHttpService plugIn; static { - PlugInLoader.getInstance(); + PluginLoader.getInstance(); } public static void start(TraceContext ctx, Object req, Object res) { if (plugIn != null) { try { - plugIn.start(new ContextWrapper(ctx), new RequestWrapper(req), new ResponseWrapper(res)); + plugIn.start(new WrContext(ctx), new WrRequest(req), new WrResponse(res)); } catch (Throwable t) { } } } - public static void end(TraceContext ctx, XLogPack p) { + public static void end(TraceContext ctx, Object req, Object res) { if (plugIn != null) { try { - plugIn.end(new ContextWrapper(ctx), p); + plugIn.end(new WrContext(ctx), new WrRequest(req), new WrResponse(res)); } catch (Throwable t) { } } @@ -48,7 +47,7 @@ public static void end(TraceContext ctx, XLogPack p) { public static boolean reject(TraceContext ctx, Object req, Object res) { if (plugIn != null) { try { - return plugIn.reject(new ContextWrapper(ctx), new RequestWrapper(req), new ResponseWrapper(res)); + return plugIn.reject(new WrContext(ctx), new WrRequest(req), new WrResponse(res)); } catch (Throwable t) { } } diff --git a/scouter.agent.java/src/scouter/agent/plugin/PluginJdbcPoolTrace.java b/scouter.agent.java/src/scouter/agent/plugin/PluginJdbcPoolTrace.java new file mode 100644 index 000000000..0957fd01c --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginJdbcPoolTrace.java @@ -0,0 +1,42 @@ +/* + * 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.plugin; + +import scouter.agent.trace.TraceContext; + +public class PluginJdbcPoolTrace { + + static AbstractJdbcPool plugIn; + + static { + PluginLoader.getInstance(); + } + + public static String url(TraceContext ctx, String msg, Object pool) { + if (plugIn != null) { + try { + return plugIn.url(new WrContext(ctx),msg, pool); + } catch (Throwable t) { + } + } + return null; + } + + + +} \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java b/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java new file mode 100644 index 000000000..8aff7f65c --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java @@ -0,0 +1,604 @@ +/* + * 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.plugin; + +import java.io.BufferedReader; +import java.io.File; +import java.io.StringReader; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; + +import scouter.agent.Configure; +import scouter.agent.Logger; +import scouter.agent.trace.HookArgs; +import scouter.agent.trace.HookReturn; +import scouter.agent.trace.TraceSQL; +import scouter.javassist.CannotCompileException; +import scouter.javassist.ClassPool; +import scouter.javassist.CtClass; +import scouter.javassist.CtMethod; +import scouter.javassist.CtNewMethod; +import scouter.lang.pack.XLogPack; +import scouter.util.FileUtil; +import scouter.util.Hexa32; +import scouter.util.StringUtil; +import scouter.util.ThreadUtil; + +public class PluginLoader extends Thread { + private static PluginLoader instance; + + public synchronized static PluginLoader getInstance() { + if (instance == null) { + instance = new PluginLoader(); + instance.setDaemon(true); + instance.setName(ThreadUtil.getName(PluginLoader.class)); + instance.start(); + } + return instance; + } + + public void run() { + while (true) { + try { + File root = Configure.getInstance().plugin_dir; + cleckPluginModified(root); + } catch (Throwable t) { + Logger.println("A160", t.toString()); + } + ThreadUtil.sleep(5000); + } + } + + private void cleckPluginModified(File root) { + File script = new File(root, "service.plug"); + if (script.canRead() == false) { + PluginAppServiceTrace.plugIn = null; + } else { + if (PluginAppServiceTrace.plugIn == null + || PluginAppServiceTrace.plugIn.lastModified != script.lastModified()) { + PluginAppServiceTrace.plugIn = createAppService(script); + } + } + script = new File(root, "httpservice.plug"); + if (script.canRead() == false) { + PluginHttpServiceTrace.plugIn = null; + } else { + if (PluginHttpServiceTrace.plugIn == null + || PluginHttpServiceTrace.plugIn.lastModified != script.lastModified()) { + PluginHttpServiceTrace.plugIn = createHttpService(script); + } + } + script = new File(root, "capture.plug"); + if (script.canRead() == false) { + PluginCaptureTrace.plugIn = null; + } else { + if (PluginCaptureTrace.plugIn == null || PluginCaptureTrace.plugIn.lastModified != script.lastModified()) { + PluginCaptureTrace.plugIn = createICaptureTrace(script); + } + } + script = new File(root, "jdbcpool.plug"); + if (script.canRead() == false) { + PluginJdbcPoolTrace.plugIn = null; + } else { + if (PluginJdbcPoolTrace.plugIn == null + || PluginJdbcPoolTrace.plugIn.lastModified != script.lastModified()) { + PluginJdbcPoolTrace.plugIn = createIJdbcPool(script); + if (PluginJdbcPoolTrace.plugIn != null) { + TraceSQL.clearUrlMap(); + } + } + } + script = new File(root, "httpcall.plug"); + if (script.canRead() == false) { + PluginHttpCallTrace.plugIn = null; + } else { + if (PluginHttpCallTrace.plugIn == null + || PluginHttpCallTrace.plugIn.lastModified != script.lastModified()) { + PluginHttpCallTrace.plugIn = createIHttpCall(script); + } + } + } + + private long IHttpServiceCompile; + + private AbstractHttpService createHttpService(File script) { + if (IHttpServiceCompile == script.lastModified()) + return null; + IHttpServiceCompile = script.lastModified(); + + try { + HashMap bodyTable = loadFileText(script); + String superName = AbstractHttpService.class.getName(); + String className = "scouter.agent.plugin.impl.HttpServiceImpl"; + + String METHOD_START = "start"; + String METHOD_END = "end"; + String METHOD_REJECT = "reject"; + + String SIGNATURE = nativeName(WrContext.class) + nativeName(WrRequest.class) + nativeName(WrResponse.class); + String METHOD_P1 = WrContext.class.getName(); + String METHOD_P2 = WrRequest.class.getName(); + String METHOD_P3 = WrResponse.class.getName(); + + if (bodyTable.containsKey(METHOD_START) == false) + throw new CannotCompileException("no method body: " + METHOD_START); + if (bodyTable.containsKey(METHOD_END) == false) + throw new CannotCompileException("no method body: " + METHOD_END); + if (bodyTable.containsKey(METHOD_REJECT) == false) + throw new CannotCompileException("no method body: " + METHOD_REJECT); + + ClassPool cp = ClassPool.getDefault(); + String jar = FileUtil.getJarFileName(PluginLoader.class); + if (jar != null) { + cp.appendClassPath(jar); + } + CtClass cc = cp.get(superName); + CtClass impl = null; + + CtMethod method_start = null; + CtMethod method_end = null; + CtMethod method_reject = null; + StringBuffer sb = null; + + try { + impl = cp.get(className); + impl.defrost(); + // START METHOD + method_start = impl.getMethod(METHOD_START, "(" + SIGNATURE + ")V"); + // END METHOD + method_end = impl.getMethod(METHOD_END, "(" + SIGNATURE + ")V"); + // REJECT METHOD + method_reject = impl.getMethod(METHOD_REJECT, "(" + SIGNATURE + ")Z"); + } catch (scouter.javassist.NotFoundException e) { + impl = cp.makeClass(className, cc); + + StringBuffer sb1 = new StringBuffer(); + sb1.append(METHOD_P1).append(" p1").append(","); + sb1.append(METHOD_P2).append(" p2").append(","); + sb1.append(METHOD_P3).append(" p3"); + + // START METHOD + sb = new StringBuffer(); + sb.append("public void ").append(METHOD_START).append("(").append(sb1).append("){}"); + method_start = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_start); + + // END METHOD + sb = new StringBuffer(); + sb.append("public void ").append(METHOD_END).append("(").append(sb1).append("){}"); + method_end = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_end); + + // REJECT METHOD + sb = new StringBuffer(); + sb.append("public boolean ").append(METHOD_REJECT).append("(").append(sb1).append("){return false;}"); + method_reject = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_reject); + } + + StringBuffer bodyPrefix = new StringBuffer(); + bodyPrefix.append("{"); + bodyPrefix.append(METHOD_P1).append(" $ctx=$1;"); + bodyPrefix.append(METHOD_P2).append(" $req=$2;"); + bodyPrefix.append(METHOD_P3).append(" $res=$3;"); + + method_start.setBody( + new StringBuffer().append(bodyPrefix).append(bodyTable.get(METHOD_START)).append("}").toString()); + method_end.setBody( + new StringBuffer().append(bodyPrefix).append(bodyTable.get(METHOD_END)).append("}").toString()); + method_reject.setBody( + new StringBuffer().append(bodyPrefix).append(bodyTable.get(METHOD_REJECT)).append("}").toString()); + + Class c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); + AbstractHttpService plugin = (AbstractHttpService) c.newInstance(); + plugin.lastModified = script.lastModified(); + Logger.info("PLUG-IN : " + AbstractHttpService.class.getName() + " loaded #" + + Hexa32.toString32(plugin.hashCode())); + return plugin; + } catch (scouter.javassist.CannotCompileException ee) { + Logger.info(ee.getMessage()); + } catch (Throwable e) { + Logger.println("A161", e); + } + return null; + } + + private HashMap loadFileText(File script) { + StringBuffer sb = new StringBuffer(); + HashMap result = new HashMap(); + String txt = new String(FileUtil.readAll(script)); + try { + BufferedReader r = new BufferedReader(new StringReader(txt)); + while (true) { + String line = StringUtil.trim(r.readLine()); + if (line == null) + break; + if (line.startsWith("[") && line.endsWith("]")) { + sb = new StringBuffer(); + result.put(line.substring(1, line.length() - 1), sb); + } else { + sb.append(line).append("\n"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + private long IServiceTraceCompile; + + private AbstractAppService createAppService(File script) { + if (IServiceTraceCompile == script.lastModified()) + return null; + IServiceTraceCompile = script.lastModified(); + try { + HashMap bodyTable = loadFileText(script); + String superName = AbstractAppService.class.getName(); + String className = "scouter.agent.plugin.impl.ServiceTraceImpl"; + String START = "start"; + String START_SIG = "(" + nativeName(WrContext.class) + nativeName(HookArgs.class) + ")V"; + String START_P1 = WrContext.class.getName(); + String START_P2 = HookArgs.class.getName(); + StringBuffer START_BODY = bodyTable.get(START); + if (START_BODY == null) + throw new CannotCompileException("no method body: " + START); + + String END = "end"; + String END_SIG = "(" + nativeName(WrContext.class) + ")V"; + String END_P1 = WrContext.class.getName(); + StringBuffer END_BODY = bodyTable.get(END); + if (END_BODY == null) + throw new CannotCompileException("no method body: " + END); + + ClassPool cp = ClassPool.getDefault(); + String jar = FileUtil.getJarFileName(PluginLoader.class); + if (jar != null) { + cp.appendClassPath(jar); + } + Class c = null; + CtClass cc = cp.get(superName); + CtClass impl = null; + StringBuffer sb; + CtMethod method_start = null; + CtMethod method_end = null; + + try { + impl = cp.get(className); + impl.defrost(); + // START METHOD + method_start = impl.getMethod(START, START_SIG); + // END METHOD + method_end = impl.getMethod(END, END_SIG); + + } catch (scouter.javassist.NotFoundException e) { + impl = cp.makeClass(className, cc); + // START METHOD + sb = new StringBuffer(); + sb.append("public void ").append(START).append("("); + sb.append(START_P1).append(" p1 ").append(","); + sb.append(START_P2).append(" p2"); + sb.append("){}"); + method_start = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_start); + + // END METHOD + sb = new StringBuffer(); + sb.append("public void ").append(END).append("("); + sb.append(END_P1).append(" p1 "); + sb.append("){}"); + method_end = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_end); + + } + + sb = new StringBuffer(); + sb.append("{"); + sb.append(START_P1).append(" $ctx=$1;"); + sb.append(START_P2).append(" $hook=$2;"); + sb.append(START_BODY); + sb.append("}"); + method_start.setBody(sb.toString()); + + sb = new StringBuffer(); + sb.append("{"); + sb.append(END_P1).append(" $ctx=$1;"); + sb.append(END_BODY); + sb.append("}"); + method_end.setBody(sb.toString()); + + c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); + AbstractAppService plugin = (AbstractAppService) c.newInstance(); + plugin.lastModified = script.lastModified(); + Logger.info("PLUG-IN : " + AbstractAppService.class.getName() + " loaded #" + + Hexa32.toString32(plugin.hashCode())); + return plugin; + } catch (scouter.javassist.CannotCompileException ee) { + Logger.info("PLUG-IN : " + ee.getMessage()); + } catch (Exception e) { + Logger.println("A162", e); + } + return null; + } + + private long ICaptureCompile; + + private AbstractCapture createICaptureTrace(File script) { + if (ICaptureCompile == script.lastModified()) + return null; + ICaptureCompile = script.lastModified(); + try { + HashMap bodyTable = loadFileText(script); + String superName = AbstractCapture.class.getName(); + String className = "scouter.agent.plugin.impl.CaptureImpl"; + String ARG = "capArgs"; + String ARG_SIG = "(" + nativeName(WrContext.class) + nativeName(HookArgs.class) + ")V"; + String ARG_P1 = WrContext.class.getName(); + String ARG_P2 = HookArgs.class.getName(); + StringBuffer ARG_BODY = bodyTable.get("args"); + + String RTN = "capReturn"; + String RTN_SIG = "(" + nativeName(WrContext.class) + nativeName(HookReturn.class) + ")V"; + String RTN_P1 = WrContext.class.getName(); + String RTN_P2 = HookReturn.class.getName(); + StringBuffer RTN_BODY = bodyTable.get("return"); + + String THIS = "capThis"; + String THIS_SIG = "(" + nativeName(WrContext.class) + nativeName(String.class) + nativeName(String.class) + + nativeName(Object.class) + ")V"; + String THIS_P1 = WrContext.class.getName(); + String THIS_P2 = String.class.getName(); + String THIS_P3 = String.class.getName(); + String THIS_P4 = "Object"; + StringBuffer THIS_BODY = bodyTable.get("this"); + + ClassPool cp = ClassPool.getDefault(); + String jar = FileUtil.getJarFileName(PluginLoader.class); + if (jar != null) { + cp.appendClassPath(jar); + } + Class c = null; + CtClass cc = cp.get(superName); + CtClass impl = null; + CtMethod method_args; + CtMethod method_return; + CtMethod method_this; + StringBuffer sb; + try { + impl = cp.get(className); + impl.defrost(); + // ARG METHOD + method_args = impl.getMethod(ARG, ARG_SIG); + // RETURN METHOD + method_return = impl.getMethod(RTN, RTN_SIG); + // THIS METHOD + method_this = impl.getMethod(THIS, THIS_SIG); + + } catch (scouter.javassist.NotFoundException e) { + impl = cp.makeClass(className, cc); + // ARG METHOD + sb = new StringBuffer(); + sb.append("public void ").append(ARG).append("("); + sb.append(ARG_P1).append(" p1 ").append(","); + sb.append(ARG_P2).append(" p2 "); + sb.append("){}"); + + method_args = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_args); + + // RTN METHOD + sb = new StringBuffer(); + sb.append("public void ").append(RTN).append("("); + sb.append(RTN_P1).append(" p1 ").append(","); + sb.append(RTN_P2).append(" p2 "); + sb.append("){}"); + method_return = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_return); + + // THIS METHOD + sb = new StringBuffer(); + sb.append("public void ").append(THIS).append("("); + sb.append(THIS_P1).append(" p1 ").append(","); + sb.append(THIS_P2).append(" p2 ").append(","); + sb.append(THIS_P3).append(" p3 ").append(","); + sb.append(THIS_P4).append(" p4 "); + sb.append("){}"); + method_this = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method_this); + + } + + sb = new StringBuffer(); + sb.append("{"); + sb.append(ARG_P1).append(" $ctx=$1;"); + sb.append(ARG_P2).append(" $hook=$2;"); + sb.append(ARG_BODY); + sb.append("}"); + method_args.setBody(sb.toString()); + + sb = new StringBuffer(); + sb.append("{"); + sb.append(RTN_P1).append(" $ctx=$1;"); + sb.append(RTN_P2).append(" $hook=$2;"); + sb.append(RTN_BODY); + sb.append("}"); + method_return.setBody(sb.toString()); + + sb = new StringBuffer(); + sb.append("{"); + sb.append(THIS_P1).append(" $ctx=$1;"); + sb.append(THIS_P2).append(" $class=$2;"); + sb.append(THIS_P3).append(" $desc=$3;"); + sb.append(THIS_P4).append(" $this=$4;"); + sb.append(THIS_BODY); + sb.append("}"); + method_this.setBody(sb.toString()); + + c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); + AbstractCapture plugin = (AbstractCapture) c.newInstance(); + plugin.lastModified = script.lastModified(); + Logger.info("PLUG-IN : " + AbstractCapture.class.getName() + " loaded #" + + Hexa32.toString32(plugin.hashCode())); + return plugin; + } catch (scouter.javassist.CannotCompileException ee) { + Logger.info("PLUG-IN : " + ee.getMessage()); + } catch (Exception e) { + Logger.println("A162", e); + } + return null; + } + + private long IJdbcPoolCompile; + + private AbstractJdbcPool createIJdbcPool(File script) { + if (IJdbcPoolCompile == script.lastModified()) + return null; + IJdbcPoolCompile = script.lastModified(); + try { + HashMap bodyTable = loadFileText(script); + String superName = AbstractJdbcPool.class.getName(); + String className = "scouter.agent.plugin.impl.JdbcPoolImpl"; + String URL = "url"; + String URL_SIG = "(" + nativeName(WrContext.class) + nativeName(String.class) + nativeName(Object.class) + + ")" + nativeName(String.class); + String URL_P1 = WrContext.class.getName(); + String URL_P2 = String.class.getName(); + String URL_P3 = "Object"; + StringBuffer URL_BODY = bodyTable.get("url"); + + ClassPool cp = ClassPool.getDefault(); + String jar = FileUtil.getJarFileName(PluginLoader.class); + if (jar != null) { + cp.appendClassPath(jar); + } + Class c = null; + CtClass cc = cp.get(superName); + CtClass impl = null; + CtMethod method = null; + try { + impl = cp.get(className); + impl.defrost(); + method = impl.getMethod(URL, URL_SIG); + } catch (scouter.javassist.NotFoundException e) { + impl = cp.makeClass(className, cc); + StringBuffer sb = new StringBuffer(); + sb.append("public String ").append(URL).append("("); + sb.append(URL_P1).append(" p1 ").append(","); + sb.append(URL_P2).append(" p2 ").append(","); + sb.append(URL_P3).append(" p3 "); + sb.append("){return null;}"); + + method = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method); + + } + + StringBuffer sb = new StringBuffer(); + sb.append("{"); + sb.append(URL_P1).append(" $ctx=$1;"); + sb.append(URL_P2).append(" $msg=$2;"); + sb.append(URL_P3).append(" $pool=$3;"); + sb.append(URL_BODY); + sb.append("}"); + method.setBody(sb.toString()); + + c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); + AbstractJdbcPool plugin = (AbstractJdbcPool) c.newInstance(); + plugin.lastModified = script.lastModified(); + + Logger.info("PLUG-IN : " + AbstractJdbcPool.class.getName() + " loaded #" + + Hexa32.toString32(plugin.hashCode())); + return plugin; + } catch (scouter.javassist.CannotCompileException ee) { + Logger.info("PLUG-IN : " + ee.getMessage()); + } catch (Exception e) { + Logger.println("A162", e); + } + return null; + } + + private long IHttpCallCompile; + + private AbstractHttpCall createIHttpCall(File script) { + if (IHttpCallCompile == script.lastModified()) + return null; + IHttpCallCompile = script.lastModified(); + try { + HashMap bodyTable = loadFileText(script); + String superName = AbstractHttpCall.class.getName(); + String className = "scouter.agent.plugin.impl.IHttCallTraceImpl"; + String CALL = "call"; + String CALL_SIG = "(" + nativeName(WrContext.class) + nativeName(WrHttpCallRequest.class) + ")V"; + String CALL_P1 = WrContext.class.getName(); + String CALL_P2 = WrHttpCallRequest.class.getName(); + StringBuffer CALL_BODY = bodyTable.get(CALL); + if (CALL_BODY == null) + throw new CannotCompileException("no method body: " + CALL); + + ClassPool cp = ClassPool.getDefault(); + String jar = FileUtil.getJarFileName(PluginLoader.class); + if (jar != null) { + cp.appendClassPath(jar); + } + Class c = null; + CtClass cc = cp.get(superName); + CtClass impl = null; + StringBuffer sb; + CtMethod method = null; + try { + impl = cp.get(className); + impl.defrost(); + method = impl.getMethod(CALL, CALL_SIG); + + } catch (scouter.javassist.NotFoundException e) { + impl = cp.makeClass(className, cc); + sb = new StringBuffer(); + sb.append("public void ").append(CALL).append("("); + sb.append(CALL_P1).append(" p1 ").append(","); + sb.append(CALL_P2).append(" p2"); + sb.append("){}"); + method = CtNewMethod.make(sb.toString(), impl); + impl.addMethod(method); + } + sb = new StringBuffer(); + sb.append("{"); + sb.append(CALL_P1).append(" $ctx=$1;"); + sb.append(CALL_P2).append(" $req=$2;"); + sb.append(CALL_BODY); + sb.append("}"); + method.setBody(sb.toString()); + + c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); + AbstractHttpCall plugin = (AbstractHttpCall) c.newInstance(); + plugin.lastModified = script.lastModified(); + Logger.info("PLUG-IN : " + AbstractHttpCall.class.getName() + " loaded #" + + Hexa32.toString32(plugin.hashCode())); + return plugin; + } catch (scouter.javassist.CannotCompileException ee) { + Logger.info("PLUG-IN : " + ee.getMessage()); + } catch (Exception e) { + Logger.println("A162", e); + } + return null; + } + + private String nativeName(Class class1) { + return "L" + class1.getName().replace('.', '/') + ";"; + } +} diff --git a/scouter.agent.java/src/scouter/agent/plugin/ContextWrapper.java b/scouter.agent.java/src/scouter/agent/plugin/WrContext.java similarity index 72% rename from scouter.agent.java/src/scouter/agent/plugin/ContextWrapper.java rename to scouter.agent.java/src/scouter/agent/plugin/WrContext.java index 6c790917b..daa3118c8 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/ContextWrapper.java +++ b/scouter.agent.java/src/scouter/agent/plugin/WrContext.java @@ -7,11 +7,11 @@ import scouter.util.IPUtil; import scouter.util.SysJMX; -public class ContextWrapper { +public class WrContext { private TraceContext ctx; - public ContextWrapper(TraceContext ctx) { + public WrContext(TraceContext ctx) { this.ctx = ctx; } @@ -30,24 +30,49 @@ public int serviceHash() { return ctx.serviceHash; } - public void ip(String ip) { - ctx.remoteAddr = IPUtil.toBytes(ip); + public void remoteIp(String ip) { + ctx.remoteIp = ip; } + public String remoteIp() { + return ctx.remoteIp==null?"0.0.0.0":ctx.remoteIp; + } + + public void error(String err) { if (ctx.error == 0) { ctx.error = DataProxy.sendError(err); } } + public boolean isError() { + return ctx.error != 0; + } + + public void group(String group) { + ctx.group = group; + } + + public String group() { + return ctx.group; + } + public void login(String id) { ctx.login = id; } + public String login() { + return ctx.login; + } + public void desc(String desc) { ctx.desc = desc; } + public String desc() { + return ctx.desc; + } + public String httpMethod() { return ctx.http_method; } @@ -81,4 +106,8 @@ public long txid() { public long gxid() { return ctx.gxid; } + + public TraceContext inner(){ + return this.ctx; + } } diff --git a/scouter.agent.java/src/scouter/agent/plugin/WrHttpCallRequest.java b/scouter.agent.java/src/scouter/agent/plugin/WrHttpCallRequest.java new file mode 100644 index 000000000..a134ce9fe --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/plugin/WrHttpCallRequest.java @@ -0,0 +1,94 @@ +/* + * 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.plugin; + +import java.net.HttpURLConnection; + +import scouter.agent.Logger; +import scouter.agent.proxy.IHttpClient; +import scouter.util.ObjectUtil; + +public class WrHttpCallRequest extends Wrapper { + protected static Class[] arg_c_ss = { String.class, String.class }; + + private Object reqObject; + private java.lang.reflect.Method addHeader; + + private HttpURLConnection urlCon; + private IHttpClient httpclient; + + private boolean enabled = true; + private Throwable _error; + + + public WrHttpCallRequest(HttpURLConnection req) { + this.urlCon = req; + } + + public WrHttpCallRequest(Object req) { + this.reqObject = req; + } + + public WrHttpCallRequest(IHttpClient httpclient, Object req) { + this.httpclient = httpclient; + this.reqObject = req; + } + + public void header(Object key, Object value) { + if (enabled == false || key == null || value == null) + return; + try { + if (this.urlCon != null) { + this.urlCon.setRequestProperty(toString(key), toString(value)); + return; + } + if(this.httpclient!=null){ + this.httpclient.addHeader(reqObject, toString(key), toString(value)); + return; + } + if (addHeader == null) { + addHeader = this.reqObject.getClass().getMethod("addHeader", arg_c_ss); + addHeader.setAccessible(true); + } + addHeader.invoke(reqObject, new Object[] { toString(key), toString(value) }); + } catch (Throwable e) { + enabled = false; + _error = e; + Logger.println("A900", e); + } + } + + private String toString(Object value) { + String s = ObjectUtil.toString(value); + if (s.length() > 80) + return s.substring(0, 80); + return s; + } + + public Object inner() { + return this.reqObject; + } + + public boolean isOk() { + return enabled; + } + + public Throwable error() { + return _error; + } + +} diff --git a/scouter.agent.java/src/scouter/agent/plugin/RequestWrapper.java b/scouter.agent.java/src/scouter/agent/plugin/WrRequest.java similarity index 65% rename from scouter.agent.java/src/scouter/agent/plugin/RequestWrapper.java rename to scouter.agent.java/src/scouter/agent/plugin/WrRequest.java index 11cbe3e1a..7c402a0e7 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/RequestWrapper.java +++ b/scouter.agent.java/src/scouter/agent/plugin/WrRequest.java @@ -15,46 +15,57 @@ * limitations under the License. */ package scouter.agent.plugin; + import java.util.Enumeration; +import java.util.Set; +import java.util.TreeSet; + import scouter.agent.Logger; -public class RequestWrapper extends Wrapper{ - + +public class WrRequest extends Wrapper { + private Object reqObject; - - private static java.lang.reflect.Method getRequestURI; - private static java.lang.reflect.Method getRemoteAddr; - private static java.lang.reflect.Method getMethod; - private static java.lang.reflect.Method getParameterNames; - private static java.lang.reflect.Method getParameter; - private static java.lang.reflect.Method getHeaderNames; - private static java.lang.reflect.Method getHeader; - private static java.lang.reflect.Method getQueryString; - private static java.lang.reflect.Method getSession; - private static java.lang.reflect.Method getCookies; - private static java.lang.reflect.Method getName; - private static java.lang.reflect.Method getValue; - private static java.lang.reflect.Method getSessionAttribute; - - private static boolean enabled = true; - - public RequestWrapper(Object req) { + + private java.lang.reflect.Method getRequestURI; + private java.lang.reflect.Method getRemoteAddr; + private java.lang.reflect.Method getMethod; + private java.lang.reflect.Method getParameterNames; + private java.lang.reflect.Method getParameter; + private java.lang.reflect.Method getHeaderNames; + private java.lang.reflect.Method getHeader; + private java.lang.reflect.Method getQueryString; + private java.lang.reflect.Method getSession; + private java.lang.reflect.Method getCookies; + private java.lang.reflect.Method getName; + private java.lang.reflect.Method getValue; + private java.lang.reflect.Method getSessionAttribute; + private java.lang.reflect.Method getAttribute; + + private boolean enabled = true; + private Throwable _error = null; + + public WrRequest(Object req) { reqObject = req; } + public String getCookie(String key) { if (enabled == false) return null; try { if (getCookies == null) { getCookies = this.reqObject.getClass().getMethod("getCookies", arg_c); + getCookies.setAccessible(true); } Object[] c = (Object[]) getCookies.invoke(reqObject, arg_o); if (c == null && c.length == 0) return null; if (getName == null) { getName = c[0].getClass().getMethod("getName", arg_c); + getName.setAccessible(true); } if (getValue == null) { getValue = c[0].getClass().getMethod("getValue", arg_c); + getValue.setAccessible(true); } for (int i = 0; i < c.length; i++) { if (key.equals(getName.invoke(c[i], arg_o))) { @@ -62,156 +73,243 @@ public String getCookie(String key) { } } } catch (Throwable e) { - e.printStackTrace(); - Logger.println("A163", e); enabled = false; + _error = e; } return null; } + public String getRequestURI() { if (enabled == false) return null; try { if (getRequestURI == null) { getRequestURI = this.reqObject.getClass().getMethod("getRequestURI", arg_c); + getRequestURI.setAccessible(true); } return (String) getRequestURI.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A164", e); return null; } } + public String getRemoteAddr() { if (enabled == false) return null; try { if (getRemoteAddr == null) { getRemoteAddr = this.reqObject.getClass().getMethod("getRemoteAddr", arg_c); + getRemoteAddr.setAccessible(true); } return (String) getRemoteAddr.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A165", e); return null; } } + public String getMethod() { if (enabled == false) return null; try { if (getMethod == null) { getMethod = this.reqObject.getClass().getMethod("getMethod", arg_c); + getMethod.setAccessible(true); } return (String) getMethod.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A166", e); return null; } } + public String getQueryString() { if (enabled == false) return null; try { if (getQueryString == null) { getQueryString = this.reqObject.getClass().getMethod("getQueryString", arg_c); + getQueryString.setAccessible(true); } return (String) getQueryString.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A167", e); return null; } } + public String getParameter(String key) { if (enabled == false) return null; try { if (getParameter == null) { getParameter = this.reqObject.getClass().getMethod("getParameter", arg_c_s); + getParameter.setAccessible(true); } return (String) getParameter.invoke(reqObject, new Object[] { key }); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A168", e); return null; } } + + public Object getAttribute(String key) { + if (enabled == false) + return null; + try { + if (getAttribute == null) { + getAttribute = this.reqObject.getClass().getMethod("getAttribute", arg_c_s); + getAttribute.setAccessible(true); + } + return getAttribute.invoke(reqObject, new Object[] { key }); + } catch (Throwable e) { + enabled = false; + Logger.println("A168", e); + return null; + } + } + public String getHeader(String key) { if (enabled == false) return null; try { if (getHeader == null) { getHeader = this.reqObject.getClass().getMethod("getHeader", arg_c_s); + getHeader.setAccessible(true); } return (String) getHeader.invoke(reqObject, new Object[] { key }); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A169", e); return null; } } + public Enumeration getParameterNames() { if (enabled == false) return null; try { if (getParameterNames == null) { getParameterNames = this.reqObject.getClass().getMethod("getParameterNames", arg_c); + getParameterNames.setAccessible(true); } return (Enumeration) getParameterNames.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A170", e); return null; } } + public Enumeration getHeaderNames() { if (enabled == false) return null; try { if (getHeaderNames == null) { getHeaderNames = this.reqObject.getClass().getMethod("getHeaderNames", arg_c); + getHeaderNames.setAccessible(true); } return (Enumeration) getHeaderNames.invoke(reqObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; return null; } } - public SessionWrapper getSession() { + + public WrSession getSession() { if (enabled == false) return null; try { if (getSession == null) { getSession = this.reqObject.getClass().getMethod("getSession", arg_c_z); + getSession.setAccessible(true); } Object o = getSession.invoke(reqObject, new Object[] { false }); - return new SessionWrapper(o); + return new WrSession(o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A171", e); return null; } } + + public Set getSessionNames() { + if (enabled == false) + return null; + try { + TreeSet names = new TreeSet(); + if (getSession == null) { + getSession = this.reqObject.getClass().getMethod("getSession", arg_c_z); + getSession.setAccessible(true); + } + Object o = getSession.invoke(reqObject, new Object[] { false }); + if (o == null) + return names; + Enumeration en = new WrSession(o).getAttributeNames(); + if (en != null) { + while (en.hasMoreElements()) { + names.add(en.nextElement()); + } + } + return names; + } catch (Throwable e) { + enabled = false; + _error = e; + Logger.println("A171", e); + return null; + } + + } + public Object getSessionAttribute(String key) { if (enabled == false) return null; try { if (getSession == null) { getSession = this.reqObject.getClass().getMethod("getSession", arg_c_z); + getSession.setAccessible(true); } Object o = getSession.invoke(reqObject, new Object[] { false }); if (o == null) return null; if (getSessionAttribute == null) { getSessionAttribute = o.getClass().getMethod("getAttribute", arg_c_s); + getSessionAttribute.setAccessible(true); } return getSessionAttribute.invoke(o, new Object[] { key }); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A172", e); return null; } } + + public Object inner() { + return this.reqObject; + } + + public boolean isOk() { + return enabled; + } + + public Throwable error() { + return _error; + } + } diff --git a/scouter.agent.java/src/scouter/agent/plugin/ResponseWrapper.java b/scouter.agent.java/src/scouter/agent/plugin/WrResponse.java similarity index 73% rename from scouter.agent.java/src/scouter/agent/plugin/ResponseWrapper.java rename to scouter.agent.java/src/scouter/agent/plugin/WrResponse.java index fe7083144..c70f46c83 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/ResponseWrapper.java +++ b/scouter.agent.java/src/scouter/agent/plugin/WrResponse.java @@ -20,17 +20,19 @@ import scouter.agent.Logger; -public class ResponseWrapper extends Wrapper{ +public class WrResponse extends Wrapper { private Object resObject; - private static java.lang.reflect.Method getWriter; - private static java.lang.reflect.Method getContentType; - private static java.lang.reflect.Method getCharacterEncoding; + private Throwable _error; - private static boolean enabled = true; + private java.lang.reflect.Method getWriter; + private java.lang.reflect.Method getContentType; + private java.lang.reflect.Method getCharacterEncoding; - public ResponseWrapper(Object res) { + private boolean enabled = true; + + public WrResponse(Object res) { resObject = res; } @@ -40,10 +42,12 @@ public PrintWriter getWriter() { try { if (getWriter == null) { getWriter = this.resObject.getClass().getMethod("getWriter", arg_c); + getWriter.setAccessible(true); } return (java.io.PrintWriter) getWriter.invoke(resObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A173", e); return null; } @@ -55,10 +59,12 @@ public String getContentType() { try { if (getContentType == null) { getContentType = this.resObject.getClass().getMethod("getContentType", arg_c); + getContentType.setAccessible(true); } return (String) getContentType.invoke(resObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A174", e); return null; } @@ -70,13 +76,27 @@ public String getCharacterEncoding() { try { if (getCharacterEncoding == null) { getCharacterEncoding = this.resObject.getClass().getMethod("getCharacterEncoding", arg_c); + getCharacterEncoding.setAccessible(true); } return (String) getCharacterEncoding.invoke(resObject, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A175", e); return null; } } + public Object inner() { + return this.resObject; + } + + public boolean isOk() { + return enabled; + } + + public Throwable error() { + return _error; + } + } diff --git a/scouter.agent.java/src/scouter/agent/plugin/SessionWrapper.java b/scouter.agent.java/src/scouter/agent/plugin/WrSession.java similarity index 56% rename from scouter.agent.java/src/scouter/agent/plugin/SessionWrapper.java rename to scouter.agent.java/src/scouter/agent/plugin/WrSession.java index 2a2ca63a4..ee1a8c284 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/SessionWrapper.java +++ b/scouter.agent.java/src/scouter/agent/plugin/WrSession.java @@ -20,49 +20,64 @@ import scouter.agent.Logger; -public class SessionWrapper extends Wrapper { +public class WrSession extends Wrapper { - private Object reqObject; + private Object session; - private static java.lang.reflect.Method getAttribute; - private static java.lang.reflect.Method getAttributeNames; + private java.lang.reflect.Method getAttribute; + private java.lang.reflect.Method getAttributeNames; - private static boolean enabled = true; + private boolean enabled = true; + private Throwable _error; - public SessionWrapper(Object req) { - if (req == null) { - enabled = false; - } - reqObject = req; + public WrSession(Object session) { + this.session = session; } public Object getAttribute(String key) { - if (enabled == false) + if (enabled == false || session == null) return null; try { if (getAttribute == null) { - getAttribute = this.reqObject.getClass().getMethod("getAttribute", arg_c_s); + getAttribute = this.session.getClass().getMethod("getAttribute", arg_c_s); + getAttribute.setAccessible(true); } - return getAttribute.invoke(reqObject, new Object[] { key }); + return getAttribute.invoke(session, new Object[] { key }); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A176", e); return null; } } public Enumeration getAttributeNames() { - if (enabled == false) + if (enabled == false || session == null) return null; try { if (getAttributeNames == null) { - getAttributeNames = this.reqObject.getClass().getMethod("getAttributeNames", arg_c); + getAttributeNames = this.session.getClass().getMethod("getAttributeNames", arg_c); + getAttributeNames.setAccessible(true); } - return (Enumeration) getAttributeNames.invoke(reqObject, arg_o); + return (Enumeration) getAttributeNames.invoke(session, arg_o); } catch (Throwable e) { enabled = false; + _error = e; Logger.println("A177", e); return null; } } + + public Object inner() { + return this.session; + } + + public boolean isOk() { + return enabled; + } + + public Throwable error() { + return _error; + } + } diff --git a/scouter.agent.java/src/scouter/agent/trace/HookArgs.java b/scouter.agent.java/src/scouter/agent/trace/HookArgs.java new file mode 100644 index 000000000..a21bdd795 --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/trace/HookArgs.java @@ -0,0 +1,48 @@ +/* + * 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.trace; + +public class HookArgs { + public String class1; + public String method; + public String desc; + public Object this1; + public Object[] args; + + public HookArgs(String className, String methodName, String methodDesc, Object this1, Object[] args) { + this.class1 = className; + this.method = methodName; + this.desc = methodDesc; + this.this1 = this1; + this.args = args; + } + public String getClassName(){ + return this.class1; + } + public String getMethodName(){ + return this.method; + } + public String getMethodDesc(){ + return this.desc; + } + public Object getThis(){ + return this.this1; + } + public Object[] getArgs(){ + return this.args; + } +} \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/trace/HookReturn.java b/scouter.agent.java/src/scouter/agent/trace/HookReturn.java new file mode 100644 index 000000000..a227079e3 --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/trace/HookReturn.java @@ -0,0 +1,48 @@ +/* + * 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.trace; + +public class HookReturn { + public String class1; + public String method; + public String desc; + public Object this1; + public Object return1; + + public HookReturn(String className, String methodName, String methodDesc, Object this1, Object return1) { + this.class1 = className; + this.method = methodName; + this.desc = methodDesc; + this.this1 = this1; + this.return1 = return1; + } + public String getClassName(){ + return this.class1; + } + public String getMethodName(){ + return this.method; + } + public String getMethodDesc(){ + return this.desc; + } + public Object getThis(){ + return this.this1; + } + public Object getReturn(){ + return this.return1; + } +} \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceApiCall.java b/scouter.agent.java/src/scouter/agent/trace/TraceApiCall.java index c88f807a3..7ec1edb44 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceApiCall.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceApiCall.java @@ -24,7 +24,7 @@ import scouter.agent.Logger; import scouter.agent.counter.meter.MeterAPI; import scouter.agent.netio.data.DataProxy; -import scouter.agent.plugin.HttpServiceTracePlugIn; +import scouter.agent.plugin.PluginHttpServiceTrace; import scouter.agent.summary.ServiceSummary; import scouter.agent.trace.api.ApiCallTraceHelper; import scouter.lang.step.ApiCallStep; @@ -48,7 +48,7 @@ public Stat(TraceContext ctx) { } static { try { - HttpServiceTracePlugIn.class.getClass(); + PluginHttpServiceTrace.class.getClass(); } catch (Throwable t) { } } @@ -69,7 +69,7 @@ public static Object startApicall(String className, String methodName, String me } // System.out.println("apicall start: " +ctx.apicall_name + // " target="+ctx.apicall_target); - HookPoint hookPoint = new HookPoint(className, methodName, methodDesc, _this, arg); + HookArgs hookPoint = new HookArgs(className, methodName, methodDesc, _this, arg); ApiCallStep step = ApiCallTraceHelper.start(ctx, hookPoint); if (step == null) return null; diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceContext.java b/scouter.agent.java/src/scouter/agent/trace/TraceContext.java index c5df3b001..f64c670be 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceContext.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceContext.java @@ -17,7 +17,6 @@ package scouter.agent.trace; -import scouter.agent.netio.data.DataProxy; import scouter.util.SysJMX; public class TraceContext { @@ -53,7 +52,8 @@ public TraceContext(boolean profile_summary) { public byte xType; public int serviceHash; public String serviceName; - public byte[] remoteAddr; + public String remoteIp; + public int error; public boolean done_http_service; public String http_method; @@ -93,6 +93,7 @@ public TraceContext(boolean profile_summary) { public int web_time; public int userTransaction; public boolean debug_sql_call; + public String group; public TraceContext createChild() { TraceContext child = new TraceContext(this.isSummary); @@ -115,7 +116,7 @@ public TraceContext createChild() { child.xType = this.xType; child.serviceHash = this.serviceHash; child.serviceName = this.serviceName; - child.remoteAddr = this.remoteAddr; + child.remoteIp = this.remoteIp; // child.error = this.error; child.done_http_service = this.done_http_service; diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceMain.java b/scouter.agent.java/src/scouter/agent/trace/TraceMain.java index c60b22528..b2a5974cd 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceMain.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceMain.java @@ -15,6 +15,7 @@ * limitations under the License. */ package scouter.agent.trace; + import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.counter.meter.MeterService; @@ -22,9 +23,9 @@ import scouter.agent.error.REQUEST_REJECT; import scouter.agent.error.USERTX_NOT_CLOSE; import scouter.agent.netio.data.DataProxy; -import scouter.agent.plugin.CapturePlugIn; -import scouter.agent.plugin.HttpServiceTracePlugIn; -import scouter.agent.plugin.ServiceTracePlugIn; +import scouter.agent.plugin.PluginCaptureTrace; +import scouter.agent.plugin.PluginHttpServiceTrace; +import scouter.agent.plugin.PluginAppServiceTrace; import scouter.agent.proxy.HttpTraceFactory; import scouter.agent.proxy.IHttpTrace; import scouter.agent.summary.ServiceSummary; @@ -40,22 +41,27 @@ import scouter.util.StringUtil; import scouter.util.SysJMX; import scouter.util.ThreadUtil; + public class TraceMain { public static class Stat { public TraceContext ctx; public Object req; public Object res; public boolean isStaticContents; + public Stat(TraceContext ctx, Object req, Object res) { this.ctx = ctx; this.req = req; this.res = res; } + public Stat(TraceContext ctx) { this.ctx = ctx; } } + private static IHttpTrace http = null; + public static Object startHttpService(Object req, Object res) { try { TraceContext ctx = TraceContextManager.getLocalContext(); @@ -72,6 +78,7 @@ public static Object startHttpService(Object req, Object res) { } return null; } + public static Object startHttpFilter(Object req, Object res) { try { TraceContext ctx = TraceContextManager.getLocalContext(); @@ -84,8 +91,10 @@ public static Object startHttpFilter(Object req, Object res) { } return null; } + private static Error REJECT = new REQUEST_REJECT("service rejected"); private static Error userTxNotClose = new USERTX_NOT_CLOSE("Missing Commit/Rollback Error"); + public static Object reject(Object stat, Object req, Object res) { Configure conf = Configure.getInstance(); if (conf.enable_reject_service) { @@ -98,7 +107,7 @@ public static Object reject(Object stat, Object req, Object res) { if (stat0.isStaticContents) return null; // reject by customized plugin - if (HttpServiceTracePlugIn.reject(stat0.ctx, req, res) + if (PluginHttpServiceTrace.reject(stat0.ctx, req, res) // reject by max_active_service || TraceContextManager.size() > conf.max_active_service) { // howto reject @@ -114,6 +123,7 @@ public static Object reject(Object stat, Object req, Object res) { } return null; } + private static void addSeviceName(TraceContext ctx, Object req) { try { Configure conf = Configure.getInstance(); @@ -153,7 +163,9 @@ private static void addSeviceName(TraceContext ctx, Object req) { } catch (Throwable t) { } } + private static Object lock = new Object(); + private static Object startHttp(Object req, Object res) { if (http == null) { initHttp(req); @@ -172,13 +184,14 @@ private static Object startHttp(Object req, Object res) { ctx.serviceName = "Non-URI"; Stat stat = new Stat(ctx, req, res); stat.isStaticContents = isStaticContents(ctx.serviceName); - - if(stat.isStaticContents ==false){ - HttpServiceTracePlugIn.start(ctx, req, res); + + if (stat.isStaticContents == false) { + PluginHttpServiceTrace.start(ctx, req, res); } - + return stat; } + private static void initHttp(Object req) { synchronized (lock) { if (http == null) { @@ -186,6 +199,7 @@ private static void initHttp(Object req) { } } } + public static void endHttpService(Object stat, Throwable thr) { try { Stat stat0 = (Stat) stat; @@ -217,12 +231,22 @@ public static void endHttpService(Object stat, Throwable thr) { return; } TraceContext ctx = stat0.ctx; + // HTTP END http.end(ctx, stat0.req, stat0.res); - TraceContextManager.end(ctx.threadId); - Configure conf = Configure.getInstance(); + + // static-contents -> stop processing if (stat0.isStaticContents) { + TraceContextManager.end(ctx.threadId); return; } + // Plug-in end + PluginHttpServiceTrace.end(ctx, stat0.req, stat0.res); + + // profile close + TraceContextManager.end(ctx.threadId); + + Configure conf = Configure.getInstance(); + XLogPack pack = new XLogPack(); // pack.endTime = System.currentTimeMillis(); pack.elapsed = (int) (System.currentTimeMillis() - ctx.startTime); @@ -238,7 +262,7 @@ public static void endHttpService(Object stat, Throwable thr) { pack.status = ctx.status; pack.sqlCount = ctx.sqlCount; pack.sqlTime = ctx.sqlTime; - pack.ipaddr = ctx.remoteAddr; + pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); pack.userid = ctx.userid; // //////////////////////////////////////////////////////// if (ctx.error != 0) { @@ -268,9 +292,12 @@ public static void endHttpService(Object stat, Throwable thr) { } } else if (ctx.userTransaction > 0) { pack.error = DataProxy.sendError("Missing Commit/Rollback Error"); - ServiceSummary.getInstance().process(userTxNotClose, pack.error,ctx.serviceHash, ctx.txid, 0, 0); - } - // pack.divPerf = ctx.divPerf; + ServiceSummary.getInstance().process(userTxNotClose, pack.error, ctx.serviceHash, ctx.txid, 0, 0); + } + + if (ctx.group != null) { + pack.group = DataProxy.sendGroup(ctx.group); + } pack.userAgent = ctx.userAgent; pack.referer = ctx.referer; // 2015.02.02 @@ -288,7 +315,6 @@ public static void endHttpService(Object stat, Throwable thr) { pack.webTime = ctx.web_time; } metering(pack); - HttpServiceTracePlugIn.end(ctx, pack); if (sendOk) { DataProxy.sendXLog(pack); } @@ -296,6 +322,7 @@ public static void endHttpService(Object stat, Throwable thr) { Logger.println("A146", e); } } + public static void metering(XLogPack pack) { switch (pack.xType) { case XLogTypes.WEB_SERVICE: @@ -306,6 +333,7 @@ public static void metering(XLogPack pack) { case XLogTypes.BACK_THREAD: } } + private static boolean isStaticContents(String serviceName) { int x = serviceName.lastIndexOf('.'); if (x <= 0) @@ -317,8 +345,9 @@ private static boolean isStaticContents(String serviceName) { return false; } } - public static Object startService(String name, String className, String methodName, String methodDesc, - Object _this, Object[] arg, byte xType) { + + public static Object startService(String name, String className, String methodName, String methodDesc, Object _this, + Object[] arg, byte xType) { try { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx != null) { @@ -337,13 +366,14 @@ public static Object startService(String name, String className, String methodNa ctx.bytes = SysJMX.getCurrentThreadAllocBytes(); ctx.profile_thread_cputime = conf.profile_thread_cputime; ctx.xType = xType; - ServiceTracePlugIn.start(ctx, new HookPoint(className, methodName, methodDesc, _this, arg)); + PluginAppServiceTrace.start(ctx, new HookArgs(className, methodName, methodDesc, _this, arg)); return new Stat(ctx); } catch (Throwable t) { Logger.println("A147", t); } return null; } + public static void endService(Object stat, Object returnValue, Throwable thr) { try { Stat stat0 = (Stat) stat; @@ -353,7 +383,10 @@ public static void endService(Object stat, Object returnValue, Throwable thr) { if (ctx == null) { return; } + + PluginAppServiceTrace.end(ctx); TraceContextManager.end(ctx.threadId); + XLogPack pack = new XLogPack(); pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); // pack.endTime = System.currentTimeMillis(); @@ -364,13 +397,13 @@ public static void endService(Object stat, Object returnValue, Throwable thr) { pack.service = ctx.serviceHash; pack.xType = ctx.xType; pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - pack.bytes = (int) (SysJMX.getCurrentThreadAllocBytes() - ctx.bytes); + pack.bytes = (int) (SysJMX.getCurrentThreadAllocBytes() - ctx.bytes); pack.status = ctx.status; pack.sqlCount = ctx.sqlCount; pack.sqlTime = ctx.sqlTime; pack.txid = ctx.txid; pack.gxid = ctx.gxid; - pack.ipaddr = ctx.remoteAddr; + pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); pack.userid = ctx.userid; if (ctx.error != 0) { pack.error = ctx.error; @@ -393,8 +426,14 @@ public static void endService(Object stat, Object returnValue, Throwable thr) { ServiceSummary.getInstance().process(thr, pack.error, ctx.serviceHash, ctx.txid, 0, 0); } else if (ctx.userTransaction > 0) { pack.error = DataProxy.sendError("Missing Commit/Rollback Error"); - ServiceSummary.getInstance().process(userTxNotClose, pack.error,ctx.serviceHash, ctx.txid, 0, 0); + ServiceSummary.getInstance().process(userTxNotClose, pack.error, ctx.serviceHash, ctx.txid, 0, 0); + } + + // 2015.11.10 + if (ctx.group != null) { + pack.group = DataProxy.sendGroup(ctx.group); } + // 2015.02.02 pack.apicallCount = ctx.apicall_count; pack.apicallTime = ctx.apicall_time; @@ -404,7 +443,7 @@ public static void endService(Object stat, Object returnValue, Throwable thr) { if (ctx.desc != null) { pack.desc = DataProxy.sendDesc(ctx.desc); } - ServiceTracePlugIn.end(ctx, pack); + metering(pack); if (sendOk) { DataProxy.sendXLog(pack); @@ -413,19 +452,22 @@ public static void endService(Object stat, Object returnValue, Throwable thr) { Logger.println("A148", t); } } - public static void capArgs(String className, String methodName, String methodDesc, Object[] arg) { + + public static void capArgs(String className, String methodName, String methodDesc, Object this1, Object[] arg) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) return; -// MessageStep step = new MessageStep(); -// step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); -// if (ctx.profile_thread_cputime) { -// step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); -// } -// step.message = toString("CAP-ARG", className, methodName, methodDesc, arg); -// ctx.profile.add(step); - CapturePlugIn.capArgs(ctx, className, methodName, methodDesc, arg); + // MessageStep step = new MessageStep(); + // step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + // if (ctx.profile_thread_cputime) { + // step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + // } + // step.message = toString("CAP-ARG", className, methodName, methodDesc, + // arg); + // ctx.profile.add(step); + PluginCaptureTrace.capArgs(ctx, new HookArgs(className, methodName, methodDesc, this1, arg)); } + public static void jspServlet(Object[] arg) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null || arg.length < 3) @@ -438,6 +480,7 @@ public static void jspServlet(Object[] arg) { step.message = "JSP " + arg[2]; ctx.profile.add(step); } + private static String toString(String type, String className, String methodName, String methodDesc, Object[] arg) { StringBuffer sb = new StringBuffer(); sb.append(type).append(" "); @@ -457,6 +500,7 @@ private static String toString(String type, String className, String methodName, sb.append("]"); return sb.toString(); } + private static String toStringRTN(String type, String className, String methodName, String methodDesc, Object arg) { StringBuffer sb = new StringBuffer(); sb.append(type).append(" "); @@ -469,6 +513,7 @@ private static String toStringRTN(String type, String className, String methodNa sb.append("]"); return sb.toString(); } + private static String toStringTHIS(String type, String className, String methodDesc, Object arg) { StringBuffer sb = new StringBuffer(); sb.append(type).append(" "); @@ -479,33 +524,31 @@ private static String toStringTHIS(String type, String className, String methodD sb.append("]"); return sb.toString(); } + public static void capThis(String className, String methodDesc, Object this0) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) return; -// MessageStep step = new MessageStep(); -// step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); -// if (ctx.profile_thread_cputime) { -// step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); -// } -// step.message = toStringTHIS("CAP-THIS", className, methodDesc, this0); -// ctx.profile.add(step); - CapturePlugIn.capThis(ctx, className, methodDesc, this0); + // MessageStep step = new MessageStep(); + // step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + // if (ctx.profile_thread_cputime) { + // step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + // } + // step.message = toStringTHIS("CAP-THIS", className, methodDesc, + // this0); + // ctx.profile.add(step); + PluginCaptureTrace.capThis(ctx, className, methodDesc, this0); } - public static void capReturn(String className, String methodName, String methodDesc, Object rtn) { + + public static void capReturn(String className, String methodName, String methodDesc, Object this1, Object rtn) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) return; -// MessageStep step = new MessageStep(); -// step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); -// if (ctx.profile_thread_cputime) { -// step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); -// } -// step.message = toStringRTN("CAP-RTN", className, methodName, methodDesc, rtn); -// ctx.profile.add(step); - CapturePlugIn.capReturn(ctx, className, methodName, methodDesc, rtn); + PluginCaptureTrace.capReturn(ctx, new HookReturn(className,methodName, methodDesc, this1, rtn)); } + private static Configure conf = Configure.getInstance(); + public static Object startMethod(int hash, String classMethod) { if (conf.trace_method_enabled == false) return null; @@ -533,6 +576,7 @@ public static Object startMethod(int hash, String classMethod) { ctx.profile.push(p); return new LocalContext(ctx, p); } + public static void endMethod(Object stat, Throwable thr) { if (stat == null) return; @@ -553,6 +597,7 @@ public static void endMethod(Object stat, Throwable thr) { } tctx.profile.pop(step); } + public static void setServiceName(String name) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null || name == null) @@ -560,12 +605,14 @@ public static void setServiceName(String name) { ctx.serviceName = name; ctx.serviceHash = HashUtil.hash(name); } + public static void setStatus(int httpStatus) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) return; ctx.status = httpStatus; } + public static XLogPack txperf(long endtime, long txid, int service_hash, String serviceName, int elapsed, int cpu, int sqlCount, int sqlTime, String remoteAddr, String error, long visitor) { XLogPack pack = new XLogPack(); @@ -589,6 +636,7 @@ public static XLogPack txperf(long endtime, long txid, int service_hash, String MeterUsers.add(pack.userid); return pack; } + public static void addMessage(String msg) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java index 992527cbb..ffa78c8a0 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java @@ -30,6 +30,7 @@ import scouter.agent.error.SLOW_SQL; import scouter.agent.error.TOO_MANY_RECORDS; import scouter.agent.netio.data.DataProxy; +import scouter.agent.plugin.PluginJdbcPoolTrace; import scouter.agent.summary.ServiceSummary; import scouter.jdbc.DetectConnection; import scouter.jdbc.WrConnection; @@ -172,8 +173,8 @@ public static Object start(Object o, String sql) { // Looking for the position of calling SQL COMMIT if (conf.profile_fullstack_sql_commit) { if ("commit".equalsIgnoreCase(sql)) { - ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), ThreadUtil - .getThreadStack())); + ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), + ThreadUtil.getThreadStack())); } } @@ -452,8 +453,8 @@ public static Object start(Object o, SqlParameter args) { // Looking for the position of calling SQL COMMIT if (conf.profile_fullstack_sql_commit) { if ("commit".equalsIgnoreCase(args.getSql())) { - ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), ThreadUtil - .getThreadStack())); + ctx.profile.add(new MessageStep((int) (System.currentTimeMillis() - ctx.startTime), + ThreadUtil.getThreadStack())); } } SqlStep2 step = new SqlStep2(); @@ -554,7 +555,7 @@ public static Object dbcOpenStart(int hash, String msg, Object pool) { p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); } - DBURL dbUrl = getUrl(pool); + DBURL dbUrl = getUrl(ctx, msg, pool); if (dbUrl != unknown) { hash = DataProxy.sendMethodName(dbUrl.url); } @@ -586,7 +587,11 @@ public DBURL(int hash, String url) { static IntKeyLinkedMap urlTable = new IntKeyLinkedMap().setMax(500); static DBURL unknown = new DBURL(0, null); - private static DBURL getUrl(Object pool) { + public static void clearUrlMap() { + urlTable.clear(); + } + + private static DBURL getUrl(TraceContext ctx, String msg, Object pool) { if (pool == null) return unknown; @@ -596,19 +601,20 @@ private static DBURL getUrl(Object pool) { return dbUrl; } try { - Field field = pool.getClass().getDeclaredField("url"); - if (field != null) { - field.setAccessible(true); - String u = "OPEN-DBC " + field.get(pool); + Method m = pool.getClass().getMethod("getUrl", new Class[0]); + if (m != null) { + String u = "OPEN-DBC " + m.invoke(pool, new Object[0]); dbUrl = new DBURL(HashUtil.hash(u), u); - } else { - Method m = pool.getClass().getMethod("getUrl", new Class[0]); - if (m != null) { - String u = "OPEN-DBC " + m.invoke(pool, new Object[0]); + } + } catch (Exception e) { + try { + String u = PluginJdbcPoolTrace.url(ctx, msg, pool); + if (u != null) { + u = "OPEN-DBC " + u; dbUrl = new DBURL(HashUtil.hash(u), u); } + } catch (Throwable ignore) { } - } catch (Throwable e) { } if (dbUrl == null) { dbUrl = unknown; @@ -691,8 +697,8 @@ public static void sqlMap(String methodName, String sqlname) { return; MessageStep p = new MessageStep(); p.start_time = (int) (System.currentTimeMillis() - ctx.startTime); - p.message = new StringBuffer(40).append("SQLMAP ").append(methodName).append(" { ").append(sqlname) - .append(" }").toString(); + p.message = new StringBuffer(40).append("SQLMAP ").append(methodName).append(" { ").append(sqlname).append(" }") + .toString(); ctx.profile.add(p); } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ApiCallTraceHelper.java b/scouter.agent.java/src/scouter/agent/trace/api/ApiCallTraceHelper.java index 128d2a698..c8f86e623 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ApiCallTraceHelper.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ApiCallTraceHelper.java @@ -20,13 +20,13 @@ import java.util.HashMap; import java.util.Map; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; public class ApiCallTraceHelper { static interface IHelper { - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint); + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint); } static Map handlers = new HashMap(); @@ -53,8 +53,8 @@ public static IHelper get(String name) { private static IHelper defaultObj = new ForDefault(); - public static ApiCallStep start(TraceContext ctx, HookPoint hookPoint) { - IHelper plug = handlers.get(hookPoint.className); + public static ApiCallStep start(TraceContext ctx, HookArgs hookPoint) { + IHelper plug = handlers.get(hookPoint.class1); if (plug == null) return defaultObj.process(ctx, hookPoint); return plug.process(ctx, hookPoint); diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForDefault.java b/scouter.agent.java/src/scouter/agent/trace/api/ForDefault.java index 5ef17e609..44cb962a5 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForDefault.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForDefault.java @@ -16,15 +16,15 @@ */ package scouter.agent.trace.api; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; public class ForDefault implements ApiCallTraceHelper.IHelper { - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient.java b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient.java index d25b473b1..8de66f94c 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient.java @@ -18,7 +18,7 @@ import java.lang.reflect.Method; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; @@ -26,11 +26,11 @@ public class ForHttpClient implements ApiCallTraceHelper.IHelper{ private boolean ok = true; - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { - if (ok && hookPoint.arg != null && hookPoint.arg.length == 3) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { + if (ok && hookPoint.args != null && hookPoint.args.length == 3) { try { - Method method = hookPoint.arg[1].getClass().getMethod("getURI"); - Object o = method.invoke(hookPoint.arg[1]); + Method method = hookPoint.args[1].getClass().getMethod("getURI"); + Object o = method.invoke(hookPoint.args[1]); if (o != null) { ctx.apicall_name = o.toString(); } @@ -41,7 +41,7 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { ApiCallStep step = new ApiCallStep(); if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient40.java b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient40.java index 5cc7bb85d..48f97ac57 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient40.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient40.java @@ -17,9 +17,11 @@ package scouter.agent.trace.api; import scouter.agent.Configure; +import scouter.agent.Logger; +import scouter.agent.plugin.PluginHttpCallTrace; import scouter.agent.proxy.HttpClient43Factory; import scouter.agent.proxy.IHttpClient; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.agent.trace.TraceContextManager; import scouter.lang.step.ApiCallStep; @@ -32,27 +34,27 @@ public class ForHttpClient40 implements ApiCallTraceHelper.IHelper { private static IntKeyLinkedMap httpclients = new IntKeyLinkedMap().setMax(5); - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); try { if (ok == false) - ctx.apicall_name = hookPoint.className + "." + hookPoint.methodName; + ctx.apicall_name = hookPoint.class1 + "." + hookPoint.method; - if (hookPoint.arg != null && hookPoint.arg.length >= 2) { + if (hookPoint.args != null && hookPoint.args.length >= 2) { IHttpClient httpclient = getProxy(hookPoint); step.txid = KeyGen.next(); - transfer(httpclient, ctx, hookPoint.arg[0], hookPoint.arg[1], step.txid); - String host = httpclient.getHost(hookPoint.arg[0]); + transfer(httpclient, ctx, hookPoint.args[0], hookPoint.args[1], step.txid); + String host = httpclient.getHost(hookPoint.args[0]); step.opt = 1; step.address = host; if (host != null) ctx.apicall_target = host; - ctx.apicall_name = httpclient.getURI(hookPoint.arg[1]); + ctx.apicall_name = httpclient.getURI(hookPoint.args[1]); } } catch (Exception e) { @@ -61,16 +63,16 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } - private IHttpClient getProxy(HookPoint hookPoint) { - int key = System.identityHashCode(hookPoint._this.getClass()); + private IHttpClient getProxy(HookArgs hookPoint) { + int key = System.identityHashCode(hookPoint.this1.getClass()); IHttpClient httpclient = httpclients.get(key); if (httpclient == null) { synchronized (this) { - httpclient = HttpClient43Factory.create(hookPoint._this.getClass().getClassLoader()); + httpclient = HttpClient43Factory.create(hookPoint.this1.getClass().getClassLoader()); httpclients.put(key, httpclient); } } @@ -89,8 +91,9 @@ private void transfer(IHttpClient httpclient, TraceContext ctx, Object host, Obj httpclient.addHeader(req, conf.gxid, Hexa32.toString32(ctx.gxid)); httpclient.addHeader(req, conf.caller_txid, Hexa32.toString32(ctx.txid)); httpclient.addHeader(req, conf.this_txid, Hexa32.toString32(calleeTxid)); - } catch (Exception e) { - System.err.println("AbstractHttpClient " + e); + PluginHttpCallTrace.call(ctx, req); + } catch (Throwable e) { + Logger.println("A001", e); ok = false; } } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient43.java b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient43.java index 164288b0b..03c4a4275 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient43.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpClient43.java @@ -15,54 +15,61 @@ * limitations under the License. */ package scouter.agent.trace.api; + import scouter.agent.Configure; import scouter.agent.Logger; +import scouter.agent.plugin.PluginHttpCallTrace; import scouter.agent.proxy.HttpClient43Factory; import scouter.agent.proxy.IHttpClient; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.agent.trace.TraceContextManager; import scouter.lang.step.ApiCallStep; import scouter.util.Hexa32; import scouter.util.IntKeyLinkedMap; import scouter.util.KeyGen; + public class ForHttpClient43 implements ApiCallTraceHelper.IHelper { private static IntKeyLinkedMap httpclients = new IntKeyLinkedMap().setMax(5); - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); if (ok) { try { - if (hookPoint.arg != null && hookPoint.arg.length >= 2) { + if (hookPoint.args != null && hookPoint.args.length >= 2) { IHttpClient httpclient = getProxy(hookPoint); step.txid = KeyGen.next(); - transfer(httpclient, ctx, hookPoint.arg[0], hookPoint.arg[1], step.txid); - String host = httpclient.getHost(hookPoint.arg[0]); + transfer(httpclient, ctx, hookPoint.args[0], hookPoint.args[1], step.txid); + String host = httpclient.getHost(hookPoint.args[0]); step.opt = 1; step.address = host; if (host != null) ctx.apicall_target = host; - ctx.apicall_name = httpclient.getURI(hookPoint.arg[1]); + ctx.apicall_name = httpclient.getURI(hookPoint.args[1]); } } catch (Exception e) { this.ok = false; } } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } - private IHttpClient getProxy(HookPoint hookPoint) { - int key = System.identityHashCode(hookPoint._this.getClass()); + + private IHttpClient getProxy(HookArgs hookPoint) { + int key = System.identityHashCode(hookPoint.this1.getClass()); IHttpClient httpclient = httpclients.get(key); if (httpclient == null) { synchronized (this) { - httpclient = HttpClient43Factory.create(hookPoint._this.getClass().getClassLoader()); + httpclient = HttpClient43Factory.create(hookPoint.this1.getClass().getClassLoader()); httpclients.put(key, httpclient); } } return httpclient; } + private boolean ok = true; + private void transfer(IHttpClient httpclient, TraceContext ctx, Object host, Object req, long calleeTxid) { Configure conf = Configure.getInstance(); if (conf.enable_trace_e2e) { @@ -73,6 +80,7 @@ private void transfer(IHttpClient httpclient, TraceContext ctx, Object host, Obj httpclient.addHeader(req, conf.gxid, Hexa32.toString32(ctx.gxid)); httpclient.addHeader(req, conf.caller_txid, Hexa32.toString32(ctx.txid)); httpclient.addHeader(req, conf.this_txid, Hexa32.toString32(calleeTxid)); + PluginHttpCallTrace.call(ctx, req); } catch (Exception e) { Logger.println("A178", e); ok = false; diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpURLConnection.java b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpURLConnection.java index 7363bf6c4..cdc2ac7d9 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForHttpURLConnection.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForHttpURLConnection.java @@ -21,7 +21,8 @@ import java.net.URL; import scouter.agent.Configure; -import scouter.agent.trace.HookPoint; +import scouter.agent.plugin.PluginHttpCallTrace; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; import scouter.util.Hexa32; @@ -43,19 +44,19 @@ public class ForHttpURLConnection implements ApiCallTraceHelper.IHelper { } } - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); try { - if (hookPoint._this instanceof sun.net.www.protocol.http.HttpURLConnection) { - if (inputStream.get(hookPoint._this) != null) { + if (hookPoint.this1 instanceof sun.net.www.protocol.http.HttpURLConnection) { + if (inputStream.get(hookPoint.this1) != null) { // Null  추적이 종료된다. return null; } } - HttpURLConnection urlCon = ((HttpURLConnection) hookPoint._this); - if ("connect".equals(hookPoint.methodName)) { + HttpURLConnection urlCon = ((HttpURLConnection) hookPoint.this1); + if ("connect".equals(hookPoint.method)) { step.txid = KeyGen.next(); transfer(ctx, urlCon, step.txid); ctx.callee = step.txid; @@ -79,7 +80,7 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } @@ -95,11 +96,13 @@ private void transfer(TraceContext ctx, HttpURLConnection urlCon, long calleeTxi urlCon.setRequestProperty(conf.gxid, Hexa32.toString32(ctx.gxid)); urlCon.setRequestProperty(conf.this_txid, Hexa32.toString32(calleeTxid)); urlCon.setRequestProperty(conf.caller_txid, Hexa32.toString32(ctx.txid)); + + PluginHttpCallTrace.call(ctx, urlCon); } catch (Throwable t) { } } } - public void checkTarget(HookPoint hookPoint) { + public void checkTarget(HookArgs hookPoint) { } } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForJCOClient.java b/scouter.agent.java/src/scouter/agent/trace/api/ForJCOClient.java index e58ffee87..867381b86 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForJCOClient.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForJCOClient.java @@ -16,21 +16,21 @@ */ package scouter.agent.trace.api; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; public class ForJCOClient implements ApiCallTraceHelper.IHelper { - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); - if (hookPoint.arg != null && hookPoint.arg.length > 0) { - ctx.apicall_name = hookPoint.arg[0] + "(JCO)"; + if (hookPoint.args != null && hookPoint.args.length > 0) { + ctx.apicall_name = hookPoint.args[0] + "(JCO)"; } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForNettyHttpRequest.java b/scouter.agent.java/src/scouter/agent/trace/api/ForNettyHttpRequest.java index ee6f655db..3cb302913 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForNettyHttpRequest.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForNettyHttpRequest.java @@ -17,9 +17,10 @@ package scouter.agent.trace.api; import scouter.agent.Configure; +import scouter.agent.plugin.PluginHttpCallTrace; import scouter.agent.proxy.IHttpClient; import scouter.agent.proxy.NettyHttpClientFactory; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; import scouter.util.Hexa32; @@ -31,19 +32,19 @@ public class ForNettyHttpRequest implements ApiCallTraceHelper.IHelper { private boolean ok = true; private static IntKeyLinkedMap httpclients = new IntKeyLinkedMap().setMax(5); - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); - if (ok && hookPoint.arg != null && hookPoint.arg.length >= 1) { + if (ok && hookPoint.args != null && hookPoint.args.length >= 1) { try { IHttpClient httpclient = getProxy(hookPoint); step.txid = KeyGen.next(); - transfer(httpclient, ctx, hookPoint.arg[0], step.txid); + transfer(httpclient, ctx, hookPoint.args[0], step.txid); step.opt = 1; step.address = null; - ctx.apicall_name = httpclient.getURI(hookPoint.arg[0]); + ctx.apicall_name = httpclient.getURI(hookPoint.args[0]); ctx.apicall_name = fw_stripes(ctx.apicall_name); } catch (Throwable e) { @@ -53,16 +54,16 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { } } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } - private IHttpClient getProxy(HookPoint hookPoint) { - int key = System.identityHashCode(hookPoint._this.getClass()); + private IHttpClient getProxy(HookArgs hookPoint) { + int key = System.identityHashCode(hookPoint.this1.getClass()); IHttpClient httpclient = httpclients.get(key); if (httpclient == null) { synchronized (this) { - httpclient = NettyHttpClientFactory.create(hookPoint._this.getClass().getClassLoader()); + httpclient = NettyHttpClientFactory.create(hookPoint.this1.getClass().getClassLoader()); httpclients.put(key, httpclient); } } @@ -85,6 +86,9 @@ private void transfer(IHttpClient httpclient, TraceContext ctx, Object req, long httpclient.addHeader(req, "scouter_caller_name", conf.objName); httpclient.addHeader(req, "scouter_thread_id", Long.toString(ctx.threadId)); + PluginHttpCallTrace.call(ctx, httpclient, req); + + } catch (Exception e) { } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForRibbonLB.java b/scouter.agent.java/src/scouter/agent/trace/api/ForRibbonLB.java index 81855d440..b00ba7713 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForRibbonLB.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForRibbonLB.java @@ -17,9 +17,10 @@ package scouter.agent.trace.api; import scouter.agent.Configure; +import scouter.agent.plugin.PluginHttpCallTrace; import scouter.agent.proxy.IHttpClient; import scouter.agent.proxy.NettyHttpClientFactory; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; import scouter.util.Hexa32; @@ -31,20 +32,20 @@ public class ForRibbonLB implements ApiCallTraceHelper.IHelper { private int fail = 0; private static IntKeyLinkedMap httpclients = new IntKeyLinkedMap().setMax(5); - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); - if (fail < 100 && hookPoint.arg != null && hookPoint.arg.length > 2) { + if (fail < 100 && hookPoint.args != null && hookPoint.args.length > 2) { try { IHttpClient httpclient = getProxy(hookPoint); step.txid = KeyGen.next(); - transfer(httpclient, ctx, hookPoint.arg[1], step.txid); - String host = httpclient.getHost(hookPoint.arg[0]); + transfer(httpclient, ctx, hookPoint.args[1], step.txid); + String host = httpclient.getHost(hookPoint.args[0]); step.opt = 1; step.address = host; - ctx.apicall_name = httpclient.getURI(hookPoint.arg[1]); + ctx.apicall_name = httpclient.getURI(hookPoint.args[1]); ctx.apicall_name = fw_stripes(ctx.apicall_name); } catch (Throwable e) { @@ -54,16 +55,16 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { } } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } - private IHttpClient getProxy(HookPoint hookPoint) { - int key = System.identityHashCode(hookPoint._this.getClass()); + private IHttpClient getProxy(HookArgs hookPoint) { + int key = System.identityHashCode(hookPoint.this1.getClass()); IHttpClient httpclient = httpclients.get(key); if (httpclient == null) { synchronized (this) { - httpclient = NettyHttpClientFactory.create(hookPoint._this.getClass().getClassLoader()); + httpclient = NettyHttpClientFactory.create(hookPoint.this1.getClass().getClassLoader()); httpclients.put(key, httpclient); } } @@ -84,7 +85,9 @@ private void transfer(IHttpClient httpclient, TraceContext ctx, Object req, long httpclient.addHeader(req, "scouter_caller_url", ctx.serviceName); httpclient.addHeader(req, "scouter_caller_name", conf.objName); httpclient.addHeader(req, "scouter_thread_id", Long.toString(ctx.threadId)); - + + PluginHttpCallTrace.call(ctx, httpclient, req); + } catch (Exception e) { } diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForSAPTemp.java b/scouter.agent.java/src/scouter/agent/trace/api/ForSAPTemp.java index 2d4ec8ea9..ae7fa8ed0 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForSAPTemp.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForSAPTemp.java @@ -16,27 +16,27 @@ */ package scouter.agent.trace.api; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; public class ForSAPTemp implements ApiCallTraceHelper.IHelper { - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); - if (hookPoint.arg != null && hookPoint.arg.length > 0) { - ctx.apicall_name = hookPoint.methodName + "(" + hookPoint.arg[0] + ")"; + if (hookPoint.args != null && hookPoint.args.length > 0) { + ctx.apicall_name = hookPoint.method + "(" + hookPoint.args[0] + ")"; } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } - public void apiEnd(TraceContext ctx, HookPoint hookPoint, Object returnValue, Throwable thr) { + public void apiEnd(TraceContext ctx, HookArgs hookPoint, Object returnValue, Throwable thr) { } - public void checkTarget(HookPoint hookPoint) { + public void checkTarget(HookArgs hookPoint) { } public String targetName() { diff --git a/scouter.agent.java/src/scouter/agent/trace/api/ForSunHttpClient.java b/scouter.agent.java/src/scouter/agent/trace/api/ForSunHttpClient.java index a5f0c84b0..9a08bda7e 100644 --- a/scouter.agent.java/src/scouter/agent/trace/api/ForSunHttpClient.java +++ b/scouter.agent.java/src/scouter/agent/trace/api/ForSunHttpClient.java @@ -19,13 +19,14 @@ import java.lang.reflect.Field; import java.net.URL; -import scouter.agent.trace.HookPoint; +import scouter.agent.trace.HookArgs; import scouter.agent.trace.TraceContext; import scouter.lang.step.ApiCallStep; public class ForSunHttpClient implements ApiCallTraceHelper.IHelper { static Class sunHttpClass = null; static Field url = null; + static { try { @@ -41,13 +42,13 @@ public class ForSunHttpClient implements ApiCallTraceHelper.IHelper { private boolean ok = true; - public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { + public ApiCallStep process(TraceContext ctx, HookArgs hookPoint) { ApiCallStep step = new ApiCallStep(); try { - if (ok && (hookPoint._this instanceof sun.net.www.http.HttpClient)) { - URL u = (URL) url.get(hookPoint._this); + if (ok && (hookPoint.this1 instanceof sun.net.www.http.HttpClient)) { + URL u = (URL) url.get(hookPoint.this1); if (u != null) { ctx.apicall_name = u.getPath(); } @@ -56,7 +57,7 @@ public ApiCallStep process(TraceContext ctx, HookPoint hookPoint) { ok = false; } if (ctx.apicall_name == null) - ctx.apicall_name = hookPoint.className; + ctx.apicall_name = hookPoint.class1; return step; } diff --git a/scouter.agent.java/src/scouter/test/TpsRush.java b/scouter.agent.java/src/scouter/test/TpsRush.java index fd36e5550..6e6845d1c 100644 --- a/scouter.agent.java/src/scouter/test/TpsRush.java +++ b/scouter.agent.java/src/scouter/test/TpsRush.java @@ -73,7 +73,7 @@ public static void main(String[] args) { while (true) { txcount++; - String serviceName = "service" + (next(r, 1000)); + String serviceName = "fdafafdafdafdafdfdsafaafda" + (next(r, 100000)); int service_hash = HashUtil.hash(serviceName); long txid = KeyGen.next(); profile(txid,service_hash); diff --git a/scouter.agent.java/src/scouter/xtra/http/HttpTrace.java b/scouter.agent.java/src/scouter/xtra/http/HttpTrace.java index aa26f6b46..f6775bc55 100644 --- a/scouter.agent.java/src/scouter/xtra/http/HttpTrace.java +++ b/scouter.agent.java/src/scouter/xtra/http/HttpTrace.java @@ -88,7 +88,8 @@ public void start(TraceContext ctx, Object req, Object res) { ctx.http_query = request.getQueryString(); ctx.http_content_type = request.getContentType(); - ctx.remoteAddr = IPUtil.toBytes(getRemoteAddr(request)); + ctx.remoteIp = getRemoteAddr(request); + try { switch (conf.mode_userid) { case 2: @@ -96,12 +97,14 @@ public void start(TraceContext ctx, Object req, Object res) { break; case 1: ctx.userid = UseridUtil.getUseridCustom(request, response, conf.userid_jsessionid); - if (ctx.userid == 0) { - ctx.userid = DataInputX.toInt(ctx.remoteAddr, 0); + if (ctx.userid == 0 && ctx.remoteIp != null) { + ctx.userid = HashUtil.hash(ctx.remoteIp); } break; default: - ctx.userid = DataInputX.toInt(ctx.remoteAddr, 0); + if (ctx.remoteIp != null) { + ctx.userid = HashUtil.hash(ctx.remoteIp); + } break; } MeterUsers.add(ctx.userid); @@ -115,7 +118,7 @@ public void start(TraceContext ctx, Object req, Object res) { String userAgent = request.getHeader("User-Agent"); if (userAgent != null) { ctx.userAgent = DataProxy.sendUserAgent(userAgent); - ctx.userAgentString=userAgent; + ctx.userAgentString = userAgent; } dump(ctx.profile, request, ctx); if (conf.enable_trace_e2e) { diff --git a/scouter.client.build/pom.xml b/scouter.client.build/pom.xml index 19d6a19da..29f0b066d 100644 --- a/scouter.client.build/pom.xml +++ b/scouter.client.build/pom.xml @@ -11,7 +11,7 @@ ../scouter.client.product - 0.22.0 + 0.24.0 http://download.eclipse.org/releases/mars UTF-8 @@ -62,4 +62,4 @@ - \ No newline at end of file + diff --git a/scouter.client/src/scouter/client/model/AgentModelThread.java b/scouter.client/src/scouter/client/model/AgentModelThread.java index cdfc10539..d4e836039 100644 --- a/scouter.client/src/scouter/client/model/AgentModelThread.java +++ b/scouter.client/src/scouter/client/model/AgentModelThread.java @@ -29,7 +29,6 @@ import scouter.client.net.INetReader; import scouter.client.net.TcpProxy; import scouter.client.server.ServerManager; -import scouter.client.util.ConsoleProxy; import scouter.io.DataInputX; import scouter.lang.counters.CounterEngine; import scouter.lang.pack.ObjectPack; @@ -74,6 +73,7 @@ public synchronized void fetchObjectList() { Map tempAgentMap = new HashMap(); ArrayList objectPackList = new ArrayList(); boolean existUnknownType = false; + existServerset.clear(); Set serverIdSet = ServerManager.getInstance().getOpenServerList(); if (serverIdSet.size() > 0) { Integer[] serverIds = serverIdSet.toArray(new Integer[serverIdSet.size()]); @@ -110,8 +110,11 @@ public void process(DataInputX in) throws IOException { existUnknownType = true; } } + if (agentList.size() > 0) { + existServerset.add(serverId); + } } catch (Exception e) { - ConsoleProxy.errorSafe(e.toString()); + e.printStackTrace(); } finally { TcpProxy.putTcpProxy(proxy); } @@ -123,6 +126,12 @@ public void process(DataInputX in) throws IOException { this.existUnknownType = existUnknownType; } + private Set existServerset = new HashSet(); + + public Set existServerSet() { + return existServerset; + } + public AgentObject getAgentObject(int objHash) { return agentMap.get(objHash); } diff --git a/scouter.client/src/scouter/client/net/ClientTCP.java b/scouter.client/src/scouter/client/net/ClientTCP.java index 02953d719..a7766bc7a 100644 --- a/scouter.client/src/scouter/client/net/ClientTCP.java +++ b/scouter.client/src/scouter/client/net/ClientTCP.java @@ -24,7 +24,6 @@ import scouter.client.server.Server; import scouter.client.server.ServerManager; -import scouter.client.util.ConsoleProxy; import scouter.io.DataInputX; import scouter.io.DataOutputX; import scouter.net.NetCafe; @@ -60,11 +59,11 @@ public void open(int serverId) { out.flush(); //*************// if (server.isConnected() == false) { - ConsoleProxy.infoSafe("Success to connect " + server.getIp() + ":" + server.getPort()); + System.out.println("Success to connect " + server.getIp() + ":" + server.getPort()); server.setConnected(true); } } catch (Throwable t) { - ConsoleProxy.errorSafe(t.toString()); + t.printStackTrace(); close(); server.setConnected(false); } diff --git a/scouter.client/src/scouter/client/net/LoginMgr.java b/scouter.client/src/scouter/client/net/LoginMgr.java index 52d4cd95d..1a4a85a38 100644 --- a/scouter.client/src/scouter/client/net/LoginMgr.java +++ b/scouter.client/src/scouter/client/net/LoginMgr.java @@ -20,7 +20,6 @@ import scouter.Version; import scouter.client.server.Server; import scouter.client.server.ServerManager; -import scouter.client.util.ConsoleProxy; import scouter.lang.counters.CounterEngine; import scouter.lang.pack.MapPack; import scouter.lang.pack.Pack; @@ -161,9 +160,8 @@ public static MapPack getCounterXmlServer(int serverId) { Pack p = null; try { p = tcp.getSingle(RequestCmd.GET_XML_COUNTER, null); - ConsoleProxy.infoSafe("- counter.xml is successfully"); } catch (Exception e) { - ConsoleProxy.errorSafe(e.toString()); + e.printStackTrace(); return null; } finally { TcpProxy.putTcpProxy(tcp); diff --git a/scouter.client/src/scouter/client/remote/handle/ActionControl.java b/scouter.client/src/scouter/client/remote/handle/ActionControl.java index b079c951c..b920db7ef 100644 --- a/scouter.client/src/scouter/client/remote/handle/ActionControl.java +++ b/scouter.client/src/scouter/client/remote/handle/ActionControl.java @@ -27,7 +27,6 @@ import scouter.client.server.ServerManager; import scouter.client.util.ConsoleProxy; import scouter.client.util.ExUtil; -import scouter.client.views.ObjectNavigationView; import scouter.lang.counters.CounterEngine; import scouter.lang.pack.MapPack; import scouter.lang.pack.Pack; @@ -83,7 +82,7 @@ public void refetchCounterXml(int serverId, final MapPack param) throws Exceptio if (v1 != null) { engine.parse(((BlobValue)v1).value); } - ObjectNavigationView.removeActionCache(serverId); + server.setDirty(true); ConsoleProxy.infoSafe("Applied Complete."); ConsoleProxy.infoSafe("***********************************"); } diff --git a/scouter.client/src/scouter/client/server/Server.java b/scouter.client/src/scouter/client/server/Server.java index cd420da8d..eb1a07259 100644 --- a/scouter.client/src/scouter/client/server/Server.java +++ b/scouter.client/src/scouter/client/server/Server.java @@ -18,7 +18,6 @@ package scouter.client.server; import scouter.client.net.ConnectionPool; -import scouter.client.views.ObjectNavigationView; import scouter.lang.counters.CounterEngine; import scouter.lang.value.MapValue; import scouter.util.HashUtil; @@ -45,6 +44,7 @@ public class Server { private long usedMemory; private long totalMemory; + private boolean dirty = false; private MapValue groupPolicyMap = new MapValue(); private MapValue menuEnableMap = new MapValue(); @@ -106,8 +106,6 @@ public boolean isConnected() { public void setConnected(boolean isConnected) { this.connected = isConnected; - if (isConnected == false) - ObjectNavigationView.removeActionCache(getId()); } public String getTimezone() { @@ -211,6 +209,14 @@ public void setMenuEnableMap(MapValue mv) { public boolean isEnableMenu(String key) { return menuEnableMap.getBoolean(key); } + + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + + public boolean isDirty() { + return this.dirty; + } public String toString() { return "Server [id=" + id + ", name=" + name + ", ip=" + ip + ", port=" diff --git a/scouter.client/src/scouter/client/server/ServerManager.java b/scouter.client/src/scouter/client/server/ServerManager.java index 97bdc8df0..a9a0799c9 100644 --- a/scouter.client/src/scouter/client/server/ServerManager.java +++ b/scouter.client/src/scouter/client/server/ServerManager.java @@ -22,8 +22,6 @@ import java.util.Set; import scouter.client.net.TcpProxy; -import scouter.client.util.ConsoleProxy; -import scouter.client.views.ObjectNavigationView; import scouter.lang.pack.MapPack; import scouter.net.RequestCmd; import scouter.util.HashUtil; @@ -89,7 +87,7 @@ private void syncServerTime() { server.setUsedMemory(usedMemory); server.setTotalMemory(totalMemory); } catch (Throwable th) { - //ConsoleProxy.errorSafe("SERVER_TIME : " + server.getName() + " " + th.getMessage()); + th.printStackTrace(); } finally { TcpProxy.putTcpProxy(tcp); } @@ -114,8 +112,7 @@ public void removeServer(int serverId) { Server remove = serverMap.remove(serverId); if (remove != null) { remove.close(); - ConsoleProxy.infoSafe("Disconneted : " + remove.getName()); - ObjectNavigationView.removeActionCache(remove.getId()); + System.out.println("Remove server : " + remove.getName()); } } diff --git a/scouter.client/src/scouter/client/views/ObjectNavigationView.java b/scouter.client/src/scouter/client/views/ObjectNavigationView.java index 710584237..343078b2e 100644 --- a/scouter.client/src/scouter/client/views/ObjectNavigationView.java +++ b/scouter.client/src/scouter/client/views/ObjectNavigationView.java @@ -144,6 +144,19 @@ public void refresh() { } else if (mode == PresentMode.FLAT_MODE) { makeFlatMap(); } + + Integer[] actionSet = counterActions.keySet().toArray(new Integer[counterActions.size()]); + Set existServerSet = agentThread.existServerSet(); + for (int serverId : actionSet) { + Server server = ServerManager.getInstance().getServer(serverId); + if (existServerSet.contains(serverId) == false || server == null) { + removeActionCache(serverId); + } else if (server.isDirty()) { + server.setDirty(false); + removeActionCache(serverId); + } + } + ExUtil.exec(agentTree, new Runnable() { public void run() { refreshViewer(); @@ -543,7 +556,7 @@ private void addObjectTypeMenu(IMenuManager objTitle, CounterEngine counterEngin } } - public static void removeActionCache(int serverId) { + private static void removeActionCache(int serverId) { counterActions.remove(serverId); } diff --git a/scouter.client/src/scouter/client/xlog/views/XLogProfileView.java b/scouter.client/src/scouter/client/xlog/views/XLogProfileView.java index 736852f96..ef1726ec5 100644 --- a/scouter.client/src/scouter/client/xlog/views/XLogProfileView.java +++ b/scouter.client/src/scouter/client/xlog/views/XLogProfileView.java @@ -136,7 +136,7 @@ public void setInput(Step[] steps, final XLogData item, int serverId) { text.setText(""); ProfileText.build(DateUtil.yyyymmdd(xLogData.p.endTime), text, this.xLogData, steps, spaceCnt, serverId); - text.addListener(SWT.MouseDown, new Listener(){ + text.addListener(SWT.MouseUp, new Listener(){ public void handleEvent(Event event) { try { int offset = text.getOffsetAtLocation(new Point (event.x, event.y)); diff --git a/scouter.common/src/scouter/lang/counters/CounterConstants.java b/scouter.common/src/scouter/lang/counters/CounterConstants.java index 5189e4054..b7b4292ba 100644 --- a/scouter.common/src/scouter/lang/counters/CounterConstants.java +++ b/scouter.common/src/scouter/lang/counters/CounterConstants.java @@ -84,6 +84,7 @@ public class CounterConstants { public final static String HOST_MEM_TOTAL = "MemT"; public final static String HOST_SWAP_PAGE_IN = "PageIn"; public final static String HOST_SWAP_PAGE_OUT = "PageOut"; + public final static String HOST_SWAP = "Swap"; public final static String HOST_SWAP_USED = "SwapU"; public final static String HOST_SWAP_TOTAL = "SwapT"; public final static String PROC_CPU = "ProcCpu"; diff --git a/scouter.common/src/scouter/lang/counters/counters.xml b/scouter.common/src/scouter/lang/counters/counters.xml index a1440a92a..04020d677 100644 --- a/scouter.common/src/scouter/lang/counters/counters.xml +++ b/scouter.common/src/scouter/lang/counters/counters.xml @@ -21,11 +21,12 @@ mrhit : MariaDB HitRatio - + - - + + + diff --git a/scouter.common/src/scouter/lang/pack/XLogPack.java b/scouter.common/src/scouter/lang/pack/XLogPack.java index 0b9f8d571..e42d42b6b 100644 --- a/scouter.common/src/scouter/lang/pack/XLogPack.java +++ b/scouter.common/src/scouter/lang/pack/XLogPack.java @@ -60,8 +60,6 @@ public class XLogPack implements Pack { public int webHash; // WEB서버의 ObjectHash public int webTime; // WEB서버 --> WAS 시작 시점까지의 시간 - //just used to control flow - transient public boolean ignore; public String toString() { StringBuilder sb = new StringBuilder(); sb.append("XLOG "); diff --git a/scouter.common/src/scouter/util/HashUtil.java b/scouter.common/src/scouter/util/HashUtil.java index 182cacdd9..88a22baba 100644 --- a/scouter.common/src/scouter/util/HashUtil.java +++ b/scouter.common/src/scouter/util/HashUtil.java @@ -53,7 +53,7 @@ public class HashUtil { 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; - public static int hash(String str){ + public static int hash(String str){ return hash(str.getBytes()); } public static int hash(byte[] bytes){ diff --git a/scouter.deploy/build.xml b/scouter.deploy/build.xml index c264f351d..1482244f3 100644 --- a/scouter.deploy/build.xml +++ b/scouter.deploy/build.xml @@ -4,7 +4,7 @@ - + diff --git a/scouter.server/scripts/env.sh b/scouter.server/scripts/env.sh new file mode 100644 index 000000000..6673fca9a --- /dev/null +++ b/scouter.server/scripts/env.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +READLINK="`dirname $0`/readlink.sh" +TUNAHOME="`dirname $($READLINK $0/..)`" + +JAVAOPTS="-Xmx512m" + diff --git a/scouter.server/scripts/readlink.sh b/scouter.server/scripts/readlink.sh new file mode 100755 index 000000000..3e31fd345 --- /dev/null +++ b/scouter.server/scripts/readlink.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +TARGET_FILE=$1 + +cd `dirname $TARGET_FILE` +TARGET_FILE=`basename $TARGET_FILE` + +# Iterate down a (possible) chain of symlinks +while [ -L "$TARGET_FILE" ] +do + TARGET_FILE=`readlink $TARGET_FILE` + cd `dirname $TARGET_FILE` + TARGET_FILE=`basename $TARGET_FILE` +done + +# Compute the canonicalized name by finding the physical path +# for the directory we're in and appending the target file. +PHYS_DIR=`pwd -P` +RESULT=$PHYS_DIR/$TARGET_FILE +echo $RESULT diff --git a/scouter.server/scripts/startcon.sh b/scouter.server/scripts/startcon.sh index f0472d5b8..7db9ccabd 100644 --- a/scouter.server/scripts/startcon.sh +++ b/scouter.server/scripts/startcon.sh @@ -1 +1,5 @@ -java -Xmx512m -classpath ./boot.jar scouter.boot.Boot ./lib -console \ No newline at end of file +#!/usr/bin/env bash + +. $(dirname $0)/env.sh + +java -Xmx512m -classpath "$TUNAHOME/boot.jar" scouter.boot.Boot "$TUNAHOME/lib" -console diff --git a/scouter.server/scripts/startup.sh b/scouter.server/scripts/startup.sh index 2fe15e5b3..0531ae98f 100644 --- a/scouter.server/scripts/startup.sh +++ b/scouter.server/scripts/startup.sh @@ -1,5 +1,10 @@ -mkdir logs > /dev/null 2>&1 -cp nohup.out ./logs/nohup.$(date '+%Y%m%d%H%M%S').out > /dev/null 2>&1 -nohup java -Xmx512m -classpath ./boot.jar scouter.boot.Boot ./lib > nohup.out & +#!/usr/bin/env bash + +. $(dirname $0)/env.sh + +mkdir -p "$TUNAHOME/logs" > /dev/null 2>&1 +cp nohup.out "$TUNAHOME/logs/nohup.$(date '+%Y%m%d%H%M%S').out" > /dev/null 2>&1 +nohup java $JAVAOPTS -classpath "$TUNAHOME/boot.jar" scouter.boot.Boot "$TUNAHOME/lib" > nohup.out & + echo "Scouter server launching..." echo "See the nohup.out." diff --git a/scouter.server/scripts/stop.sh b/scouter.server/scripts/stop.sh index 0e0cf0bab..c8fd19e9d 100644 --- a/scouter.server/scripts/stop.sh +++ b/scouter.server/scripts/stop.sh @@ -1 +1,5 @@ -rm -f *.scouter \ No newline at end of file +#!/usr/bin/env bash + +. $(dirname $0)/env.sh + +rm -f "$TUNAHOME/*.scouter" diff --git a/scouter.server/src/scouter/server/core/XLogCore.scala b/scouter.server/src/scouter/server/core/XLogCore.scala index 3d0794eaa..55de239b1 100644 --- a/scouter.server/src/scouter/server/core/XLogCore.scala +++ b/scouter.server/src/scouter/server/core/XLogCore.scala @@ -36,54 +36,53 @@ import scouter.util.RequestQueue object ServiceCore { - val queue = new RequestQueue[XLogPack](CoreRun.MAX_QUE_SIZE); + val queue = new RequestQueue[XLogPack](CoreRun.MAX_QUE_SIZE); - val conf = Configure.getInstance(); + val conf = Configure.getInstance(); - def calc(m: XLogPack) = { - XLogGroupUtil.process(m); - if (conf.enable_geoip) { - GeoIpUtil.setNationAndCity(m); - } - XLogGroupPerf.add(m); + def calc(m: XLogPack) = { + XLogGroupUtil.process(m); + if (conf.enable_geoip) { + GeoIpUtil.setNationAndCity(m); } - ThreadScala.startDaemon("scouter.server.core.XLogCore", { CoreRun.running }) { - val m = queue.get(); - ServerStat.put("xlog.core.queue", queue.size()); + XLogGroupPerf.add(m); + } + ThreadScala.startDaemon("scouter.server.core.XLogCore", { CoreRun.running }) { + val m = queue.get(); + ServerStat.put("xlog.core.queue", queue.size()); - if (Configure.WORKABLE) { + if (Configure.WORKABLE) { + + PlugInManager.xlog(m); + m.xType match { + case XLogTypes.WEB_SERVICE => + VisitorCore.add(m) + calc(m) + case XLogTypes.APP_SERVICE => + calc(m) + case _ => //기타 타입은 무시한다. + } + + PlugInManager.xlogdb(m); + val b = new DataOutputX().writePack(m).toByteArray(); + XLogCache.put(m.objHash, m.elapsed, m.error != 0, b); + if (conf.tagcnt_enabled) { + XLogTagCount.add(m) + } + XLogWR.add(m.endTime, m.txid, m.gxid, m.elapsed, b); - PlugInManager.xlog(m); - if (m.ignore == false) { - m.xType match { - case XLogTypes.WEB_SERVICE => - VisitorCore.add(m) - calc(m) - case XLogTypes.APP_SERVICE => - calc(m) - case _ => //기타 타입은 무시한다. - } - - PlugInManager.xlogdb(m); - val b = new DataOutputX().writePack(m).toByteArray(); - XLogCache.put(m.objHash, m.elapsed, m.error != 0, b); - if (conf.tagcnt_enabled) { - XLogTagCount.add(m) - } - XLogWR.add(m.endTime, m.txid, m.gxid, m.elapsed, b); - } - } } + } - def add(p: XLogPack) { - if (p.endTime == 0) { - p.endTime = System.currentTimeMillis(); - } + def add(p: XLogPack) { + if (p.endTime == 0) { + p.endTime = System.currentTimeMillis(); + } - val ok = queue.put(p); - if (ok == false) { - Logger.println("S116", 10, "queue exceeded!!"); - } + val ok = queue.put(p); + if (ok == false) { + Logger.println("S116", 10, "queue exceeded!!"); } + } } diff --git a/scouter.server/src/scouter/server/db/TextPermRD.scala b/scouter.server/src/scouter/server/db/TextPermRD.scala index 182d77702..acc718faa 100644 --- a/scouter.server/src/scouter/server/db/TextPermRD.scala +++ b/scouter.server/src/scouter/server/db/TextPermRD.scala @@ -14,42 +14,49 @@ * See the License for the specific language governing permissions and * limitations under the License. * - */ + */ package scouter.server.db; -import scouter.server.core.cache.TextCache; -import scouter.server.db.text.TextTable; -import scouter.util.HashUtil; +import scouter.server.core.cache.TextCache +import scouter.util.HashUtil object TextPermRD { + def getString(division: String, hash: Int): String = { + val divHash = HashUtil.hash(division); + return getString(divHash, hash); + } + def getString(divHash: Int, hash: Int): String = { + val out = TextCache.get(divHash, hash); + if (out != null) + return out; - def getString(division: String, hash: Int): String = { - val divHash = HashUtil.hash(division); - val out = TextCache.get(divHash, hash); - if (out != null) - return out; - - val idx = TextPermWR.open(); - try { - val b = idx.get(divHash, hash); - if (b == null) - return null; - val text = new String(b, "UTF-8"); - TextCache.put(divHash, hash, text); - return text; - } catch { - case e: Exception => e.printStackTrace(); - } + try { + val (index, data) = TextPermWR.open(divHash); + if (index == null) + return null; + val pos = index.get(hash); + if (pos <= 0) return null; + val bytes = data.read(pos); + val text = new String(bytes, "UTF-8"); + TextCache.put(divHash, hash, text); + return text; + } catch { + case e: Exception => e.printStackTrace(); } + return null; + } - def read(handler: (Array[Byte], Array[Byte]) => Unit) { - try { - val idx = TextPermWR.open(); - idx.read(handler); - } catch { - case e: Exception => e.printStackTrace(); - } + def read(division: String, handler: (Array[Byte], Array[Byte]) => Unit) { + try { + val divHash = HashUtil.hash(division); + val (index, data) = TextPermWR.open(divHash); + if (index == null) + return ; + index.read(handler, data.read); + } catch { + case e: Exception => e.printStackTrace(); } + } } \ No newline at end of file diff --git a/scouter.server/src/scouter/server/db/TextPermWR.scala b/scouter.server/src/scouter/server/db/TextPermWR.scala index d8df9fbcf..10b6a3855 100644 --- a/scouter.server/src/scouter/server/db/TextPermWR.scala +++ b/scouter.server/src/scouter/server/db/TextPermWR.scala @@ -19,117 +19,114 @@ package scouter.server.db; import java.io.File -import java.util.ArrayList + import scouter.lang.TextTypes import scouter.server.Logger import scouter.server.core.cache.TextCache -import scouter.server.db.text.TextTable +import scouter.server.db.obj.TextPermData +import scouter.server.db.obj.TextPermIndex import scouter.server.util.ThreadScala -import scouter.util.DateUtil -import scouter.util.FileUtil import scouter.util.HashUtil -import scouter.util.ICloseDB -import scouter.util.IntSet -import scouter.util.LinkedMap +import scouter.util.Hexa32 import scouter.util.RequestQueue -import com.sun.xml.internal.ws.util.StringUtils import scouter.util.StringUtil object TextPermWR { - var permTable: TextTable = null - - val queue = new RequestQueue[Data](DBCtr.LARGE_MAX_QUE_SIZE); - -// val common = new IntSet(); -// common.add(HashUtil.hash(TextTypes.METHOD)); -// common.add(HashUtil.hash(TextTypes.GROUP)); -// common.add(HashUtil.hash(TextTypes.CITY)); -// //move to perm db -// common.add(HashUtil.hash(TextTypes.LOGIN)); -// common.add(HashUtil.hash(TextTypes.DESC)); -// common.add(HashUtil.hash(TextTypes.GROUP)); -// common.add(HashUtil.hash(TextTypes.USER_AGENT)); - - //에러만 날짜별로 저장한다.-20151110 - val errorHash = HashUtil.hash(TextTypes.ERROR); - def isA(divs: Int): Boolean = { - return divs != errorHash; - } + val queue = new RequestQueue[Data](DBCtr.LARGE_MAX_QUE_SIZE); - ThreadScala.start("scouter.server.db.TextPermWR") { - while (DBCtr.running) { - val m = queue.get(); - var writingTable = open(); - try { - if (writingTable == null) { - queue.clear(); - Logger.println("S137", 10, "can't open db"); - } else { - val ok = writingTable.hasKey(m.div, m.hash); - if (ok == false) { - writingTable.set(m.div, m.hash, m.text.getBytes("UTF8")); - } - } - } catch { - case t: Throwable => t.printStackTrace(); - } - } - close(); - } + // val common = new IntSet(); + // common.add(HashUtil.hash(TextTypes.METHOD)); + // common.add(HashUtil.hash(TextTypes.GROUP)); + // common.add(HashUtil.hash(TextTypes.CITY)); + // //move to perm db + // common.add(HashUtil.hash(TextTypes.LOGIN)); + // common.add(HashUtil.hash(TextTypes.DESC)); + // common.add(HashUtil.hash(TextTypes.GROUP)); + // common.add(HashUtil.hash(TextTypes.USER_AGENT)); - def add(divHash: Int, hash: Int, text: String) { - if (StringUtil.isEmpty(text)) - return + //에러만 날짜별로 저장한다.-20151110 + val errorHash = HashUtil.hash(TextTypes.ERROR); + def isA(divs: Int): Boolean = { + return divs != errorHash; + } - TextCache.put(divHash, hash, text) - val ok = queue.put(new Data(divHash, hash, text)) - if (ok == false) { - Logger.println("S138", 10, "queue exceeded!!"); + ThreadScala.start("scouter.server.db.TextPermWR") { + while (DBCtr.running) { + val m = queue.get(); + var (index, data) = open(m.div); + try { + if (index == null) { + queue.clear(); + Logger.println("S137", 10, "can't open db"); + } else { + val ok = index.hasKey(m.hash); + if (ok == false) { + val pos = data.write(m.text.getBytes("UTF8")); + index.set(m.hash, pos); + } } + } catch { + case t: Throwable => t.printStackTrace(); + } } + close(); + } - class Data(_divs: Int, _hash: Int, _text: String) { - val div = _divs; - val hash = _hash; - val text = _text; - } + def add(divHash: Int, hash: Int, text: String) { + if (StringUtil.isEmpty(text)) + return - def open(): TextTable = { - try { - if (permTable != null) - return permTable; - - this.synchronized { - if (permTable != null) - return permTable; - - val path = getDBPath(); - val f = new File(path); - if (f.exists() == false) - f.mkdirs(); - val file = path + "/ltext"; - - permTable = TextTable.open(file); - return permTable; - } - } catch { - case e: Throwable => - e.printStackTrace(); - close(); - } - return null; + TextCache.put(divHash, hash, text) + val ok = queue.put(new Data(divHash, hash, text)) + if (ok == false) { + Logger.println("S138", 10, "queue exceeded!!"); } + } - def getDBPath(): String = { - val sb = new StringBuffer(); - sb.append(DBCtr.getRootPath()); - sb.append("/00000000/text"); - return sb.toString(); - } - def close() { - if (permTable != null) { - permTable.close() - } + class Data(_divs: Int, _hash: Int, _text: String) { + val div = _divs; + val hash = _hash; + val text = _text; + } + + def open(div: Int): (TextPermIndex, TextPermData) = { + try { + var index = TextPermIndex.get(div); + var data = TextPermData.get(div); + if (index != null && data != null) { + return (index, data); + } + this.synchronized { + + val path = getDBPath(); + val f = new File(path); + if (f.exists() == false) + f.mkdirs(); + val file = path + "/text_" + Hexa32.toString32(div); + + index = TextPermIndex.open(div, file); + data = TextPermData.open(div, file); + + return (index, data); + } + } catch { + case e: Throwable => + e.printStackTrace(); + close(); } + return (null,null); + } + + def getDBPath(): String = { + val sb = new StringBuffer(); + sb.append(DBCtr.getRootPath()); + sb.append("/00000000/text"); + return sb.toString(); + } + def close() { + TextPermIndex.closeAll(); + TextPermData.closeAll(); + } + } diff --git a/scouter.server/src/scouter/server/db/TextRD.scala b/scouter.server/src/scouter/server/db/TextRD.scala index a5845923d..62bd4b48e 100644 --- a/scouter.server/src/scouter/server/db/TextRD.scala +++ b/scouter.server/src/scouter/server/db/TextRD.scala @@ -32,7 +32,7 @@ object TextRD { try { val divhash = HashUtil.hash(divs); if (TextPermWR.isA(divhash)) { - return TextPermRD.getString(divs, hash); + return TextPermRD.getString(divhash, hash); } val table = TextWR.open(date) val b = table.get(divhash, hash); diff --git a/scouter.server/src/scouter/server/db/text/TextPermData.scala b/scouter.server/src/scouter/server/db/text/TextPermData.scala new file mode 100644 index 000000000..88480e750 --- /dev/null +++ b/scouter.server/src/scouter/server/db/text/TextPermData.scala @@ -0,0 +1,109 @@ +/* +* 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.server.db.obj; + +import java.io.IOException +import java.io.RandomAccessFile +import java.util.Hashtable +import scouter.util.IClose; +import scouter.util.IntKeyLinkedMap + +object TextPermData { + val table = new IntKeyLinkedMap[TextPermData](); + def get(div: Int): TextPermData = { + table.synchronized { + var reader = table.get(div); + if (reader != null) { + reader.refrence += 1; + } + return reader; + } + } + def open(div: Int, file: String): TextPermData = { + table.synchronized { + var reader = table.get(div); + if (reader != null) { + reader.refrence += 1; + } else { + reader = new TextPermData(div, file); + table.put(div, reader); + } + return reader; + } + } + def closeAll() { + while (table.size() > 0) { + table.removeFirst().close(); + } + } +} + +class TextPermData(div: Int, file: String) extends IClose { + + var refrence = 0; + val dataFile = new RandomAccessFile(file + ".data", "rw"); + + def close() { + TextPermData.table.synchronized { + if (this.refrence == 0) { + TextPermData.table.remove(this.div); + try { + dataFile.close(); + } catch { + case e: Throwable => + e.printStackTrace() + } + } else { + this.refrence -= 1; + } + } + + } + + def read(fpos: Long): Array[Byte] = { + this.synchronized { + try { + dataFile.seek(fpos); + val length = dataFile.readInt(); + val buffer = new Array[Byte](length); + dataFile.read(buffer); + return buffer; + } catch { + case e: IOException => + throw new RuntimeException(e); + } + } + } + + def write(data: Array[Byte]): Long = { + this.synchronized { + val location = dataFile.length(); + dataFile.seek(location); + dataFile.writeInt(data.length); + dataFile.write(data); + return location; + } + } + + def update(pos: Long, data: Array[Byte]) { + dataFile.seek(pos); + dataFile.writeInt(data.length); + dataFile.write(data); + } +} \ No newline at end of file diff --git a/scouter.server/src/scouter/server/db/text/TextPermIndex.scala b/scouter.server/src/scouter/server/db/text/TextPermIndex.scala new file mode 100644 index 000000000..f11c50195 --- /dev/null +++ b/scouter.server/src/scouter/server/db/text/TextPermIndex.scala @@ -0,0 +1,104 @@ +/* +* 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.server.db.obj; + +import java.io.IOException +import java.util.Hashtable +import scouter.server.db.io.IndexKeyFile +import scouter.io.DataInputX +import scouter.io.DataOutputX +import scouter.util.FileUtil +import scouter.util.IClose; +import scouter.util.IntKeyLinkedMap +object TextPermIndex { + val table = new IntKeyLinkedMap[TextPermIndex](); + + def get(div: Int): TextPermIndex = { + table.synchronized { + var index = table.get(div); + if (index != null) { + index.refrence += 1; + return index; + } else return null; + } + } + def open(div: Int, file: String): TextPermIndex = { + table.synchronized { + var index = table.get(div); + if (index != null) { + index.refrence += 1; + return index; + } else { + index = new TextPermIndex(div, file); + table.put(div, index); + return index; + } + } + } + def closeAll() { + while (table.size() > 0) { + table.removeFirst().close(); + } + } +} +class TextPermIndex(div: Int, file: String) extends IClose { + + var refrence = 0; + var index: IndexKeyFile = null + + def set(key: Int, pos: Long) { + if (this.index == null) { + this.index = new IndexKeyFile(file); + } + this.index.put(DataOutputX.toBytes(key), DataOutputX.toBytes5(pos)); + } + + def get(key: Int): Long = { + if (this.index == null) { + this.index = new IndexKeyFile(file); + } + val buf = this.index.get(DataOutputX.toBytes(key)); + if (buf == null) -1 else DataInputX.toLong5(buf, 0) + } + def hasKey(key: Int): Boolean = { + if (this.index == null) { + this.index = new IndexKeyFile(file); + } + return this.index.hasKey(DataOutputX.toBytes(key)); + } + def read(handler: (Array[Byte], Array[Byte]) => Any, reader: (Long) => Array[Byte]) { + if (this.index == null) { + this.index = new IndexKeyFile(file); + } + this.index.read(handler, reader); + } + + override def close() { + TextPermIndex.table.synchronized { + if (this.refrence == 0) { + TextPermIndex.table.remove(this.div); + FileUtil.close(this.index); + this.index = null; + } else { + this.refrence -= 1; + } + } + } + +} \ No newline at end of file