diff --git a/build_client.sh b/build_client.sh old mode 100755 new mode 100644 diff --git a/build_package.sh b/build_package.sh old mode 100755 new mode 100644 diff --git a/scouter.agent.host/scripts/readlink.sh b/scouter.agent.host/scripts/readlink.sh old mode 100755 new mode 100644 diff --git a/scouter.agent.host/scripts/sample2.host.sh b/scouter.agent.host/scripts/sample2.host.sh old mode 100755 new mode 100644 diff --git a/scouter.agent.host/scripts/sample2.stop.sh b/scouter.agent.host/scripts/sample2.stop.sh old mode 100755 new mode 100644 diff --git a/scouter.agent.java/src/scouter/agent/AgentTransformer.java b/scouter.agent.java/src/scouter/agent/AgentTransformer.java index 7a0e673c5..7b8238e6f 100644 --- a/scouter.agent.java/src/scouter/agent/AgentTransformer.java +++ b/scouter.agent.java/src/scouter/agent/AgentTransformer.java @@ -125,6 +125,7 @@ public byte[] transform(ClassLoader loader, String className, Class classBeingRe public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { classDesc.set(version, access, name, signature, superName, interfaces); + super.visit(version, access, name, signature, superName, interfaces); } @Override diff --git a/scouter.agent.java/src/scouter/agent/Configure.java b/scouter.agent.java/src/scouter/agent/Configure.java index 7a176c107..5d0e74847 100644 --- a/scouter.agent.java/src/scouter/agent/Configure.java +++ b/scouter.agent.java/src/scouter/agent/Configure.java @@ -16,17 +16,6 @@ */ package scouter.agent; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -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; import scouter.lang.conf.ConfObserver; @@ -35,16 +24,10 @@ import scouter.lang.value.ListValue; import scouter.lang.value.MapValue; import scouter.net.NetConstants; -import scouter.util.DateUtil; -import scouter.util.FileUtil; -import scouter.util.HashUtil; -import scouter.util.StringEnumer; -import scouter.util.StringKeyLinkedMap; -import scouter.util.StringSet; -import scouter.util.StringUtil; -import scouter.util.SysJMX; -import scouter.util.SystemUtil; -import scouter.util.ThreadUtil; +import scouter.util.*; + +import java.io.*; +import java.util.*; public class Configure extends Thread { public static boolean JDBC_REDEFINED = false; private static Configure instance = null; @@ -162,6 +145,8 @@ public final static synchronized Configure getInstance() { public String log_dir =""; public boolean log_rotation_enabled =true; public int log_keep_days =7; + public boolean _log_trace_enabled = false; + public boolean _log_trace_use_logger = false; //Hook public String hook_args_patterns = ""; @@ -490,6 +475,8 @@ private void apply() { this.log_dir = getValue("log_dir", ""); this.log_rotation_enabled = getBoolean("log_rotation_enabled", true); this.log_keep_days = getInt("log_keep_days", 7); + this._log_trace_enabled = getBoolean("_log_trace_enabled", false); + this._log_trace_use_logger = getBoolean("_log_trace_use_logger", false); this.enduser_trace_endpoint_url = getValue("enduser_trace_endpoint_url", "_scouter_browser.jsp"); this.enduser_perf_endpoint_hash = HashUtil.hash(this.enduser_trace_endpoint_url); diff --git a/scouter.agent.java/src/scouter/agent/Logger.java b/scouter.agent.java/src/scouter/agent/Logger.java index 2cca70c6b..7beec9f43 100644 --- a/scouter.agent.java/src/scouter/agent/Logger.java +++ b/scouter.agent.java/src/scouter/agent/Logger.java @@ -16,25 +16,16 @@ */ package scouter.agent; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; - -import scouter.util.CompareUtil; -import scouter.util.DateUtil; -import scouter.util.FileUtil; -import scouter.util.IClose; -import scouter.util.StringLongLinkedMap; -import scouter.util.StringUtil; -import scouter.util.ThreadUtil; +import scouter.util.*; + +import java.io.*; public class Logger { private static StringLongLinkedMap lastLog = new StringLongLinkedMap().setMax(1000); + static Configure conf = Configure.getInstance(); - public static void println(Object message) { + public static void println(Object message) { println(build("SCOUTER", toString(message)), true); } @@ -45,6 +36,24 @@ public static void println(String id, Object message) { println(build(id, toString(message)), true); } + public static void println(String id, String message, Throwable t) { + if (checkOk(id, 10) == false) { + return; + } + println(build(id, message), true); + println(ThreadUtil.getStackTrace(t), true); + } + + public static void trace(Object message) { + if(conf._log_trace_enabled) { + if(conf._log_trace_use_logger) { + println(build("SCOUTER-TRC", toString(message)), true); + } else { + System.out.println(build("SCOUTER-TRC", toString(message))); + } + } + } + private static String toString(Object message) { return message == null ? "null" : message.toString(); } @@ -55,14 +64,6 @@ private static String build(String id, String message) { .append(message).toString(); } - public static void println(String id, String message, Throwable t) { - if (checkOk(id, 10) == false) { - return; - } - println(build(id, message), true); - println(ThreadUtil.getStackTrace(t), true); - } - public static String getCallStack(Throwable t) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); @@ -133,7 +134,6 @@ private static synchronized void openFile(String prefix) throws IOException { } } - static Configure conf = Configure.getInstance(); static Runnable initializer = new Runnable() { long last = System.currentTimeMillis(); long lastDataUnit = DateUtil.getDateUnit(); diff --git a/scouter.agent.java/src/scouter/agent/asm/JDBCDriverASM.java b/scouter.agent.java/src/scouter/agent/asm/JDBCDriverASM.java index e989243e3..9846557ff 100644 --- a/scouter.agent.java/src/scouter/agent/asm/JDBCDriverASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/JDBCDriverASM.java @@ -15,19 +15,16 @@ * limitations under the License. */ package scouter.agent.asm; -import java.util.Map; import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.asm.util.AsmUtil; import scouter.agent.asm.util.HookingSet; import scouter.agent.trace.TraceSQL; -import scouter.org.objectweb.asm.ClassVisitor; -import scouter.org.objectweb.asm.Label; -import scouter.org.objectweb.asm.MethodVisitor; -import scouter.org.objectweb.asm.Opcodes; -import scouter.org.objectweb.asm.Type; +import scouter.org.objectweb.asm.*; import scouter.org.objectweb.asm.commons.LocalVariablesSorter; + +import java.util.Map; public class JDBCDriverASM implements IASM, Opcodes { //user can define driver.connect() private Map reserved =HookingSet.getHookingSet(Configure.getInstance().hook_jdbc_wrapping_driver_patterns); @@ -43,7 +40,7 @@ public ClassVisitor transform(ClassVisitor cv, String className, ClassDesc class if (mset != null){ return new JDBCDriverCV(cv, mset, className); } - + return cv; } } @@ -64,7 +61,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si if (AsmUtil.isSpecial(name)) { return mv; } - String fullname = AsmUtil.add(className, name, desc); + String fullname = AsmUtil.makeMethodFullName(className, name, desc); Logger.println("A105", "jdbc db2 driver loaded: " + fullname); return new JDBCDriverMV(access, desc, mv, fullname); diff --git a/scouter.agent.java/src/scouter/agent/asm/JDBCPreparedStatementASM.java b/scouter.agent.java/src/scouter/agent/asm/JDBCPreparedStatementASM.java index 8c741edb4..2727436d3 100644 --- a/scouter.agent.java/src/scouter/agent/asm/JDBCPreparedStatementASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/JDBCPreparedStatementASM.java @@ -15,15 +15,10 @@ * limitations under the License. */ package scouter.agent.asm; -import java.util.HashSet; import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.Logger; -import scouter.agent.asm.jdbc.PsClearParametersMV; -import scouter.agent.asm.jdbc.PsExecuteMV; -import scouter.agent.asm.jdbc.PsInitMV; -import scouter.agent.asm.jdbc.PsSetMV; -import scouter.agent.asm.jdbc.StExecuteMV; +import scouter.agent.asm.jdbc.*; import scouter.agent.asm.util.HookingSet; import scouter.agent.trace.SqlParameter; import scouter.agent.trace.TraceSQL; @@ -31,6 +26,8 @@ import scouter.org.objectweb.asm.MethodVisitor; import scouter.org.objectweb.asm.Opcodes; import scouter.org.objectweb.asm.Type; + +import java.util.HashSet; public class JDBCPreparedStatementASM implements IASM, Opcodes { public final HashSet target = HookingSet.getHookingClassSet(Configure.getInstance().hook_jdbc_pstmt_classes); public final HashSet noField = new HashSet(); @@ -85,6 +82,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); if ("".equals(name)) { return new PsInitMV(access, desc, mv, owner); + } else { String targetDesc = PsSetMV.getSetSignature(name); if (targetDesc != null) { @@ -93,13 +91,16 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si } } else if (PsExecuteMV.isTarget(name)) { if (desc.startsWith("()")) { - return new PsExecuteMV(access, desc, mv, owner); + return new PsExecuteMV(access, desc, mv, owner, name); } else if (desc.startsWith("(Ljava/lang/String;)")) { - return new StExecuteMV(access, desc, mv, owner); + return new StExecuteMV(access, desc, mv, owner, name); } } else if ("clearParameters".equals(name) && "()V".equals(desc)) { return new PsClearParametersMV(access, desc, mv, owner); - } + + } else if ("getUpdateCount".equals(name) && "()I".equals(desc)) { + return new PsUpdateCountMV(mv); + } } return mv; } diff --git a/scouter.agent.java/src/scouter/agent/asm/JDBCStatementASM.java b/scouter.agent.java/src/scouter/agent/asm/JDBCStatementASM.java index 352d183a1..c308d4c22 100644 --- a/scouter.agent.java/src/scouter/agent/asm/JDBCStatementASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/JDBCStatementASM.java @@ -15,15 +15,17 @@ * limitations under the License. */ package scouter.agent.asm; -import java.util.HashSet; import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.Logger; +import scouter.agent.asm.jdbc.PsUpdateCountMV; import scouter.agent.asm.jdbc.StExecuteMV; import scouter.agent.asm.util.HookingSet; import scouter.org.objectweb.asm.ClassVisitor; import scouter.org.objectweb.asm.MethodVisitor; import scouter.org.objectweb.asm.Opcodes; + +import java.util.HashSet; public class JDBCStatementASM implements IASM, Opcodes { public final HashSet target = HookingSet.getHookingClassSet(Configure.getInstance().hook_jdbc_stmt_classes); public JDBCStatementASM() { @@ -65,8 +67,10 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); if (StExecuteMV.isTarget(name)) { if (desc.startsWith("(Ljava/lang/String;)")) { - return new StExecuteMV(access, desc, mv, owner); + return new StExecuteMV(access, desc, mv, owner, name); } + } else if ("getUpdateCount".equals(name) && "()I".equals(desc)) { + return new PsUpdateCountMV(mv); } return mv; } diff --git a/scouter.agent.java/src/scouter/agent/asm/MethodASM.java b/scouter.agent.java/src/scouter/agent/asm/MethodASM.java index a726ced11..758321fe3 100644 --- a/scouter.agent.java/src/scouter/agent/asm/MethodASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/MethodASM.java @@ -17,21 +17,17 @@ package scouter.agent.asm; -import java.util.List; - import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.asm.util.AsmUtil; import scouter.agent.asm.util.HookingSet; import scouter.agent.netio.data.DataProxy; import scouter.agent.trace.TraceMain; -import scouter.org.objectweb.asm.ClassVisitor; -import scouter.org.objectweb.asm.Label; -import scouter.org.objectweb.asm.MethodVisitor; -import scouter.org.objectweb.asm.Opcodes; -import scouter.org.objectweb.asm.Type; +import scouter.org.objectweb.asm.*; import scouter.org.objectweb.asm.commons.LocalVariablesSorter; +import java.util.List; + public class MethodASM implements IASM, Opcodes { private List target = HookingSet.getHookingMethodSet(Configure.getInstance().hook_method_patterns); @@ -106,7 +102,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si if (conf.isIgnoreMethodPrefix(name)) return mv; - String fullname = AsmUtil.add(className, name, desc); + String fullname = AsmUtil.makeMethodFullName(className, name, desc); int fullname_hash = DataProxy.sendMethodName(fullname); return new MethodMV(access, desc, mv, fullname, fullname_hash); diff --git a/scouter.agent.java/src/scouter/agent/asm/ServiceASM.java b/scouter.agent.java/src/scouter/agent/asm/ServiceASM.java index 1ff48be1c..1b468aee2 100644 --- a/scouter.agent.java/src/scouter/agent/asm/ServiceASM.java +++ b/scouter.agent.java/src/scouter/agent/asm/ServiceASM.java @@ -17,21 +17,17 @@ package scouter.agent.asm; -import java.util.List; - import scouter.agent.ClassDesc; import scouter.agent.Configure; import scouter.agent.asm.util.AsmUtil; import scouter.agent.asm.util.HookingSet; import scouter.agent.trace.TraceMain; import scouter.lang.pack.XLogTypes; -import scouter.org.objectweb.asm.ClassVisitor; -import scouter.org.objectweb.asm.Label; -import scouter.org.objectweb.asm.MethodVisitor; -import scouter.org.objectweb.asm.Opcodes; -import scouter.org.objectweb.asm.Type; +import scouter.org.objectweb.asm.*; import scouter.org.objectweb.asm.commons.LocalVariablesSorter; +import java.util.List; + public class ServiceASM implements IASM, Opcodes { private List target = HookingSet.getHookingMethodSet(Configure.getInstance().hook_service_patterns); @@ -67,8 +63,24 @@ public ServiceCV(ClassVisitor cv, HookingSet mset, String className,byte xType) this.xType=xType; } - @Override + /** + * @param access the method's access flags (see {@link Opcodes}). This + * parameter also indicates if the method is synthetic and/or + * deprecated. + * @param name the method's name. + * @param desc the method's descriptor (see {@link Type Type}). (ex) (Ljava/lang/String;)Lorg/mybatis/jpetstore/domain/Category; + * @param signature the method's signature. May be null if the method + * parameters, return type and exceptions do not use generic + * types. + * @param exceptions the internal names of the method's exception classes (see + * {@link Type#getInternalName() getInternalName}). May be + * null. + * @return + */ + @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + //System.out.println("access = [" + access + "], name = [" + name + "], desc = [" + desc + "], signature = [" + signature + "], exceptions = [" + exceptions + "]"); + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); if (mv == null || mset.isA(name, desc) == false) { return mv; @@ -77,7 +89,7 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si return mv; } - String fullname = AsmUtil.add(className, name, desc); + String fullname = AsmUtil.makeMethodFullName(className, name, desc); return new ServiceMV(access, desc, mv, fullname,Type.getArgumentTypes(desc),(access & ACC_STATIC) != 0,xType,className, name, desc); } diff --git a/scouter.agent.java/src/scouter/agent/asm/jdbc/PsExecuteMV.java b/scouter.agent.java/src/scouter/agent/asm/jdbc/PsExecuteMV.java index e4d2d40b8..f68d8420d 100644 --- a/scouter.agent.java/src/scouter/agent/asm/jdbc/PsExecuteMV.java +++ b/scouter.agent.java/src/scouter/agent/asm/jdbc/PsExecuteMV.java @@ -1,30 +1,31 @@ -/* - * Copyright 2015 Scouter Project. - * - * 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. - */ - +/* + * Copyright 2015 Scouter Project. + * + * 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.asm.jdbc; -import java.util.HashSet; -import java.util.Set; - -import scouter.agent.trace.TraceSQL; -import scouter.org.objectweb.asm.Label; -import scouter.org.objectweb.asm.MethodVisitor; -import scouter.org.objectweb.asm.Opcodes; -import scouter.org.objectweb.asm.Type; -import scouter.org.objectweb.asm.commons.LocalVariablesSorter; +import scouter.agent.asm.util.AsmUtil; +import scouter.agent.trace.TraceSQL; +import scouter.org.objectweb.asm.Label; +import scouter.org.objectweb.asm.MethodVisitor; +import scouter.org.objectweb.asm.Opcodes; +import scouter.org.objectweb.asm.Type; +import scouter.org.objectweb.asm.commons.LocalVariablesSorter; + +import java.util.HashSet; +import java.util.Set; public class PsExecuteMV extends LocalVariablesSorter implements Opcodes { @@ -36,31 +37,39 @@ public class PsExecuteMV extends LocalVariablesSorter implements Opcodes { target.add("executeBatch"); } + private final byte methodType; + public static boolean isTarget(String name) { return target.contains(name); } private final static String TRACESQL = TraceSQL.class.getName().replace('.', '/'); private final static String START_METHOD = "start"; + private static final String START_SIGNATURE = "(Ljava/lang/Object;Lscouter/agent/trace/SqlParameter;B)Ljava/lang/Object;"; private final static String END_METHOD = "end"; - private static final String END_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Throwable;)V"; - private static final String START_SIGNATURE = "(Ljava/lang/Object;Lscouter/agent/trace/SqlParameter;)Ljava/lang/Object;"; + private static final String END_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Throwable;I)V"; - public PsExecuteMV(int access, String desc, MethodVisitor mv, String owner) { + public PsExecuteMV(int access, String desc, MethodVisitor mv, String owner,String name) { super(ASM4,access, desc, mv); this.owner = owner; + this.returnType = Type.getReturnType(desc); + this.desc = desc; + this.methodType = StExecuteMV.methodType(name); } private Label startFinally = new Label(); private String owner; private int statIdx; + private final Type returnType; + private final String desc; @Override public void visitCode() { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, owner, TraceSQL.PSTMT_PARAM_FIELD, "Lscouter/agent/trace/SqlParameter;"); - + mv.visitFieldInsn(GETFIELD, owner, TraceSQL.PSTMT_PARAM_FIELD, "Lscouter/agent/trace/SqlParameter;"); + AsmUtil.PUSH(mv, this.methodType); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, START_METHOD, START_SIGNATURE,false); statIdx = newLocal(scouter.org.objectweb.asm.Type.getType(Object.class)); @@ -72,8 +81,44 @@ public void visitCode() { @Override public void visitInsn(int opcode) { if ((opcode >= IRETURN && opcode <= RETURN)) { - mv.visitVarInsn(Opcodes.ALOAD, statIdx); - mv.visitInsn(Opcodes.ACONST_NULL); + int lvPosReturn; + switch (returnType.getSort()) { + case Type.ARRAY: + if(returnType.getElementType().getSort() == Type.INT) { + lvPosReturn = newLocal(returnType); + mv.visitVarInsn(Opcodes.ASTORE, lvPosReturn); + mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn); + + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "getIntArraySum", "([I)I", false); + + } else { + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + AsmUtil.PUSH(mv, -1); + } + break; + case Type.BOOLEAN: + case Type.INT: + lvPosReturn = newLocal(returnType); + mv.visitVarInsn(Opcodes.ISTORE, lvPosReturn); + mv.visitVarInsn(Opcodes.ILOAD, lvPosReturn); + + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitVarInsn(Opcodes.ILOAD, lvPosReturn); + + if(returnType.getSort()== Type.BOOLEAN){ + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "toInt", "(Z)I",false); + } + break; + default: + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + AsmUtil.PUSH(mv, -1); + } mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE,false); } mv.visitInsn(opcode); @@ -90,8 +135,19 @@ public void visitMaxs(int maxStack, int maxLocals) { mv.visitVarInsn(Opcodes.ALOAD, statIdx); mv.visitVarInsn(Opcodes.ALOAD, errIdx); + AsmUtil.PUSH(mv, -3); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE,false); mv.visitInsn(ATHROW); mv.visitMaxs(maxStack + 8, maxLocals + 2); } + + public static void main(String[] args) { + Type type = Type.getReturnType("(Z)[I"); + System.out.println("type = " + type.getSort()); + System.out.println("dim = " + type.getDimensions()); + System.out.println("element = " + type.getElementType()); + + } + } \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/asm/jdbc/PsUpdateCountMV.java b/scouter.agent.java/src/scouter/agent/asm/jdbc/PsUpdateCountMV.java new file mode 100644 index 000000000..accf81a8d --- /dev/null +++ b/scouter.agent.java/src/scouter/agent/asm/jdbc/PsUpdateCountMV.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Scouter Project. + * + * 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.asm.jdbc; + +import scouter.agent.trace.TraceSQL; +import scouter.org.objectweb.asm.MethodVisitor; +import scouter.org.objectweb.asm.Opcodes; + + +/** + * (smt/psmt).getUpdateCount + * + * @author Gun Lee (gunlee01@gmail.com) + */ +public class PsUpdateCountMV extends MethodVisitor implements Opcodes { + private static final String TRACESQL = TraceSQL.class.getName().replace('.', '/'); + private static final String METHOD = "incUpdateCount"; + private static final String SIGNATURE = "(I)I"; + + public PsUpdateCountMV(MethodVisitor mv) { + super(ASM4, mv); + } + + @Override + public void visitInsn(int opcode) { + if (opcode == IRETURN) { + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, METHOD, SIGNATURE, false); + } + mv.visitInsn(opcode); + } +} \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/asm/jdbc/StExecuteMV.java b/scouter.agent.java/src/scouter/agent/asm/jdbc/StExecuteMV.java index 00d529101..8c4a2a9ac 100644 --- a/scouter.agent.java/src/scouter/agent/asm/jdbc/StExecuteMV.java +++ b/scouter.agent.java/src/scouter/agent/asm/jdbc/StExecuteMV.java @@ -16,16 +16,18 @@ package scouter.agent.asm.jdbc; -import java.util.HashSet; -import java.util.Set; - +import scouter.agent.asm.util.AsmUtil; import scouter.agent.trace.TraceSQL; +import scouter.lang.step.SqlXType; import scouter.org.objectweb.asm.Label; import scouter.org.objectweb.asm.MethodVisitor; import scouter.org.objectweb.asm.Opcodes; import scouter.org.objectweb.asm.Type; import scouter.org.objectweb.asm.commons.LocalVariablesSorter; +import java.util.HashSet; +import java.util.Set; + public class StExecuteMV extends LocalVariablesSorter implements Opcodes { private static Set target = new HashSet(); static { @@ -35,27 +37,48 @@ public class StExecuteMV extends LocalVariablesSorter implements Opcodes { target.add("executeBatch"); } + private final Type returnType; + private final byte methodType; + public static boolean isTarget(String name) { return target.contains(name); } private final static String TRACESQL = TraceSQL.class.getName().replace('.', '/'); private final static String START_METHOD = "start"; - private static final String START_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"; + private static final String START_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/String;B)Ljava/lang/Object;"; private final static String END_METHOD = "end"; - private static final String END_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Throwable;)V"; + private static final String END_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Throwable;I)V"; - public StExecuteMV(int access, String desc, MethodVisitor mv, String owner) { + public StExecuteMV(int access, String desc, MethodVisitor mv, String owner, String name) { super(ASM4, access, desc, mv); + this.returnType = Type.getReturnType(desc); + this.desc = desc; + this.methodType = methodType(name); + } + + public static byte methodType(String name) { + if("execute".equals(name)){ + return SqlXType.METHOD_EXECUTE; + } + if("executeQuery".equals(name)){ + return SqlXType.METHOD_QUERY; + } + if("executeUpdate".equals(name)){ + return SqlXType.METHOD_UPDATE; + } + return SqlXType.METHOD_KNOWN; } private Label startFinally = new Label(); private int statIdx; + private String desc; @Override public void visitCode() { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); + AsmUtil.PUSH(mv, this.methodType); mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, START_METHOD, START_SIGNATURE, false); @@ -68,8 +91,46 @@ public void visitCode() { @Override public void visitInsn(int opcode) { if ((opcode >= IRETURN && opcode <= RETURN)) { - mv.visitVarInsn(Opcodes.ALOAD, statIdx); - mv.visitInsn(Opcodes.ACONST_NULL); + int lvPosReturn; + switch (returnType.getSort()) { + case Type.ARRAY: + if(returnType.getElementType().getSort() == Type.INT) { + + lvPosReturn = newLocal(returnType); + mv.visitVarInsn(Opcodes.ASTORE, lvPosReturn); + mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn); + + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitVarInsn(Opcodes.ALOAD, lvPosReturn); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "getIntArraySum", "([I)I", false); + + } else { + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + AsmUtil.PUSH(mv, -1); + } + break; + case Type.BOOLEAN: + case Type.INT: + int i = newLocal(returnType); + mv.visitVarInsn(Opcodes.ISTORE, i); + mv.visitVarInsn(Opcodes.ILOAD, i); + + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + + mv.visitVarInsn(Opcodes.ILOAD, i); + + if(returnType.getSort() == Type.BOOLEAN){ + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, "toInt", "(Z)I", false); + } + break; + default: + mv.visitVarInsn(Opcodes.ALOAD, statIdx); + mv.visitInsn(Opcodes.ACONST_NULL); + AsmUtil.PUSH(mv, -1); + } mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE, false); } mv.visitInsn(opcode); @@ -86,6 +147,8 @@ public void visitMaxs(int maxStack, int maxLocals) { mv.visitVarInsn(Opcodes.ALOAD, statIdx); mv.visitVarInsn(Opcodes.ALOAD, errIdx); + AsmUtil.PUSH(mv, -3); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, TRACESQL, END_METHOD, END_SIGNATURE, false); mv.visitInsn(ATHROW); mv.visitMaxs(maxStack + 8, maxLocals + 2); diff --git a/scouter.agent.java/src/scouter/agent/asm/util/AsmUtil.java b/scouter.agent.java/src/scouter/agent/asm/util/AsmUtil.java index 2998d5534..de90ec707 100644 --- a/scouter.agent.java/src/scouter/agent/asm/util/AsmUtil.java +++ b/scouter.agent.java/src/scouter/agent/asm/util/AsmUtil.java @@ -34,7 +34,7 @@ public static boolean isPublic(int access) { } public static Type stringType = Type.getType(String.class); - public static String add(String className, String methodName, String methodSignature) { + public static String makeMethodFullName(String className, String methodName, String methodSignature) { return new StringBuffer().append(className.replace('/','.')).append(".").append(methodName).append(methodSignature).toString(); } diff --git a/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java b/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java index bf2be11ff..6d546b689 100644 --- a/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java +++ b/scouter.agent.java/src/scouter/agent/asm/util/HookingSet.java @@ -17,18 +17,12 @@ package scouter.agent.asm.util; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import scouter.util.StrMatch; import scouter.util.StringUtil; +import java.util.*; +import java.util.Map.Entry; + public class HookingSet { public byte xType = 0; public StrMatch classMatch = null; @@ -104,29 +98,29 @@ public static Map getHookingSet(String arg) { return classSet; } - public static List getHookingMethodSet(String arg) { - String[] c = StringUtil.split(arg, ','); + public static List getHookingMethodSet(String patterns) { + String[] methodPatterns = StringUtil.split(patterns, ','); - Map classSet = new HashMap(); - for (int i = 0; i < c.length; i++) { - String s = c[i]; - int x = s.lastIndexOf("."); - if (x <= 0) + Map classMap = new HashMap(); + for (int i = 0; i < methodPatterns.length; i++) { + String pattern = methodPatterns[i]; + int dotPos = pattern.lastIndexOf("."); + if (dotPos <= 0) continue; - String cname = s.substring(0, x).replace('.', '/').trim(); - String mname = s.substring(x + 1).trim(); + String cname = pattern.substring(0, dotPos).replace('.', '/').trim(); + String mname = pattern.substring(dotPos + 1).trim(); - HookingSet methodSet = classSet.get(cname); + HookingSet methodSet = classMap.get(cname); if (methodSet == null) { methodSet = new HookingSet(); - classSet.put(cname, methodSet); + classMap.put(cname, methodSet); } methodSet.add(mname); } List list = new ArrayList(); - Iterator> itr = classSet.entrySet().iterator(); + Iterator> itr = classMap.entrySet().iterator(); while (itr.hasNext()) { Entry e = itr.next(); e.getValue().classMatch = new StrMatch(e.getKey()); 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 34fdacbf2..3e9c5f7a6 100644 --- a/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java +++ b/scouter.agent.java/src/scouter/agent/netio/data/DataProxy.java @@ -15,28 +15,22 @@ * limitations under the License. */ package scouter.agent.netio.data; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.netio.data.net.DataUdpAgent; import scouter.agent.trace.TraceContext; import scouter.io.DataOutputX; import scouter.lang.TextTypes; -import scouter.lang.pack.AlertPack; -import scouter.lang.pack.ObjectPack; -import scouter.lang.pack.Pack; -import scouter.lang.pack.PerfCounterPack; -import scouter.lang.pack.SummaryPack; -import scouter.lang.pack.TextPack; -import scouter.lang.pack.XLogPack; -import scouter.lang.pack.XLogProfilePack; +import scouter.lang.pack.*; import scouter.lang.step.Step; import scouter.lang.value.MapValue; import scouter.util.HashUtil; import scouter.util.IntIntLinkedMap; import scouter.util.IntLinkedSet; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class DataProxy { private static UDPDataSendThread udpCollect = UDPDataSendThread.getInstance(); private static IntIntLinkedMap sqlHash = new IntIntLinkedMap().setMax(5000); @@ -197,15 +191,15 @@ private static void sendDirect(List buff) { } } static DataUdpAgent udpDirect = DataUdpAgent.getInstance(); - public static void sendProfile(Step[] p, TraceContext x) { + public static void sendProfile(Step[] p, TraceContext context) { if (p == null || p.length == 0) return; XLogProfilePack pk = new XLogProfilePack(); - pk.txid = x.txid; + pk.txid = context.txid; pk.objHash = conf.getObjHash(); pk.profile = Step.toBytes(p); - pk.service = x.serviceHash; - pk.elapsed = (int) (System.currentTimeMillis() - x.startTime); + pk.service = context.serviceHash; + pk.elapsed = (int) (System.currentTimeMillis() - context.startTime); sendDirect(pk); } public static void sendProfile(List p, TraceContext x) { diff --git a/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java b/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java index 7347b800f..19903eb8e 100644 --- a/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java +++ b/scouter.agent.java/src/scouter/agent/plugin/PluginLoader.java @@ -16,26 +16,23 @@ * */ 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.javassist.*; import scouter.util.FileUtil; import scouter.util.Hexa32; import scouter.util.StringUtil; import scouter.util.ThreadUtil; + +import java.io.BufferedReader; +import java.io.File; +import java.io.StringReader; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; public class PluginLoader extends Thread { private static PluginLoader instance; public synchronized static PluginLoader getInstance() { @@ -51,14 +48,14 @@ public void run() { while (true) { try { File root = Configure.getInstance().plugin_dir; - cleckPluginModified(root); + reloadIfModified(root); } catch (Throwable t) { Logger.println("A160", t.toString()); } ThreadUtil.sleep(5000); } } - private void cleckPluginModified(File root) { + private void reloadIfModified(File root) { File script = new File(root, "service.plug"); if (script.canRead() == false) { PluginAppServiceTrace.plugIn = null; diff --git a/scouter.agent.java/src/scouter/agent/proxy/ToolsMainFactory.java b/scouter.agent.java/src/scouter/agent/proxy/ToolsMainFactory.java index 9268ce97f..9dd55a791 100644 --- a/scouter.agent.java/src/scouter/agent/proxy/ToolsMainFactory.java +++ b/scouter.agent.java/src/scouter/agent/proxy/ToolsMainFactory.java @@ -16,15 +16,15 @@ package scouter.agent.proxy; -import java.io.PrintWriter; -import java.util.List; - import scouter.lang.pack.MapPack; import scouter.lang.pack.Pack; import scouter.lang.value.ListValue; import scouter.util.SystemUtil; import scouter.util.ThreadUtil; +import java.io.PrintWriter; +import java.util.List; + public class ToolsMainFactory { private static final String TOOLS_MAIN = "scouter.xtra.tools.ToolsMain"; @@ -82,9 +82,17 @@ public static void heaphisto(PrintWriter out) throws Throwable { } } - public static Pack threadDump(Pack param) throws Throwable { + /** + * get thread dump + * @param param + * @return + * @throws Throwable + */ + public static Pack threadDump(Pack param) throws Throwable { MapPack m = new MapPack(); + + //Java 1.5 or IBM JDK if (SystemUtil.IS_JAVA_1_5||SystemUtil.JAVA_VENDOR.startsWith("IBM")) { List out = ThreadUtil.getThreadDumpList(); ListValue lv = m.newList("threadDump"); @@ -93,6 +101,7 @@ public static Pack threadDump(Pack param) throws Throwable { } return m; } + ClassLoader loader = LoaderManager.getToolsLoader(); if (loader == null) { List out = ThreadUtil.getThreadDumpList(); @@ -100,6 +109,7 @@ public static Pack threadDump(Pack param) throws Throwable { for (int i = 0; i < out.size(); i++) { lv.add(out.get(i)); } + return m; } try { diff --git a/scouter.agent.java/src/scouter/agent/trace/ProfileCollector.java b/scouter.agent.java/src/scouter/agent/trace/ProfileCollector.java index 366ecce21..8e9916881 100644 --- a/scouter.agent.java/src/scouter/agent/trace/ProfileCollector.java +++ b/scouter.agent.java/src/scouter/agent/trace/ProfileCollector.java @@ -23,52 +23,76 @@ import scouter.lang.step.StepSingle; public class ProfileCollector implements IProfileCollector { - private Configure conf=Configure.getInstance(); - private TraceContext context; - protected Step[] buffer = new Step[conf.profile_step_max_count]; - protected int position = 0; + private Configure conf = Configure.getInstance(); + private TraceContext context; + protected Step[] steps = new Step[conf.profile_step_max_count]; + protected int pos = 0; - public int this_index = 0; - public int parent_index = -1; + public int currentLevel = 0; + public int parentLevel = -1; - public ProfileCollector(TraceContext context) { - this.context = context; - } + public ProfileCollector(TraceContext context) { + this.context = context; + } - public void push(StepSingle stepSingle) { - stepSingle.index = this_index; - stepSingle.parent = parent_index; - parent_index = this_index; - this_index++; - } + /** + * (syn: pushAndSetLevel) + * set the step's level as the current level and increase one level(to deeper level). + * @param stepSingle + */ + public void push(StepSingle stepSingle) { + stepSingle.index = currentLevel; + stepSingle.parent = parentLevel; + parentLevel = currentLevel; + currentLevel++; + } - protected void process(StepSingle stepSingle) { - buffer[position++] = stepSingle; - if (position >= buffer.length) { - Step[] o = buffer; - buffer = new Step[conf.profile_step_max_count]; - position = 0; - DataProxy.sendProfile(o, context); - } - } + /** + * (syn: addStep) + * assign a given step to steps[pos++] + * @param stepSingle + */ + protected void process(StepSingle stepSingle) { + steps[pos++] = stepSingle; + if (pos >= steps.length) { + Step[] o = steps; + steps = new Step[conf.profile_step_max_count]; + pos = 0; + DataProxy.sendProfile(o, context); + } + } - public void add(StepSingle stepSingle) { - stepSingle.index = this_index; - stepSingle.parent = parent_index; - this_index++; - process(stepSingle); - } + /** + * (syn: setLevelAndAddStep) + * add a step + * @param stepSingle + */ + public void add(StepSingle stepSingle) { + stepSingle.index = currentLevel; + stepSingle.parent = parentLevel; + currentLevel++; + process(stepSingle); + } - public void pop(StepSingle stepSingle) { - parent_index = stepSingle.parent; - process(stepSingle); - } + /** + * (syn: pullAndAddStep) + * add the step already leveled and decrease one level(to lower level). + * @param stepSingle + */ + public void pop(StepSingle stepSingle) { + parentLevel = stepSingle.parent; + process(stepSingle); + } - public void close(boolean ok) { - if (ok && position > 0) { - StepSingle[] buff = new StepSingle[position]; - System.arraycopy(buffer, 0, buff, 0, position); - DataProxy.sendProfile(buff, context); - } - } + /** + * send the Steps[] data + * @param ok : send the data or not + */ + public void close(boolean ok) { + if (ok && pos > 0) { + StepSingle[] newSteps = new StepSingle[pos]; + System.arraycopy(steps, 0, newSteps, 0, pos); + DataProxy.sendProfile(newSteps, context); + } + } } \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/agent/trace/ProfileSummary.java b/scouter.agent.java/src/scouter/agent/trace/ProfileSummary.java index 8919eb01e..d4348aa50 100644 --- a/scouter.agent.java/src/scouter/agent/trace/ProfileSummary.java +++ b/scouter.agent.java/src/scouter/agent/trace/ProfileSummary.java @@ -29,7 +29,6 @@ import scouter.lang.step.SocketStep; import scouter.lang.step.SocketSum; import scouter.lang.step.SqlStep; -import scouter.lang.step.SqlStep2; import scouter.lang.step.SqlSum; import scouter.lang.step.Step; import scouter.lang.step.StepEnum; @@ -122,6 +121,7 @@ public void pop(StepSingle ss) { break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: add((SqlStep) ss); break; case StepEnum.APICALL: diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceContext.java b/scouter.agent.java/src/scouter/agent/trace/TraceContext.java index 484a55fd5..019640df4 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceContext.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceContext.java @@ -17,6 +17,7 @@ package scouter.agent.trace; +import scouter.lang.step.SqlStep; import scouter.util.SysJMX; public class TraceContext { @@ -97,6 +98,8 @@ public TraceContext(boolean profile_summary) { public boolean debug_sql_call; public String group; + public SqlStep lastSqlStep; + public TraceContext createChild() { TraceContext child = new TraceContext(this.isSummary); child.parent = this; diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceMain.java b/scouter.agent.java/src/scouter/agent/trace/TraceMain.java index 86c7f66ad..4da2dd74d 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceMain.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceMain.java @@ -15,7 +15,6 @@ * limitations under the License. */ package scouter.agent.trace; -import javax.sql.DataSource; import scouter.agent.Configure; import scouter.agent.Logger; @@ -36,629 +35,655 @@ import scouter.lang.step.MessageStep; import scouter.lang.step.MethodStep; import scouter.lang.step.MethodStep2; -import scouter.util.ArrayUtil; -import scouter.util.HashUtil; -import scouter.util.IPUtil; -import scouter.util.KeyGen; -import scouter.util.ObjectUtil; -import scouter.util.StringUtil; -import scouter.util.SysJMX; -import scouter.util.ThreadUtil; +import scouter.util.*; + +import javax.sql.DataSource; + 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(); - if (ctx != null) { - return null; - } - return startHttp(req, res); - } catch (Throwable t) { - Logger.println("A143", "fail to deploy ", t); - } - return null; - } - public static Object startHttpFilter(Object req, Object res) { - try { - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx != null) { - return null; - } - return startHttp(req, res); - } catch (Throwable t) { - Logger.println("A144", "fail to deploy ", t); - } - 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.control_reject_service_enabled) { - if (stat == null || req == null || res == null) - return null; - if (http == null) { - initHttp(req); - } - Stat stat0 = (Stat) stat; - if (stat0.isStaticContents) - return null; - // reject by customized plugin - if (PluginHttpServiceTrace.reject(stat0.ctx, req, res) - // reject by control_reject_service_max_count - || TraceContextManager.size() > conf.control_reject_service_max_count) { - // howto reject - if (conf.control_reject_redirect_url_enabled) { - http.rejectUrl(res, conf.control_reject_redirect_url); // by url - } else { - http.rejectText(res, conf.control_reject_text);// just message - } - // close transaction - endHttpService(stat0, REJECT); - return REJECT; - } - } - return null; - } - private static void addSeviceName(TraceContext ctx, Object req) { - try { - Configure conf = Configure.getInstance(); - - StringBuilder sb = new StringBuilder(); - if (conf.trace_service_name_post_key != null) { - String v = http.getParameter(req, conf.trace_service_name_post_key); - if (v != null) { - if (sb.length() == 0) { - sb.append(ctx.serviceName); - sb.append('?').append(conf.trace_service_name_post_key).append("=").append(v); - } else { - sb.append('&').append(conf.trace_service_name_post_key).append("=").append(v); - } - } - } - if (conf.trace_service_name_get_key != null && ctx.http_query != null) { - int x = ctx.http_query.indexOf(conf.trace_service_name_get_key); - if (x >= 0) { - String v = null; - int y = ctx.http_query.indexOf('&', x + 1); - if (y > x) { - v = ctx.http_query.substring(x, y); - } else { - v = ctx.http_query.substring(x); - } - if (sb.length() == 0) { - sb.append(ctx.serviceName); - sb.append('?').append(v); - } else { - sb.append('&').append(v); - } - } - } - if (conf.trace_service_name_header_key != null) { - String v = http.getHeader(req, conf.trace_service_name_header_key); - ctx.serviceName = new StringBuilder(ctx.serviceName.length() + v.length() + 5).append(ctx.serviceName) - .append('-').append(v).toString(); - } - if (sb.length() > 0) { - ctx.serviceName = sb.toString(); - } - } catch (Throwable t) { - } - } - private static Object lock = new Object(); - private static Object startHttp(Object req, Object res) { - if (http == null) { - initHttp(req); - } - Configure conf = Configure.getInstance(); - TraceContext ctx = new TraceContext(conf.profile_summary_mode_enabled); - ctx.thread = Thread.currentThread(); - ctx.txid = KeyGen.next(); - ctx.startTime = System.currentTimeMillis(); - ctx.startCpu = SysJMX.getCurrentThreadCPU(); - ctx.threadId = TraceContextManager.start(ctx.thread, ctx); - ctx.bytes = SysJMX.getCurrentThreadAllocBytes(); - ctx.profile_thread_cputime = conf.profile_thread_cputime_enabled; - - http.start(ctx, req, res); - if (ctx.serviceName == null) - ctx.serviceName = "Non-URI"; - Stat stat = new Stat(ctx, req, res); - stat.isStaticContents = ctx.isStaticContents; - - if (stat.isStaticContents == false) { - PluginHttpServiceTrace.start(ctx, req, res); - } - return stat; - } - private static void initHttp(Object req) { - synchronized (lock) { - if (http == null) { - http = HttpTraceFactory.create(req.getClass().getClassLoader()); - } - } - } - public static void endHttpService(Object stat, Throwable thr) { - try { - Stat stat0 = (Stat) stat; - if (stat0 == null) { - if (thr == null) - return; - try { - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx != null && ctx.error == 0) { - Configure conf = Configure.getInstance(); - String emsg = thr.toString(); - if (conf.profile_fullstack_service_error_enabled) { - StringBuffer sb = new StringBuffer(); - sb.append(emsg).append("\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - while (thr != null) { - sb.append("\nCause...\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - } - emsg = sb.toString(); - } - ctx.error = DataProxy.sendError(emsg); - ServiceSummary.getInstance().process(thr, ctx.error, ctx.serviceHash, ctx.txid, 0, 0); - } - } catch (Throwable t) { - } - return; - } - TraceContext ctx = stat0.ctx; - - if(conf.getEndUserPerfEndpointHash() == ctx.serviceHash){ - TraceContextManager.end(ctx.threadId); - return; - } - //additional service name - addSeviceName(ctx, stat0.req); - // HTTP END - http.end(ctx, stat0.req, stat0.res); - // 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); - boolean sendOk = pack.elapsed >= conf.xlog_lower_bound_time_ms; - ctx.profile.close(sendOk); - ctx.serviceHash = DataProxy.sendServiceName(ctx.serviceName); - pack.service = ctx.serviceHash; - pack.xType = XLogTypes.WEB_SERVICE; - pack.txid = ctx.txid; - pack.gxid = ctx.gxid; - pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - pack.bytes = (int) (SysJMX.getCurrentThreadAllocBytes() - ctx.bytes); - pack.status = ctx.status; - pack.sqlCount = ctx.sqlCount; - pack.sqlTime = ctx.sqlTime; - pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); - pack.userid = ctx.userid; - // //////////////////////////////////////////////////////// - if (ctx.error != 0) { - pack.error = ctx.error; - } else if (thr != null) { - if (thr == REJECT) { - Logger.println("A145", ctx.serviceName); - String emsg = conf.control_reject_text; - pack.error = DataProxy.sendError(emsg); - ServiceSummary.getInstance().process(thr, pack.error, ctx.serviceHash, ctx.txid, 0, 0); - } else { - String emsg = thr.toString(); - if (conf.profile_fullstack_service_error_enabled) { - StringBuffer sb = new StringBuffer(); - sb.append(emsg).append("\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - while (thr != null) { - sb.append("\nCause...\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - } - emsg = sb.toString(); - } - pack.error = DataProxy.sendError(emsg); - 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); - } - if (ctx.group != null) { - pack.group = DataProxy.sendGroup(ctx.group); - } - pack.userAgent = ctx.userAgent; - pack.referer = ctx.referer; - // 2015.02.02 - pack.apicallCount = ctx.apicall_count; - pack.apicallTime = ctx.apicall_time; - pack.caller = ctx.caller; - if (ctx.login != null) { - pack.login = DataProxy.sendLogin(ctx.login); - } - if (ctx.desc != null) { - pack.desc = DataProxy.sendDesc(ctx.desc); - } - if (ctx.web_name != null) { - pack.webHash = DataProxy.sendWebName(ctx.web_name); - pack.webTime = ctx.web_time; - } - metering(pack); - if (sendOk) { - DataProxy.sendXLog(pack); - } - } catch (Throwable e) { - Logger.println("A146", e); - } - } - public static void metering(XLogPack pack) { - switch (pack.xType) { - case XLogTypes.WEB_SERVICE: - case XLogTypes.APP_SERVICE: - MeterService.getInstance().add(pack.elapsed, pack.error != 0); - ServiceSummary.getInstance().process(pack); - break; - case XLogTypes.BACK_THREAD: - } - } - public static boolean isStaticContents(String serviceName) { - int x = serviceName.lastIndexOf('.'); - if (x <= 0) - return false; - try { - String ext = serviceName.substring(x + 1); - return Configure.getInstance().isStaticContents(ext); - } catch (Exception e) { - return false; - } - } - 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) { - return null; - } - Configure conf = Configure.getInstance(); - ctx = new TraceContext(conf.profile_summary_mode_enabled); - String service_name = name; - ctx.thread = Thread.currentThread(); - ctx.serviceHash = HashUtil.hash(service_name); - ctx.serviceName = service_name; - ctx.startTime = System.currentTimeMillis(); - ctx.startCpu = SysJMX.getCurrentThreadCPU(); - ctx.txid = KeyGen.next(); - ctx.threadId = TraceContextManager.start(ctx.thread, ctx); - ctx.bytes = SysJMX.getCurrentThreadAllocBytes(); - ctx.profile_thread_cputime = conf.profile_thread_cputime_enabled; - ctx.xType = xType; - PluginAppServiceTrace.start(ctx, new HookArgs(className, methodName, methodDesc, _this, arg)); - if (ctx.xType == XLogTypes.BACK_THREAD) { - MethodStep2 ms = new MethodStep2(); - ms.hash = DataProxy.sendMethodName(service_name); - ms.start_time = (int) (System.currentTimeMillis() - ctx.startTime); - if (ctx.profile_thread_cputime) { - ms.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - } - ctx.profile.push(ms); - - return new LocalContext(ctx, ms); - } else { - return new LocalContext(ctx,null); - } - } catch (Throwable t) { - Logger.println("A147", t); - } - return null; - } - public static void endService(Object stat, Object returnValue, Throwable thr) { - try { - LocalContext localCtx = (LocalContext) stat; - if (localCtx == null){ - return; - } - TraceContext ctx = localCtx.context; - if (ctx == null) { - return; - } - if (ctx.xType == XLogTypes.BACK_THREAD) { - MethodStep2 step = (MethodStep2) localCtx.stepSingle; - step.elapsed = (int) (System.currentTimeMillis() - ctx.startTime) - step.start_time; - if (ctx.profile_thread_cputime) { - step.cputime = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu) - step.start_cpu; - } - step.error = errorCheck(ctx, thr); - ctx.profile.pop(step); - PluginAppServiceTrace.end(ctx); - TraceContextManager.end(ctx.threadId); - ctx.profile.close(true); - return; - } - PluginAppServiceTrace.end(ctx); - TraceContextManager.end(ctx.threadId); - - XLogPack pack = new XLogPack(); - pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - // pack.endTime = System.currentTimeMillis(); - pack.elapsed = (int) (System.currentTimeMillis() - ctx.startTime); - boolean sendOk = pack.elapsed >= Configure.getInstance().xlog_lower_bound_time_ms; - ctx.profile.close(sendOk); - DataProxy.sendServiceName(ctx.serviceHash, ctx.serviceName); - pack.service = ctx.serviceHash; - pack.xType = ctx.xType; - pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - 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.caller = ctx.caller; - pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); - pack.userid = ctx.userid; - pack.error = errorCheck(ctx, thr); - // 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; - if (ctx.login != null) { - pack.login = DataProxy.sendLogin(ctx.login); - } - if (ctx.desc != null) { - pack.desc = DataProxy.sendDesc(ctx.desc); - } - metering(pack); - if (sendOk) { - DataProxy.sendXLog(pack); - } - } catch (Throwable t) { - Logger.println("A148", "service end error", t); - } - } - private static int errorCheck(TraceContext ctx, Throwable thr) { - int error = 0; - if (ctx.error != 0) { - error = ctx.error; - } else if (thr != null) { - Configure conf = Configure.getInstance(); - String emsg = thr.toString(); - if (conf.profile_fullstack_service_error_enabled) { - StringBuffer sb = new StringBuffer(); - sb.append(emsg).append("\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - while (thr != null) { - sb.append("\nCause...\n"); - ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); - thr = thr.getCause(); - } - emsg = sb.toString(); - } - error = DataProxy.sendError(emsg); - ServiceSummary.getInstance().process(thr, error, ctx.serviceHash, ctx.txid, 0, 0); - } else if (ctx.userTransaction > 0) { - error = DataProxy.sendError("Missing Commit/Rollback Error"); - ServiceSummary.getInstance().process(userTxNotClose, error, ctx.serviceHash, ctx.txid, 0, 0); - } - return error; - } - 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_enabled) { - // 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) - return; - HashedMessageStep step = new HashedMessageStep(); - step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); - if (ctx.profile_thread_cputime) { - step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - } - step.hash = DataProxy.sendHashedMessage("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(" "); - sb.append(className); - sb.append("."); - sb.append(methodName); - if (ArrayUtil.isEmpty(arg)) { - return sb.toString(); - } - sb.append(" ["); - for (int i = 0, max = arg.length; i < max; i++) { - if (i > 0) - sb.append(","); - String arstr = StringUtil.limiting(ObjectUtil.toString(arg[i]), 80); - sb.append(arstr); - } - 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(" "); - sb.append(className); - sb.append("."); - sb.append(methodName); - sb.append(" ["); - String arstr = StringUtil.limiting(ObjectUtil.toString(arg), 80); - sb.append(arstr); - 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(" "); - sb.append(className); - sb.append(" ["); - String arstr = StringUtil.limiting(ObjectUtil.toString(arg), 80); - sb.append(arstr); - 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_enabled) { - // 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 this1, Object rtn) { - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx == null) - return; - 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.profile_method_enabled == false) - return null; - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx == null) { - if (conf._trace_auto_service_enabled) { - Object localContext = startService(classMethod, null, null, null, null, null, XLogTypes.APP_SERVICE); - //startService내부에서 에러가 나는 경우(발생하면 안됨) - //Null이 리턴될 수 있음(방어코드) - //@skyworker - if (localContext!=null && conf._trace_auto_service_backstack_enabled) { - String stack = ThreadUtil.getStackTrace(Thread.currentThread().getStackTrace(), 2); - AutoServiceStartAnalyzer.put(classMethod, stack); - MessageStep m = new MessageStep(); - m.message = "SERVICE BACKSTACK:\n" + stack; - ((LocalContext) localContext).context.profile.add(m); - } - return localContext; - } - return null; - } - MethodStep p = new MethodStep(); - p.start_time = (int) (System.currentTimeMillis() - ctx.startTime); - if (ctx.profile_thread_cputime) { - p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - } - p.hash = hash; - ctx.profile.push(p); - return new LocalContext(ctx, p); - } - public static void endMethod(Object localContext, Throwable thr) { - if (localContext == null) - return; - LocalContext lctx = (LocalContext) localContext; - if (lctx.service) { - endService(lctx.option, null, thr); - return; - } - MethodStep step = (MethodStep) lctx.stepSingle; - if (step == null) - return; - TraceContext tctx = lctx.context; - if (tctx == null) - return; - step.elapsed = (int) (System.currentTimeMillis() - tctx.startTime) - step.start_time; - if (tctx.profile_thread_cputime) { - step.cputime = (int) (SysJMX.getCurrentThreadCPU() - tctx.startCpu) - step.start_cpu; - } - tctx.profile.pop(step); - } - public static void setServiceName(String name) { - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx == null || name == null) - return; - 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(); - pack.cpu = cpu; - pack.endTime = endtime; - pack.elapsed = elapsed; - DataProxy.sendServiceName(service_hash, serviceName); - pack.service = service_hash; - pack.bytes = 0; - pack.status = 0; - pack.sqlCount = sqlCount; - pack.sqlTime = sqlTime; - pack.txid = txid; - pack.ipaddr = IPUtil.toBytes(remoteAddr); - pack.userid = visitor; - if (error != null) { - pack.error = DataProxy.sendError(error); - } - MeterService.getInstance().add(pack.elapsed, error != null); - DataProxy.sendXLog(pack); - MeterUsers.add(pack.userid); - return pack; - } - public static void addMessage(String msg) { - TraceContext ctx = TraceContextManager.getLocalContext(); - if (ctx == null) - return; - MessageStep p = new MessageStep(); - p.message = msg; - p.start_time = (int) (System.currentTimeMillis() - ctx.startTime); - if (ctx.profile_thread_cputime) { - p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); - } - ctx.profile.add(p); - } - public static void ctxLookup(Object this1, Object ctx){ - if(ctx instanceof DataSource){ - LoadedContext.put((DataSource)ctx); - } - } + 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; + private static Configure conf = Configure.getInstance(); + private static Error REJECT = new REQUEST_REJECT("service rejected"); + private static Error userTxNotClose = new USERTX_NOT_CLOSE("Missing Commit/Rollback Error"); + + public static Object startHttpService(Object req, Object res) { + try { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx != null) { + return null; + } + return startHttp(req, res); + } catch (Throwable t) { + Logger.println("A143", "fail to deploy ", t); + } + return null; + } + + public static Object startHttpFilter(Object req, Object res) { + try { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx != null) { + return null; + } + return startHttp(req, res); + } catch (Throwable t) { + Logger.println("A144", "fail to deploy ", t); + } + return null; + } + + public static Object reject(Object stat, Object req, Object res) { + Configure conf = Configure.getInstance(); + if (conf.control_reject_service_enabled) { + if (stat == null || req == null || res == null) + return null; + if (http == null) { + initHttp(req); + } + Stat stat0 = (Stat) stat; + if (stat0.isStaticContents) + return null; + // reject by customized plugin + if (PluginHttpServiceTrace.reject(stat0.ctx, req, res) + // reject by control_reject_service_max_count + || TraceContextManager.size() > conf.control_reject_service_max_count) { + // howto reject + if (conf.control_reject_redirect_url_enabled) { + http.rejectUrl(res, conf.control_reject_redirect_url); // by url + } else { + http.rejectText(res, conf.control_reject_text);// just message + } + // close transaction + endHttpService(stat0, REJECT); + return REJECT; + } + } + return null; + } + + private static void addSeviceName(TraceContext ctx, Object req) { + try { + Configure conf = Configure.getInstance(); + + StringBuilder sb = new StringBuilder(); + if (conf.trace_service_name_post_key != null) { + String v = http.getParameter(req, conf.trace_service_name_post_key); + if (v != null) { + if (sb.length() == 0) { + sb.append(ctx.serviceName); + sb.append('?').append(conf.trace_service_name_post_key).append("=").append(v); + } else { + sb.append('&').append(conf.trace_service_name_post_key).append("=").append(v); + } + } + } + if (conf.trace_service_name_get_key != null && ctx.http_query != null) { + int x = ctx.http_query.indexOf(conf.trace_service_name_get_key); + if (x >= 0) { + String v = null; + int y = ctx.http_query.indexOf('&', x + 1); + if (y > x) { + v = ctx.http_query.substring(x, y); + } else { + v = ctx.http_query.substring(x); + } + if (sb.length() == 0) { + sb.append(ctx.serviceName); + sb.append('?').append(v); + } else { + sb.append('&').append(v); + } + } + } + if (conf.trace_service_name_header_key != null) { + String v = http.getHeader(req, conf.trace_service_name_header_key); + ctx.serviceName = new StringBuilder(ctx.serviceName.length() + v.length() + 5).append(ctx.serviceName) + .append('-').append(v).toString(); + } + if (sb.length() > 0) { + ctx.serviceName = sb.toString(); + } + } catch (Throwable t) { + } + } + + private static Object lock = new Object(); + + private static Object startHttp(Object req, Object res) { + if (http == null) { + initHttp(req); + } + Configure conf = Configure.getInstance(); + TraceContext ctx = new TraceContext(conf.profile_summary_mode_enabled); + ctx.thread = Thread.currentThread(); + ctx.txid = KeyGen.next(); + ctx.startTime = System.currentTimeMillis(); + ctx.startCpu = SysJMX.getCurrentThreadCPU(); + ctx.threadId = TraceContextManager.start(ctx.thread, ctx); + ctx.bytes = SysJMX.getCurrentThreadAllocBytes(); + ctx.profile_thread_cputime = conf.profile_thread_cputime_enabled; + + http.start(ctx, req, res); + if (ctx.serviceName == null) + ctx.serviceName = "Non-URI"; + Stat stat = new Stat(ctx, req, res); + stat.isStaticContents = ctx.isStaticContents; + + if (stat.isStaticContents == false) { + PluginHttpServiceTrace.start(ctx, req, res); + } + return stat; + } + + private static void initHttp(Object req) { + synchronized (lock) { + if (http == null) { + http = HttpTraceFactory.create(req.getClass().getClassLoader()); + } + } + } + + public static void endHttpService(Object stat, Throwable thr) { + try { + Stat stat0 = (Stat) stat; + if (stat0 == null) { + if (thr == null) + return; + try { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx != null && ctx.error == 0) { + Configure conf = Configure.getInstance(); + String emsg = thr.toString(); + if (conf.profile_fullstack_service_error_enabled) { + StringBuffer sb = new StringBuffer(); + sb.append(emsg).append("\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + while (thr != null) { + sb.append("\nCause...\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + } + emsg = sb.toString(); + } + ctx.error = DataProxy.sendError(emsg); + ServiceSummary.getInstance().process(thr, ctx.error, ctx.serviceHash, ctx.txid, 0, 0); + } + } catch (Throwable t) { + } + return; + } + TraceContext ctx = stat0.ctx; + + if (conf.getEndUserPerfEndpointHash() == ctx.serviceHash) { + TraceContextManager.end(ctx.threadId); + return; + } + //additional service name + addSeviceName(ctx, stat0.req); + // HTTP END + http.end(ctx, stat0.req, stat0.res); + // 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); + boolean sendOk = pack.elapsed >= conf.xlog_lower_bound_time_ms; + ctx.profile.close(sendOk); + ctx.serviceHash = DataProxy.sendServiceName(ctx.serviceName); + pack.service = ctx.serviceHash; + pack.xType = XLogTypes.WEB_SERVICE; + pack.txid = ctx.txid; + pack.gxid = ctx.gxid; + pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + pack.bytes = (int) (SysJMX.getCurrentThreadAllocBytes() - ctx.bytes); + pack.status = ctx.status; + pack.sqlCount = ctx.sqlCount; + pack.sqlTime = ctx.sqlTime; + pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); + pack.userid = ctx.userid; + // //////////////////////////////////////////////////////// + if (ctx.error != 0) { + pack.error = ctx.error; + } else if (thr != null) { + if (thr == REJECT) { + Logger.println("A145", ctx.serviceName); + String emsg = conf.control_reject_text; + pack.error = DataProxy.sendError(emsg); + ServiceSummary.getInstance().process(thr, pack.error, ctx.serviceHash, ctx.txid, 0, 0); + } else { + String emsg = thr.toString(); + if (conf.profile_fullstack_service_error_enabled) { + StringBuffer sb = new StringBuffer(); + sb.append(emsg).append("\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + while (thr != null) { + sb.append("\nCause...\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + } + emsg = sb.toString(); + } + pack.error = DataProxy.sendError(emsg); + 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); + } + if (ctx.group != null) { + pack.group = DataProxy.sendGroup(ctx.group); + } + pack.userAgent = ctx.userAgent; + pack.referer = ctx.referer; + // 2015.02.02 + pack.apicallCount = ctx.apicall_count; + pack.apicallTime = ctx.apicall_time; + pack.caller = ctx.caller; + if (ctx.login != null) { + pack.login = DataProxy.sendLogin(ctx.login); + } + if (ctx.desc != null) { + pack.desc = DataProxy.sendDesc(ctx.desc); + } + if (ctx.web_name != null) { + pack.webHash = DataProxy.sendWebName(ctx.web_name); + pack.webTime = ctx.web_time; + } + metering(pack); + if (sendOk) { + DataProxy.sendXLog(pack); + } + } catch (Throwable e) { + Logger.println("A146", e); + } + } + + public static void metering(XLogPack pack) { + switch (pack.xType) { + case XLogTypes.WEB_SERVICE: + case XLogTypes.APP_SERVICE: + MeterService.getInstance().add(pack.elapsed, pack.error != 0); + ServiceSummary.getInstance().process(pack); + break; + case XLogTypes.BACK_THREAD: + } + } + + public static boolean isStaticContents(String serviceName) { + int x = serviceName.lastIndexOf('.'); + if (x <= 0) + return false; + try { + String ext = serviceName.substring(x + 1); + return Configure.getInstance().isStaticContents(ext); + } catch (Exception e) { + return false; + } + } + + 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) { + return null; + } + Configure conf = Configure.getInstance(); + ctx = new TraceContext(conf.profile_summary_mode_enabled); + String service_name = name; + ctx.thread = Thread.currentThread(); + ctx.serviceHash = HashUtil.hash(service_name); + ctx.serviceName = service_name; + ctx.startTime = System.currentTimeMillis(); + ctx.startCpu = SysJMX.getCurrentThreadCPU(); + ctx.txid = KeyGen.next(); + ctx.threadId = TraceContextManager.start(ctx.thread, ctx); + ctx.bytes = SysJMX.getCurrentThreadAllocBytes(); + ctx.profile_thread_cputime = conf.profile_thread_cputime_enabled; + ctx.xType = xType; + PluginAppServiceTrace.start(ctx, new HookArgs(className, methodName, methodDesc, _this, arg)); + if (ctx.xType == XLogTypes.BACK_THREAD) { + MethodStep2 ms = new MethodStep2(); + ms.hash = DataProxy.sendMethodName(service_name); + ms.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + if (ctx.profile_thread_cputime) { + ms.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + } + ctx.profile.push(ms); + + return new LocalContext(ctx, ms); + } else { + return new LocalContext(ctx, null); + } + } catch (Throwable t) { + Logger.println("A147", t); + } + return null; + } + + public static void endService(Object stat, Object returnValue, Throwable thr) { + try { + LocalContext localCtx = (LocalContext) stat; + if (localCtx == null) { + return; + } + TraceContext ctx = localCtx.context; + if (ctx == null) { + return; + } + if (ctx.xType == XLogTypes.BACK_THREAD) { + MethodStep2 step = (MethodStep2) localCtx.stepSingle; + step.elapsed = (int) (System.currentTimeMillis() - ctx.startTime) - step.start_time; + if (ctx.profile_thread_cputime) { + step.cputime = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu) - step.start_cpu; + } + step.error = errorCheck(ctx, thr); + ctx.profile.pop(step); + PluginAppServiceTrace.end(ctx); + TraceContextManager.end(ctx.threadId); + ctx.profile.close(true); + return; + } + PluginAppServiceTrace.end(ctx); + TraceContextManager.end(ctx.threadId); + + XLogPack pack = new XLogPack(); + pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + // pack.endTime = System.currentTimeMillis(); + pack.elapsed = (int) (System.currentTimeMillis() - ctx.startTime); + boolean sendOk = pack.elapsed >= Configure.getInstance().xlog_lower_bound_time_ms; + ctx.profile.close(sendOk); + DataProxy.sendServiceName(ctx.serviceHash, ctx.serviceName); + pack.service = ctx.serviceHash; + pack.xType = ctx.xType; + pack.cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + 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.caller = ctx.caller; + pack.ipaddr = IPUtil.toBytes(ctx.remoteIp); + pack.userid = ctx.userid; + pack.error = errorCheck(ctx, thr); + // 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; + if (ctx.login != null) { + pack.login = DataProxy.sendLogin(ctx.login); + } + if (ctx.desc != null) { + pack.desc = DataProxy.sendDesc(ctx.desc); + } + metering(pack); + if (sendOk) { + DataProxy.sendXLog(pack); + } + } catch (Throwable t) { + Logger.println("A148", "service end error", t); + } + } + + private static int errorCheck(TraceContext ctx, Throwable thr) { + int error = 0; + if (ctx.error != 0) { + error = ctx.error; + } else if (thr != null) { + Configure conf = Configure.getInstance(); + String emsg = thr.toString(); + if (conf.profile_fullstack_service_error_enabled) { + StringBuffer sb = new StringBuffer(); + sb.append(emsg).append("\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + while (thr != null) { + sb.append("\nCause...\n"); + ThreadUtil.getStackTrace(sb, thr, conf.profile_fullstack_max_lines); + thr = thr.getCause(); + } + emsg = sb.toString(); + } + error = DataProxy.sendError(emsg); + ServiceSummary.getInstance().process(thr, error, ctx.serviceHash, ctx.txid, 0, 0); + } else if (ctx.userTransaction > 0) { + error = DataProxy.sendError("Missing Commit/Rollback Error"); + ServiceSummary.getInstance().process(userTxNotClose, error, ctx.serviceHash, ctx.txid, 0, 0); + } + return error; + } + + 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_enabled) { + // 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) + return; + HashedMessageStep step = new HashedMessageStep(); + step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + if (ctx.profile_thread_cputime) { + step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + } + step.hash = DataProxy.sendHashedMessage("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(" "); + sb.append(className); + sb.append("."); + sb.append(methodName); + if (ArrayUtil.isEmpty(arg)) { + return sb.toString(); + } + sb.append(" ["); + for (int i = 0, max = arg.length; i < max; i++) { + if (i > 0) + sb.append(","); + String arstr = StringUtil.limiting(ObjectUtil.toString(arg[i]), 80); + sb.append(arstr); + } + 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(" "); + sb.append(className); + sb.append("."); + sb.append(methodName); + sb.append(" ["); + String arstr = StringUtil.limiting(ObjectUtil.toString(arg), 80); + sb.append(arstr); + 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(" "); + sb.append(className); + sb.append(" ["); + String arstr = StringUtil.limiting(ObjectUtil.toString(arg), 80); + sb.append(arstr); + 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_enabled) { + // 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 this1, Object rtn) { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx == null) + return; + PluginCaptureTrace.capReturn(ctx, new HookReturn(className, methodName, methodDesc, this1, rtn)); + } + + public static Object startMethod(int hash, String classMethod) { + if (conf.profile_method_enabled == false) + return null; + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx == null) { + if (conf._trace_auto_service_enabled) { + Object localContext = startService(classMethod, null, null, null, null, null, XLogTypes.APP_SERVICE); + //startService내부에서 에러가 나는 경우(발생하면 안됨) + //Null이 리턴될 수 있음(방어코드) + //@skyworker + if (localContext != null && conf._trace_auto_service_backstack_enabled) { + String stack = ThreadUtil.getStackTrace(Thread.currentThread().getStackTrace(), 2); + AutoServiceStartAnalyzer.put(classMethod, stack); + MessageStep m = new MessageStep(); + m.message = "SERVICE BACKSTACK:\n" + stack; + ((LocalContext) localContext).context.profile.add(m); + } + return localContext; + } + return null; + } + MethodStep p = new MethodStep(); + p.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + if (ctx.profile_thread_cputime) { + p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + } + p.hash = hash; + ctx.profile.push(p); + return new LocalContext(ctx, p); + } + + public static void endMethod(Object localContext, Throwable thr) { + if (localContext == null) + return; + LocalContext lctx = (LocalContext) localContext; + if (lctx.service) { + endService(lctx.option, null, thr); + return; + } + MethodStep step = (MethodStep) lctx.stepSingle; + if (step == null) + return; + TraceContext tctx = lctx.context; + if (tctx == null) + return; + step.elapsed = (int) (System.currentTimeMillis() - tctx.startTime) - step.start_time; + if (tctx.profile_thread_cputime) { + step.cputime = (int) (SysJMX.getCurrentThreadCPU() - tctx.startCpu) - step.start_cpu; + } + tctx.profile.pop(step); + } + + public static void setServiceName(String name) { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx == null || name == null) + return; + 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(); + pack.cpu = cpu; + pack.endTime = endtime; + pack.elapsed = elapsed; + DataProxy.sendServiceName(service_hash, serviceName); + pack.service = service_hash; + pack.bytes = 0; + pack.status = 0; + pack.sqlCount = sqlCount; + pack.sqlTime = sqlTime; + pack.txid = txid; + pack.ipaddr = IPUtil.toBytes(remoteAddr); + pack.userid = visitor; + if (error != null) { + pack.error = DataProxy.sendError(error); + } + MeterService.getInstance().add(pack.elapsed, error != null); + DataProxy.sendXLog(pack); + MeterUsers.add(pack.userid); + return pack; + } + + public static void addMessage(String msg) { + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx == null) + return; + MessageStep p = new MessageStep(); + p.message = msg; + p.start_time = (int) (System.currentTimeMillis() - ctx.startTime); + if (ctx.profile_thread_cputime) { + p.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); + } + ctx.profile.add(p); + } + + public static void ctxLookup(Object this1, Object ctx) { + if (ctx instanceof DataSource) { + LoadedContext.put((DataSource) ctx); + } + } } diff --git a/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java index f9cd4560a..46a37fc78 100644 --- a/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java +++ b/scouter.agent.java/src/scouter/agent/trace/TraceSQL.java @@ -15,10 +15,6 @@ * limitations under the License. */ package scouter.agent.trace; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; import scouter.agent.Configure; import scouter.agent.Logger; import scouter.agent.counter.meter.MeterSQL; @@ -31,18 +27,20 @@ import scouter.jdbc.DetectConnection; import scouter.jdbc.WrConnection; import scouter.lang.AlertLevel; -import scouter.lang.step.HashedMessageStep; -import scouter.lang.step.MessageStep; -import scouter.lang.step.MethodStep; -import scouter.lang.step.SqlStep2; -import scouter.lang.step.SqlXType; -import scouter.util.EscapeLiteralSQL; -import scouter.util.HashUtil; -import scouter.util.IntKeyLinkedMap; -import scouter.util.IntLinkedSet; -import scouter.util.StringUtil; -import scouter.util.SysJMX; -import scouter.util.ThreadUtil; +import scouter.lang.step.*; +import scouter.util.*; + +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * Trace SQL + * @author @author Paul S.J. Kim(sjkim@whatap.io) + * @author Gun Lee (gunlee01@gmail.com) + * @author Eunsu Kim + */ public class TraceSQL { public final static int MAX_STRING = 20; public static void set(int idx, boolean p) { @@ -108,7 +106,7 @@ public static Object start(Object o) { if (ctx == null) { return null; } - SqlStep2 step = new SqlStep2(); + SqlStep3 step = new SqlStep3(); step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); if (ctx.profile_thread_cputime) { step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); @@ -126,7 +124,7 @@ public static Object start(Object o) { ctx.sqltext = sql; return new LocalContext(ctx, step); } - public static Object start(Object o, String sql) { + public static Object start(Object o, String sql, byte methodType) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) { if (conf.log_background_sql) { @@ -158,7 +156,7 @@ public static Object start(Object o, String sql) { ThreadUtil.getThreadStack())); } } - SqlStep2 step = new SqlStep2(); + SqlStep3 step = new SqlStep3(); step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); if (ctx.profile_thread_cputime) { step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); @@ -169,7 +167,7 @@ public static Object start(Object o, String sql) { sql = escapeLiteral(sql, step); } step.hash = DataProxy.sendSqlText(sql); - step.xtype = SqlXType.STMT; + step.xtype =(byte)(SqlXType.STMT | methodType); ctx.profile.push(step); ctx.sqltext = sql; return new LocalContext(ctx, step); @@ -184,7 +182,7 @@ public ParsedSql(String sql, String param) { } private static IntLinkedSet noLiteralSql = new IntLinkedSet().setMax(10000); private static IntKeyLinkedMap checkedSql = new IntKeyLinkedMap().setMax(1001); - private static String escapeLiteral(String sql, SqlStep2 step) { + private static String escapeLiteral(String sql, SqlStep3 step) { if (conf.profile_sql_escape_enabled == false) return sql; int sqlHash = sql.hashCode(); @@ -212,19 +210,27 @@ private static String escapeLiteral(String sql, SqlStep2 step) { private static SQLException tooManyFetch = new TOO_MANY_RECORDS("TOO_MANY_RECORDS", "TOO_MANY_RECORDS"); private static SQLException connectionOpenFail = new CONNECTION_OPEN_FAIL("CONNECTION_OPEN_FAIL", "CONNECTION_OPEN_FAIL"); - public static void end(Object stat, Throwable thr) { + + public static void end(Object stat, Throwable thr, int updatedCount) { if (stat == null) { if (conf.log_background_sql && thr != null) { Logger.println("BG-SQL:" + thr); } return; } - LocalContext lctx = (LocalContext) stat; - TraceContext tctx = lctx.context; - SqlStep2 ps = (SqlStep2) lctx.stepSingle; - ps.elapsed = (int) (System.currentTimeMillis() - tctx.startTime) - ps.start_time; - if (tctx.profile_thread_cputime) { - ps.cputime = (int) (SysJMX.getCurrentThreadCPU() - tctx.startCpu) - ps.start_cpu; + + LocalContext lCtx = (LocalContext) stat; + TraceContext tCtx = lCtx.context; + + Logger.trace("affected row = " + updatedCount); + + SqlStep3 step = (SqlStep3) lCtx.stepSingle; + tCtx.lastSqlStep = step; + + step.elapsed = (int) (System.currentTimeMillis() - tCtx.startTime) - step.start_time; + step.updated = updatedCount; + if (tCtx.profile_thread_cputime) { + step.cputime = (int) (SysJMX.getCurrentThreadCPU() - tCtx.startCpu) - step.start_cpu; } if (thr != null) { String msg = thr.toString(); @@ -241,26 +247,26 @@ public static void end(Object stat, Throwable thr) { msg = sb.toString(); } int hash = DataProxy.sendError(msg); - if (tctx.error == 0) { - tctx.error = hash; + if (tCtx.error == 0) { + tCtx.error = hash; } - ps.error = hash; - ServiceSummary.getInstance().process(thr, hash, tctx.serviceHash, tctx.txid, ps.hash, 0); - } else if (ps.elapsed > conf.xlog_error_sql_time_max_ms) { + step.error = hash; + ServiceSummary.getInstance().process(thr, hash, tCtx.serviceHash, tCtx.txid, step.hash, 0); + } else if (step.elapsed > conf.xlog_error_sql_time_max_ms) { String msg = "warning slow sql, over " + conf.xlog_error_sql_time_max_ms + " ms"; int hash = DataProxy.sendError(msg); - if (tctx.error == 0) { - tctx.error = hash; + if (tCtx.error == 0) { + tCtx.error = hash; } - ServiceSummary.getInstance().process(slowSql, hash, tctx.serviceHash, tctx.txid, ps.hash, 0); + ServiceSummary.getInstance().process(slowSql, hash, tCtx.serviceHash, tCtx.txid, step.hash, 0); } - tctx.sqltext = null; - tctx.sqlActiveArgs = null; - tctx.sqlCount++; - tctx.sqlTime += ps.elapsed; - ServiceSummary.getInstance().process(ps); - MeterSQL.getInstance().add(ps.elapsed, ps.error != 0); - tctx.profile.pop(ps); + tCtx.sqltext = null; + tCtx.sqlActiveArgs = null; + tCtx.sqlCount++; + tCtx.sqlTime += step.elapsed; + ServiceSummary.getInstance().process(step); + MeterSQL.getInstance().add(step.elapsed, step.error != 0); + tCtx.profile.pop(step); } public static void prepare(Object o, String sql) { TraceContext ctx = TraceContextManager.getLocalContext(); @@ -373,7 +379,7 @@ public static void clear(Object o, SqlParameter args) { args.clear(); } } - public static Object start(Object o, SqlParameter args) { + public static Object start(Object o, SqlParameter args, byte methodType) { TraceContext ctx = TraceContextManager.getLocalContext(); if (ctx == null) { if (conf.log_background_sql && args != null) { @@ -405,7 +411,7 @@ public static Object start(Object o, SqlParameter args) { ThreadUtil.getThreadStack())); } } - SqlStep2 step = new SqlStep2(); + SqlStep3 step = new SqlStep3(); step.start_time = (int) (System.currentTimeMillis() - ctx.startTime); if (ctx.profile_thread_cputime) { step.start_cpu = (int) (SysJMX.getCurrentThreadCPU() - ctx.startCpu); @@ -420,7 +426,7 @@ public static Object start(Object o, SqlParameter args) { if (sql != null) { step.hash = DataProxy.sendSqlText(sql); } - step.xtype = SqlXType.PREPARED; + step.xtype =(byte)(SqlXType.PREPARED | methodType); ctx.profile.push(step); ctx.sqltext = sql; return new LocalContext(ctx, step); @@ -618,4 +624,55 @@ public static void sqlMap(String methodName, String sqlname) { .append(sqlname).append(" }").toString()); ctx.profile.add(p); } + + /** + * used for tracing the return of xxx.execute() + * @param b true for resultSet, false for no result or update count + * @return resultSet case -1, update count case -2 + */ + public static int toInt(boolean b) { + //return b?1:0; + return b ? -1 : -2; + } + + /** + * sum of int array + * @param arr + * @return + */ + public static int getIntArraySum(int[] arr) { + int sum = 0; + for(int i=arr.length-1; i>=0; i--) { + sum += arr[i]; + } + Logger.trace("executeBatch-count=" + sum); + return sum; + } + + /** + * apply update count + * @param cnt + * @return + */ + public static int incUpdateCount(int cnt) { + Logger.trace("stmt.getUpdateCount()=" + cnt); + TraceContext ctx = TraceContextManager.getLocalContext(); + if (ctx == null) { + return cnt; + } + SqlStep3 lastSqlStep = (SqlStep3)ctx.lastSqlStep; + if(lastSqlStep == null) { + return cnt; + } + int lastCnt = lastSqlStep.updated; + if(lastCnt == -2 && cnt > 0) { // -2 : execute & the return is the case of update-count + lastCnt = cnt; + lastSqlStep.updated = lastCnt; + } else if(lastCnt >= 0 && cnt > 0) { + lastCnt += cnt; + lastSqlStep.updated = lastCnt; + } + + return cnt; + } } diff --git a/scouter.agent.java/src/scouter/jdbc/WrPreparedStatement.java b/scouter.agent.java/src/scouter/jdbc/WrPreparedStatement.java index 63e5a92ee..3927825fd 100644 --- a/scouter.agent.java/src/scouter/jdbc/WrPreparedStatement.java +++ b/scouter.agent.java/src/scouter/jdbc/WrPreparedStatement.java @@ -17,307 +17,308 @@ package scouter.jdbc; -import java.sql.ResultSet; -import java.sql.SQLException; - import scouter.agent.trace.SqlParameter; import scouter.agent.trace.TraceSQL; +import scouter.lang.step.SqlXType; + +import java.sql.ResultSet; +import java.sql.SQLException; public class WrPreparedStatement extends WrStatement implements java.sql.PreparedStatement { - java.sql.PreparedStatement inner; - SqlParameter sql = new SqlParameter(); - - public WrPreparedStatement(java.sql.PreparedStatement inner, String sql) { - super(inner); - this.inner = inner; - this.sql.setSql(sql); - } - - final public void setBoolean(int a0, boolean a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setBoolean(a0, a1); - } - - final public void setByte(int a0, byte a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setByte(a0, a1); - } - - final public void setShort(int a0, short a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setShort(a0, a1); - } - - final public void setInt(int a0, int a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setInt(a0, a1); - } - - final public void setLong(int a0, long a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setLong(a0, a1); - } - - final public void setFloat(int a0, float a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setFloat(a0, a1); - } - - final public void setDouble(int a0, double a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setDouble(a0, a1); - } - - final public void setTimestamp(int a0, java.sql.Timestamp a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setTimestamp(a0, a1); - } - - final public void setTimestamp(int a0, java.sql.Timestamp a1, java.util.Calendar a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setTimestamp(a0, a1, a2); - } - - final public void setURL(int a0, java.net.URL a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setURL(a0, a1); - } - - final public void setTime(int a0, java.sql.Time a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setTime(a0, a1); - } - - final public void setTime(int a0, java.sql.Time a1, java.util.Calendar a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setTime(a0, a1, a2); - } - - final public boolean execute() throws java.sql.SQLException { - Object stat = TraceSQL.start(this, sql); - try { - boolean b = this.inner.execute(); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public java.sql.ResultSet executeQuery() throws java.sql.SQLException { - Object stat = TraceSQL.start(this, sql); - try { - ResultSet rs = this.inner.executeQuery(); - TraceSQL.end(stat, null); - return new WrResultSet(rs); - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int executeUpdate() throws java.sql.SQLException { - Object stat = TraceSQL.start(this, sql); - try { - int n = this.inner.executeUpdate(); - TraceSQL.end(stat, null); - return n; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public void setNull(int a0, int a1, java.lang.String a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setNull(a0, a1, a2); - } - - final public void setNull(int a0, int a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, null); - this.inner.setNull(a0, a1); - } - - final public void setBigDecimal(int a0, java.math.BigDecimal a1) throws java.sql.SQLException { - this.inner.setBigDecimal(a0, a1); - } - - final public void setString(int a0, java.lang.String a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setString(a0, a1); - } - - final public void setBytes(int a0, byte[] a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[bytes]"); - this.inner.setBytes(a0, a1); - } - - final public void setDate(int a0, java.sql.Date a1, java.util.Calendar a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setDate(a0, a1, a2); - } - - final public void setDate(int a0, java.sql.Date a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setDate(a0, a1); - } - - final public void setAsciiStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[asiistream]"); - this.inner.setAsciiStream(a0, a1, a2); - } - - final public void setAsciiStream(int a0, java.io.InputStream a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[asciistream]"); - this.inner.setAsciiStream(a0, a1); - } - - final public void setAsciiStream(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[asciistream]"); - this.inner.setAsciiStream(a0, a1, a2); - } - - final public void setUnicodeStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { - this.inner.setUnicodeStream(a0, a1, a2); - } - - final public void setBinaryStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[binstream]"); - this.inner.setBinaryStream(a0, a1, a2); - } - - final public void setBinaryStream(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[binstream]"); - this.inner.setBinaryStream(a0, a1, a2); - } - - final public void setBinaryStream(int a0, java.io.InputStream a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[binstream]"); - this.inner.setBinaryStream(a0, a1); - } - - final public void clearParameters() throws java.sql.SQLException { - this.sql.clear(); - this.inner.clearParameters(); - } - - final public void setObject(int a0, java.lang.Object a1, int a2, int a3) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setObject(a0, a1, a2, a3); - } - - final public void setObject(int a0, java.lang.Object a1, int a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setObject(a0, a1, a2); - } - - final public void setObject(int a0, java.lang.Object a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, a1); - this.inner.setObject(a0, a1); - } - - final public void addBatch() throws java.sql.SQLException { - this.inner.addBatch(); - } - - final public void setCharacterStream(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { - this.inner.setCharacterStream(a0, a1, a2); - } - - final public void setCharacterStream(int a0, java.io.Reader a1, int a2) throws java.sql.SQLException { - this.inner.setCharacterStream(a0, a1, a2); - } - - final public void setCharacterStream(int a0, java.io.Reader a1) throws java.sql.SQLException { - this.inner.setCharacterStream(a0, a1); - } - - final public void setRef(int a0, java.sql.Ref a1) throws java.sql.SQLException { - this.inner.setRef(a0, a1); - } - - final public void setBlob(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[blob]"); - this.inner.setBlob(a0, a1, a2); - } - - final public void setBlob(int a0, java.io.InputStream a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[blob]"); - this.inner.setBlob(a0, a1); - } - - final public void setBlob(int a0, java.sql.Blob a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[blob]"); - this.inner.setBlob(a0, a1); - } - - final public void setClob(int a0, java.io.Reader a1) throws java.sql.SQLException { - this.inner.setClob(a0, a1); - } - - final public void setClob(int a0, java.sql.Clob a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[clob]"); - - this.inner.setClob(a0, a1); - } - - final public void setClob(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { - this.inner.setClob(a0, a1, a2); - } - - final public void setArray(int a0, java.sql.Array a1) throws java.sql.SQLException { - TraceSQL.set(sql, a0, "[array]"); - this.inner.setArray(a0, a1); - } - - final public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException { - return this.inner.getMetaData(); - } - - final public java.sql.ParameterMetaData getParameterMetaData() throws java.sql.SQLException { - return this.inner.getParameterMetaData(); - } - - final public void setRowId(int a0, java.sql.RowId a1) throws java.sql.SQLException { - this.inner.setRowId(a0, a1); - } - - final public void setNString(int a0, java.lang.String a1) throws java.sql.SQLException { - this.inner.setNString(a0, a1); - } - - final public void setNCharacterStream(int a0, java.io.Reader a1) throws java.sql.SQLException { - this.inner.setNCharacterStream(a0, a1); - } - - final public void setNCharacterStream(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { - this.inner.setNCharacterStream(a0, a1, a2); - } - - final public void setNClob(int a0, java.io.Reader a1) throws java.sql.SQLException { - this.inner.setNClob(a0, a1); - } - - final public void setNClob(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { - this.inner.setNClob(a0, a1, a2); - } - - final public void setNClob(int a0, java.sql.NClob a1) throws java.sql.SQLException { - this.inner.setNClob(a0, a1); - } - - final public void setSQLXML(int a0, java.sql.SQLXML a1) throws java.sql.SQLException { - this.inner.setSQLXML(a0, a1); - } + java.sql.PreparedStatement inner; + SqlParameter sql = new SqlParameter(); + + public WrPreparedStatement(java.sql.PreparedStatement inner, String sql) { + super(inner); + this.inner = inner; + this.sql.setSql(sql); + } + + final public void setBoolean(int a0, boolean a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setBoolean(a0, a1); + } + + final public void setByte(int a0, byte a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setByte(a0, a1); + } + + final public void setShort(int a0, short a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setShort(a0, a1); + } + + final public void setInt(int a0, int a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setInt(a0, a1); + } + + final public void setLong(int a0, long a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setLong(a0, a1); + } + + final public void setFloat(int a0, float a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setFloat(a0, a1); + } + + final public void setDouble(int a0, double a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setDouble(a0, a1); + } + + final public void setTimestamp(int a0, java.sql.Timestamp a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setTimestamp(a0, a1); + } + + final public void setTimestamp(int a0, java.sql.Timestamp a1, java.util.Calendar a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setTimestamp(a0, a1, a2); + } + + final public void setURL(int a0, java.net.URL a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setURL(a0, a1); + } + + final public void setTime(int a0, java.sql.Time a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setTime(a0, a1); + } + + final public void setTime(int a0, java.sql.Time a1, java.util.Calendar a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setTime(a0, a1, a2); + } + + final public boolean execute() throws java.sql.SQLException { + Object stat = TraceSQL.start(this, sql, SqlXType.METHOD_EXECUTE); + try { + boolean b = this.inner.execute(); + TraceSQL.end(stat, null, TraceSQL.toInt(b)); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public java.sql.ResultSet executeQuery() throws java.sql.SQLException { + Object stat = TraceSQL.start(this, sql, SqlXType.METHOD_QUERY); + try { + ResultSet rs = this.inner.executeQuery(); + TraceSQL.end(stat, null, -1); + return new WrResultSet(rs); + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int executeUpdate() throws java.sql.SQLException { + Object stat = TraceSQL.start(this, sql, SqlXType.METHOD_UPDATE); + try { + int n = this.inner.executeUpdate(); + TraceSQL.end(stat, null, n); + return n; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public void setNull(int a0, int a1, java.lang.String a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setNull(a0, a1, a2); + } + + final public void setNull(int a0, int a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, null); + this.inner.setNull(a0, a1); + } + + final public void setBigDecimal(int a0, java.math.BigDecimal a1) throws java.sql.SQLException { + this.inner.setBigDecimal(a0, a1); + } + + final public void setString(int a0, java.lang.String a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setString(a0, a1); + } + + final public void setBytes(int a0, byte[] a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[bytes]"); + this.inner.setBytes(a0, a1); + } + + final public void setDate(int a0, java.sql.Date a1, java.util.Calendar a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setDate(a0, a1, a2); + } + + final public void setDate(int a0, java.sql.Date a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setDate(a0, a1); + } + + final public void setAsciiStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[asiistream]"); + this.inner.setAsciiStream(a0, a1, a2); + } + + final public void setAsciiStream(int a0, java.io.InputStream a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[asciistream]"); + this.inner.setAsciiStream(a0, a1); + } + + final public void setAsciiStream(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[asciistream]"); + this.inner.setAsciiStream(a0, a1, a2); + } + + final public void setUnicodeStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { + this.inner.setUnicodeStream(a0, a1, a2); + } + + final public void setBinaryStream(int a0, java.io.InputStream a1, int a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[binstream]"); + this.inner.setBinaryStream(a0, a1, a2); + } + + final public void setBinaryStream(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[binstream]"); + this.inner.setBinaryStream(a0, a1, a2); + } + + final public void setBinaryStream(int a0, java.io.InputStream a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[binstream]"); + this.inner.setBinaryStream(a0, a1); + } + + final public void clearParameters() throws java.sql.SQLException { + this.sql.clear(); + this.inner.clearParameters(); + } + + final public void setObject(int a0, java.lang.Object a1, int a2, int a3) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setObject(a0, a1, a2, a3); + } + + final public void setObject(int a0, java.lang.Object a1, int a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setObject(a0, a1, a2); + } + + final public void setObject(int a0, java.lang.Object a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, a1); + this.inner.setObject(a0, a1); + } + + final public void addBatch() throws java.sql.SQLException { + this.inner.addBatch(); + } + + final public void setCharacterStream(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { + this.inner.setCharacterStream(a0, a1, a2); + } + + final public void setCharacterStream(int a0, java.io.Reader a1, int a2) throws java.sql.SQLException { + this.inner.setCharacterStream(a0, a1, a2); + } + + final public void setCharacterStream(int a0, java.io.Reader a1) throws java.sql.SQLException { + this.inner.setCharacterStream(a0, a1); + } + + final public void setRef(int a0, java.sql.Ref a1) throws java.sql.SQLException { + this.inner.setRef(a0, a1); + } + + final public void setBlob(int a0, java.io.InputStream a1, long a2) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[blob]"); + this.inner.setBlob(a0, a1, a2); + } + + final public void setBlob(int a0, java.io.InputStream a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[blob]"); + this.inner.setBlob(a0, a1); + } + + final public void setBlob(int a0, java.sql.Blob a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[blob]"); + this.inner.setBlob(a0, a1); + } + + final public void setClob(int a0, java.io.Reader a1) throws java.sql.SQLException { + this.inner.setClob(a0, a1); + } + + final public void setClob(int a0, java.sql.Clob a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[clob]"); + + this.inner.setClob(a0, a1); + } + + final public void setClob(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { + this.inner.setClob(a0, a1, a2); + } + + final public void setArray(int a0, java.sql.Array a1) throws java.sql.SQLException { + TraceSQL.set(sql, a0, "[array]"); + this.inner.setArray(a0, a1); + } + + final public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException { + return this.inner.getMetaData(); + } + + final public java.sql.ParameterMetaData getParameterMetaData() throws java.sql.SQLException { + return this.inner.getParameterMetaData(); + } + + final public void setRowId(int a0, java.sql.RowId a1) throws java.sql.SQLException { + this.inner.setRowId(a0, a1); + } + + final public void setNString(int a0, java.lang.String a1) throws java.sql.SQLException { + this.inner.setNString(a0, a1); + } + + final public void setNCharacterStream(int a0, java.io.Reader a1) throws java.sql.SQLException { + this.inner.setNCharacterStream(a0, a1); + } + + final public void setNCharacterStream(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { + this.inner.setNCharacterStream(a0, a1, a2); + } + + final public void setNClob(int a0, java.io.Reader a1) throws java.sql.SQLException { + this.inner.setNClob(a0, a1); + } + + final public void setNClob(int a0, java.io.Reader a1, long a2) throws java.sql.SQLException { + this.inner.setNClob(a0, a1, a2); + } + + final public void setNClob(int a0, java.sql.NClob a1) throws java.sql.SQLException { + this.inner.setNClob(a0, a1); + } + + final public void setSQLXML(int a0, java.sql.SQLXML a1) throws java.sql.SQLException { + this.inner.setSQLXML(a0, a1); + } } \ No newline at end of file diff --git a/scouter.agent.java/src/scouter/jdbc/WrStatement.java b/scouter.agent.java/src/scouter/jdbc/WrStatement.java index c99925c0b..23cdbd343 100644 --- a/scouter.agent.java/src/scouter/jdbc/WrStatement.java +++ b/scouter.agent.java/src/scouter/jdbc/WrStatement.java @@ -17,298 +17,299 @@ package scouter.jdbc; +import scouter.agent.trace.TraceSQL; +import scouter.lang.step.SqlXType; + import java.sql.ResultSet; import java.sql.SQLException; -import scouter.agent.trace.TraceSQL; - public class WrStatement implements java.sql.Statement { - java.sql.Statement inner; - - public WrStatement(java.sql.Statement inner) { - this.inner = inner; - } - - final public void close() throws java.sql.SQLException { - this.inner.close(); - } - - final public java.sql.Connection getConnection() throws java.sql.SQLException { - return this.inner.getConnection(); - } - - final public boolean execute(java.lang.String a0, int[] a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - boolean b = this.inner.execute(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public boolean execute(java.lang.String a0, java.lang.String[] a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - boolean b = this.inner.execute(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public boolean execute(java.lang.String a0, int a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - boolean b = this.inner.execute(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public boolean execute(java.lang.String a0) throws java.sql.SQLException { - - Object stat = TraceSQL.start(this, a0); - try { - boolean b = this.inner.execute(a0); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public java.sql.ResultSet executeQuery(java.lang.String a0) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - ResultSet rs = this.inner.executeQuery(a0); - TraceSQL.end(stat, null); - return new WrResultSet(rs); - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int executeUpdate(java.lang.String a0, java.lang.String[] a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - int b = this.inner.executeUpdate(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int executeUpdate(java.lang.String a0, int a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - int b = this.inner.executeUpdate(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int executeUpdate(java.lang.String a0) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - int b = this.inner.executeUpdate(a0); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int executeUpdate(java.lang.String a0, int[] a1) throws java.sql.SQLException { - Object stat = TraceSQL.start(this, a0); - try { - int b = this.inner.executeUpdate(a0,a1); - TraceSQL.end(stat, null); - return b; - } catch (SQLException ex) { - TraceSQL.end(stat, ex); - throw ex; - } catch (Throwable t) { - TraceSQL.end(stat, t); - throw new SQLException(t); - } - } - - final public int getMaxFieldSize() throws java.sql.SQLException { - return this.inner.getMaxFieldSize(); - } - - final public void setMaxFieldSize(int a0) throws java.sql.SQLException { - this.inner.setMaxFieldSize(a0); - } - - final public int getMaxRows() throws java.sql.SQLException { - return this.inner.getMaxRows(); - } - - final public void setMaxRows(int a0) throws java.sql.SQLException { - this.inner.setMaxRows(a0); - } - - final public void setEscapeProcessing(boolean a0) throws java.sql.SQLException { - this.inner.setEscapeProcessing(a0); - } - - final public int getQueryTimeout() throws java.sql.SQLException { - return this.inner.getQueryTimeout(); - } - - final public void setQueryTimeout(int a0) throws java.sql.SQLException { - this.inner.setQueryTimeout(a0); - } - - final public void cancel() throws java.sql.SQLException { - this.inner.cancel(); - } - - final public java.sql.SQLWarning getWarnings() throws java.sql.SQLException { - return this.inner.getWarnings(); - } - - final public void clearWarnings() throws java.sql.SQLException { - this.inner.clearWarnings(); - } - - final public void setCursorName(java.lang.String a0) throws java.sql.SQLException { - this.inner.setCursorName(a0); - } - - final public java.sql.ResultSet getResultSet() throws java.sql.SQLException { - ResultSet rs = this.inner.getResultSet(); - return new WrResultSet(rs); - } - - final public int getUpdateCount() throws java.sql.SQLException { - return this.inner.getUpdateCount(); - } - - final public boolean getMoreResults(int a0) throws java.sql.SQLException { - return this.inner.getMoreResults(a0); - } - - final public boolean getMoreResults() throws java.sql.SQLException { - return this.inner.getMoreResults(); - } - - final public void setFetchDirection(int a0) throws java.sql.SQLException { - this.inner.setFetchDirection(a0); - } - - final public int getFetchDirection() throws java.sql.SQLException { - return this.inner.getFetchDirection(); - } - - final public void setFetchSize(int a0) throws java.sql.SQLException { - this.inner.setFetchSize(a0); - } - - final public int getFetchSize() throws java.sql.SQLException { - return this.inner.getFetchSize(); - } - - final public int getResultSetConcurrency() throws java.sql.SQLException { - return this.inner.getResultSetConcurrency(); - } - - final public int getResultSetType() throws java.sql.SQLException { - return this.inner.getResultSetType(); - } - - final public void addBatch(java.lang.String a0) throws java.sql.SQLException { - this.inner.addBatch(a0); - } - - final public void clearBatch() throws java.sql.SQLException { - this.inner.clearBatch(); - } - - final public int[] executeBatch() throws java.sql.SQLException { - return this.inner.executeBatch(); - } - - final public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException { - return this.inner.getGeneratedKeys(); - } - - final public int getResultSetHoldability() throws java.sql.SQLException { - return this.inner.getResultSetHoldability(); - } - - final public boolean isClosed() throws java.sql.SQLException { - return this.inner.isClosed(); - } - - final public void setPoolable(boolean a0) throws java.sql.SQLException { - this.inner.setPoolable(a0); - } - - final public boolean isPoolable() throws java.sql.SQLException { - return this.inner.isPoolable(); - } - - - - public void closeOnCompletion() throws SQLException { - // TODO Auto-generated method stub - - } + java.sql.Statement inner; + + public WrStatement(java.sql.Statement inner) { + this.inner = inner; + } + + final public void close() throws java.sql.SQLException { + this.inner.close(); + } + + final public java.sql.Connection getConnection() throws java.sql.SQLException { + return this.inner.getConnection(); + } + + final public boolean execute(java.lang.String a0, int[] a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_EXECUTE); + try { + boolean b = this.inner.execute(a0, a1); + TraceSQL.end(stat, null, TraceSQL.toInt(b)); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public boolean execute(java.lang.String a0, java.lang.String[] a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_EXECUTE); + try { + boolean b = this.inner.execute(a0, a1); + TraceSQL.end(stat, null,TraceSQL.toInt(b)); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public boolean execute(java.lang.String a0, int a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_EXECUTE); + try { + boolean b = this.inner.execute(a0, a1); + TraceSQL.end(stat, null, TraceSQL.toInt(b)); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public boolean execute(java.lang.String a0) throws java.sql.SQLException { + + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_EXECUTE); + try { + boolean b = this.inner.execute(a0); + TraceSQL.end(stat, null, TraceSQL.toInt(b)); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, 0); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, 0); + throw new SQLException(t); + } + } + + final public java.sql.ResultSet executeQuery(java.lang.String a0) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_QUERY); + try { + ResultSet rs = this.inner.executeQuery(a0); + TraceSQL.end(stat, null, -1); + return new WrResultSet(rs); + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int executeUpdate(java.lang.String a0, java.lang.String[] a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_UPDATE); + try { + int n = this.inner.executeUpdate(a0, a1); + TraceSQL.end(stat, null, n); + return n; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int executeUpdate(java.lang.String a0, int a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_UPDATE); + try { + int n = this.inner.executeUpdate(a0, a1); + TraceSQL.end(stat, null, n); + return n; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int executeUpdate(java.lang.String a0) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_UPDATE); + try { + int b = this.inner.executeUpdate(a0); + TraceSQL.end(stat, null, b); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int executeUpdate(java.lang.String a0, int[] a1) throws java.sql.SQLException { + Object stat = TraceSQL.start(this, a0, SqlXType.METHOD_UPDATE); + try { + int b = this.inner.executeUpdate(a0, a1); + TraceSQL.end(stat, null, b); + return b; + } catch (SQLException ex) { + TraceSQL.end(stat, ex, -3); + throw ex; + } catch (Throwable t) { + TraceSQL.end(stat, t, -3); + throw new SQLException(t); + } + } + + final public int getMaxFieldSize() throws java.sql.SQLException { + return this.inner.getMaxFieldSize(); + } + + final public void setMaxFieldSize(int a0) throws java.sql.SQLException { + this.inner.setMaxFieldSize(a0); + } + + final public int getMaxRows() throws java.sql.SQLException { + return this.inner.getMaxRows(); + } + + final public void setMaxRows(int a0) throws java.sql.SQLException { + this.inner.setMaxRows(a0); + } + + final public void setEscapeProcessing(boolean a0) throws java.sql.SQLException { + this.inner.setEscapeProcessing(a0); + } + + final public int getQueryTimeout() throws java.sql.SQLException { + return this.inner.getQueryTimeout(); + } + + final public void setQueryTimeout(int a0) throws java.sql.SQLException { + this.inner.setQueryTimeout(a0); + } + + final public void cancel() throws java.sql.SQLException { + this.inner.cancel(); + } + + final public java.sql.SQLWarning getWarnings() throws java.sql.SQLException { + return this.inner.getWarnings(); + } + + final public void clearWarnings() throws java.sql.SQLException { + this.inner.clearWarnings(); + } + + final public void setCursorName(java.lang.String a0) throws java.sql.SQLException { + this.inner.setCursorName(a0); + } + + final public java.sql.ResultSet getResultSet() throws java.sql.SQLException { + ResultSet rs = this.inner.getResultSet(); + return new WrResultSet(rs); + } + + final public int getUpdateCount() throws java.sql.SQLException { + return TraceSQL.incUpdateCount(this.inner.getUpdateCount()); + //return this.inner.getUpdateCount(); + } + + final public boolean getMoreResults(int a0) throws java.sql.SQLException { + return this.inner.getMoreResults(a0); + } + + final public boolean getMoreResults() throws java.sql.SQLException { + return this.inner.getMoreResults(); + } + + final public void setFetchDirection(int a0) throws java.sql.SQLException { + this.inner.setFetchDirection(a0); + } + + final public int getFetchDirection() throws java.sql.SQLException { + return this.inner.getFetchDirection(); + } + + final public void setFetchSize(int a0) throws java.sql.SQLException { + this.inner.setFetchSize(a0); + } + + final public int getFetchSize() throws java.sql.SQLException { + return this.inner.getFetchSize(); + } + + final public int getResultSetConcurrency() throws java.sql.SQLException { + return this.inner.getResultSetConcurrency(); + } + + final public int getResultSetType() throws java.sql.SQLException { + return this.inner.getResultSetType(); + } + + final public void addBatch(java.lang.String a0) throws java.sql.SQLException { + this.inner.addBatch(a0); + } + + final public void clearBatch() throws java.sql.SQLException { + this.inner.clearBatch(); + } + + final public int[] executeBatch() throws java.sql.SQLException { + return this.inner.executeBatch(); + } + + final public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException { + return this.inner.getGeneratedKeys(); + } + + final public int getResultSetHoldability() throws java.sql.SQLException { + return this.inner.getResultSetHoldability(); + } + + final public boolean isClosed() throws java.sql.SQLException { + return this.inner.isClosed(); + } + + final public void setPoolable(boolean a0) throws java.sql.SQLException { + this.inner.setPoolable(a0); + } + + final public boolean isPoolable() throws java.sql.SQLException { + return this.inner.isPoolable(); + } + + + public void closeOnCompletion() throws SQLException { + // TODO Auto-generated method stub + + } + + public boolean isCloseOnCompletion() throws SQLException { + // TODO Auto-generated method stub + return false; + } + + public T unwrap(Class iface) throws SQLException { + // TODO Auto-generated method stub + return null; + } - public boolean isCloseOnCompletion() throws SQLException { - // TODO Auto-generated method stub - return false; - } - - public T unwrap(Class iface) throws SQLException { - // TODO Auto-generated method stub - return null; - } - - public boolean isWrapperFor(Class iface) throws SQLException { - // TODO Auto-generated method stub - return false; - } + public boolean isWrapperFor(Class iface) throws SQLException { + // TODO Auto-generated method stub + return false; + } } \ No newline at end of file diff --git a/scouter.client/gallery/1024x1024.png b/scouter.client/gallery/1024x1024.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/128x128.png b/scouter.client/gallery/128x128.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/16x16.png b/scouter.client/gallery/16x16.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/24x24.png b/scouter.client/gallery/24x24.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/256x256.png b/scouter.client/gallery/256x256.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/32x32.png b/scouter.client/gallery/32x32.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/48x48.png b/scouter.client/gallery/48x48.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/512x512.png b/scouter.client/gallery/512x512.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/64x64.png b/scouter.client/gallery/64x64.png old mode 100755 new mode 100644 diff --git a/scouter.client/gallery/96x96.png b/scouter.client/gallery/96x96.png old mode 100755 new mode 100644 diff --git a/scouter.client/src/scouter/client/net/LoginMgr.java b/scouter.client/src/scouter/client/net/LoginMgr.java index 756a5c621..7bb222855 100644 --- a/scouter.client/src/scouter/client/net/LoginMgr.java +++ b/scouter.client/src/scouter/client/net/LoginMgr.java @@ -32,65 +32,9 @@ public class LoginMgr{ public static boolean login(int serverId, String user, String password){ - try { - MapPack param = new MapPack(); - param.put("id", user); - String encrypted = CipherUtil.md5(password); - param.put("pass", encrypted); - param.put("version", Version.getClientFullVersion()); - param.put("hostname", SysJMX.getHostName()); - MapPack out = TcpProxy.loginProxy(serverId, param); - if (out != null) { - long session = out.getLong("session"); - String error = out.getText("error"); - if(error != null && session == 0L){ - return false; - } - long time = out.getLong("time"); - String hostname = out.getText("hostname"); - String type = out.getText("type"); - String version = out.getText("version"); - String email = out.getText("email"); - String timezone = out.getText("timezone"); - - Server server = ServerManager.getInstance().getServer(serverId); - server.setOpen(true); - server.setSession(session); - server.setName(hostname); - server.setDelta(time); - server.setUserId(user); - server.setPassword(encrypted); - server.setGroup(type); - server.setVersion(version); - server.setEmail(email); - server.setTimezone(timezone); - Value value = out.get("policy"); - if (value != null) { - MapValue mv = (MapValue) value; - server.setGroupPolicy(mv); - } - Value menuV = out.get("menu"); - if (menuV != null) { - MapValue mv = (MapValue) menuV; - server.setMenuEnableMap(mv); - } - CounterEngine counterEngine = server.getCounterEngine(); - MapPack m = getCounterXmlServer(serverId); - if (m != null) { - counterEngine.clear(); - Value v1 = m.get("default"); - counterEngine.parse(((BlobValue)v1).value); - v1 = m.get("custom"); - if (v1 != null) { - counterEngine.parse(((BlobValue)v1).value); - } - } - return true; - } - } catch(Exception e){ - e.printStackTrace(); - } - return false; + Server server = ServerManager.getInstance().getServer(serverId); + String encrypted = CipherUtil.md5(password); + return silentLogin(server, user, encrypted); } public static boolean silentLogin(Server server, String user, String encryptedPwd){ @@ -111,14 +55,14 @@ public static boolean silentLogin(Server server, String user, String encryptedPw } server.setOpen(true); long time = out.getLong("time"); - String hostname = out.getText("hostname"); + String serverName = out.getText("server_id"); String type = out.getText("type"); String version = out.getText("version"); String email = out.getText("email"); String timezone = out.getText("timezone"); server.setSession(session); - server.setName(hostname); + server.setName(serverName); server.setDelta(time); server.setUserId(user); server.setPassword(encryptedPwd); diff --git a/scouter.client/src/scouter/client/popup/LoginDialog.java b/scouter.client/src/scouter/client/popup/LoginDialog.java index b9d010a51..2b1db71ac 100644 --- a/scouter.client/src/scouter/client/popup/LoginDialog.java +++ b/scouter.client/src/scouter/client/popup/LoginDialog.java @@ -43,6 +43,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import scouter.Version; import scouter.client.Activator; import scouter.client.net.LoginMgr; import scouter.client.preferences.ServerPrefUtil; @@ -94,7 +95,7 @@ public LoginDialog(Display display, ILoginDialog callback, int openType, String public void show() { switch (openType) { case TYPE_STARTUP: - shell.setText("Start"); + shell.setText(Version.getClientFullVersion()); this.address = ServerPrefUtil.getStoredDefaultServer(); break; case TYPE_ADD_SERVER: diff --git a/scouter.client/src/scouter/client/views/AlertDetailListView.java b/scouter.client/src/scouter/client/views/AlertDetailListView.java index 4a9486b93..ae1f845ec 100644 --- a/scouter.client/src/scouter/client/views/AlertDetailListView.java +++ b/scouter.client/src/scouter/client/views/AlertDetailListView.java @@ -136,14 +136,15 @@ public void handleEvent(Event event) { } }); + long now = TimeUtil.getCurrentTime(serverId); label = new Label(parentGroup, SWT.NONE); label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); label.setText("From"); fromTime = new DateTime(parentGroup, SWT.TIME | SWT.SHORT); fromTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - fromTime.setHours(0); - fromTime.setMinutes(0); + fromTime.setHours(DateUtil.getHour(now) - 1); + fromTime.setMinutes(DateUtil.getMin(now)); label = new Label(parentGroup, SWT.NONE); label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); @@ -151,8 +152,8 @@ public void handleEvent(Event event) { toTime = new DateTime(parentGroup, SWT.TIME | SWT.SHORT); toTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - toTime.setHours(1); - toTime.setMinutes(0); + toTime.setHours(DateUtil.getHour(now)); + toTime.setMinutes(DateUtil.getMin(now)); label = new Label(parentGroup, SWT.NONE); label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); diff --git a/scouter.client/src/scouter/client/xlog/ProfileText.java b/scouter.client/src/scouter/client/xlog/ProfileText.java index 7bb4bd630..2453c3258 100644 --- a/scouter.client/src/scouter/client/xlog/ProfileText.java +++ b/scouter.client/src/scouter/client/xlog/ProfileText.java @@ -45,6 +45,7 @@ import scouter.lang.step.SocketSum; import scouter.lang.step.SqlStep; import scouter.lang.step.SqlStep2; +import scouter.lang.step.SqlStep3; import scouter.lang.step.SqlSum; import scouter.lang.step.SqlXType; import scouter.lang.step.Step; @@ -61,716 +62,746 @@ import scouter.util.StringUtil; public class ProfileText { - public static void build(final String date, StyledText text, XLogData xperf, Step[] profiles, int spaceCnt, - int serverId) { - - boolean truncated = false; - - if (profiles == null) { - profiles = new Step[0]; - } - profiles = SortUtil.sort(profiles); - XLogUtil.loadStepText(serverId, date, profiles); - - String error = TextProxy.error.getLoadText(date, xperf.p.error, serverId); - Color blue = text.getDisplay().getSystemColor(SWT.COLOR_BLUE); - Color dmagenta = text.getDisplay().getSystemColor(SWT.COLOR_DARK_MAGENTA); - Color red = text.getDisplay().getSystemColor(SWT.COLOR_RED); - - Color dred = text.getDisplay().getSystemColor(SWT.COLOR_DARK_RED); - Color dgreen = text.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); - - java.util.List sr = new ArrayList(); - - int slen = 0; - - final StringBuffer sb = new StringBuffer(); - sb.append("► txid = "); - slen = sb.length(); - sb.append(Hexa32.toString32(xperf.p.txid)).append("\n"); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - if (xperf.p.gxid != 0) { - sb.append("► gxid = "); - slen = sb.length(); - sb.append(Hexa32.toString32(xperf.p.gxid)).append("\n"); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - } - if (xperf.p.caller != 0) { - sb.append("► caller = "); - slen = sb.length(); - sb.append(Hexa32.toString32(xperf.p.caller)).append("\n"); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - } - sb.append("► objName = ").append(xperf.objName).append("\n"); - sb.append("► endtime = ").append(DateUtil.timestamp(xperf.p.endTime)).append("\n"); - sb.append("► elapsed = ").append(FormatUtil.print(xperf.p.elapsed, "#,##0")).append(" ms\n"); - sb.append("► service = ").append(TextProxy.service.getText(xperf.p.service)).append("\n"); - if (error != null) { - sb.append("► error = "); - slen = sb.length(); - sb.append(error).append("\n"); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - - sb.append("► ipaddr=" + IPUtil.toString(xperf.p.ipaddr) + ", "); - sb.append("userid=" + xperf.p.userid); - sb.append("\n► cpu=" + FormatUtil.print(xperf.p.cpu, "#,##0") + " ms, "); - sb.append("bytes=" + xperf.p.bytes); + public static void build(final String date, StyledText text, XLogData xperf, Step[] profiles, int spaceCnt, + int serverId) { + + boolean truncated = false; + + if (profiles == null) { + profiles = new Step[0]; + } + profiles = SortUtil.sort(profiles); + XLogUtil.loadStepText(serverId, date, profiles); + + String error = TextProxy.error.getLoadText(date, xperf.p.error, serverId); + Color blue = text.getDisplay().getSystemColor(SWT.COLOR_BLUE); + Color dmagenta = text.getDisplay().getSystemColor(SWT.COLOR_DARK_MAGENTA); + Color red = text.getDisplay().getSystemColor(SWT.COLOR_RED); + + Color dred = text.getDisplay().getSystemColor(SWT.COLOR_DARK_RED); + Color dgreen = text.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); + + java.util.List sr = new ArrayList(); + + int slen = 0; + + final StringBuffer sb = new StringBuffer(); + sb.append("► txid = "); + slen = sb.length(); + sb.append(Hexa32.toString32(xperf.p.txid)).append("\n"); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + if (xperf.p.gxid != 0) { + sb.append("► gxid = "); + slen = sb.length(); + sb.append(Hexa32.toString32(xperf.p.gxid)).append("\n"); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + } + if (xperf.p.caller != 0) { + sb.append("► caller = "); + slen = sb.length(); + sb.append(Hexa32.toString32(xperf.p.caller)).append("\n"); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + } + sb.append("► objName = ").append(xperf.objName).append("\n"); + sb.append("► endtime = ").append(DateUtil.timestamp(xperf.p.endTime)).append("\n"); + sb.append("► elapsed = ").append(FormatUtil.print(xperf.p.elapsed, "#,##0")).append(" ms\n"); + sb.append("► service = ").append(TextProxy.service.getText(xperf.p.service)).append("\n"); + if (error != null) { + sb.append("► error = "); + slen = sb.length(); + sb.append(error).append("\n"); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + + sb.append("► ipaddr=" + IPUtil.toString(xperf.p.ipaddr) + ", "); + sb.append("userid=" + xperf.p.userid); + sb.append("\n► cpu=" + FormatUtil.print(xperf.p.cpu, "#,##0") + " ms, "); + sb.append("bytes=" + xperf.p.bytes); // sb.append("bytes=" + xperf.p.bytes + ", "); // sb.append("status=" + xperf.p.status); - if (xperf.p.sqlCount > 0) { - sb.append("\n► sqlCount=" + xperf.p.sqlCount + ", "); - sb.append("sqlTime=" + FormatUtil.print(xperf.p.sqlTime, "#,##0") + " ms"); - } - if (xperf.p.apicallCount > 0) { - sb.append("\n► ApiCallCount=" + xperf.p.apicallCount + ", "); - sb.append("ApiCallTime=" + FormatUtil.print(xperf.p.apicallTime, "#,##0") + " ms"); - } - - String t = TextProxy.userAgent.getLoadText(date, xperf.p.userAgent, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► userAgent=" + t); - } - - t = TextProxy.referer.getLoadText(date, xperf.p.referer, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► referer=" + t); - } - - t = TextProxy.group.getLoadText(date, xperf.p.group, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► group=" + t); - } - if (StringUtil.isNotEmpty(xperf.p.countryCode)) { - sb.append("\n► country=" + CountryCode.getCountryName(xperf.p.countryCode)); - } - t = TextProxy.city.getLoadText(date, xperf.p.city, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► city=" + t); - } - t = TextProxy.web.getLoadText(date, xperf.p.webHash, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► webName=" + t).append(" webTime=" + xperf.p.webTime + " ms"); - } - t = TextProxy.login.getLoadText(date, xperf.p.login, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► login=" + t); - } - t = TextProxy.desc.getLoadText(date, xperf.p.desc, serverId); - if (StringUtil.isNotEmpty(t)) { - sb.append("\n► desc=" + t); - } - sb.append("\n"); - - sb.append("------------------------------------------------------------------------------------------\n"); - sb.append(" p# # TIME T-GAP CPU CONTENTS\n"); - sb.append("------------------------------------------------------------------------------------------\n"); - if (profiles.length == 0) { - sb.append("\n ( No xlog profile collected ) "); - text.setText(sb.toString()); - // for (int i = 0; i < sr.size(); i++) { - text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); - // } - return; - } - - long stime = xperf.p.endTime - xperf.p.elapsed; - long prev_tm = stime; - long prev_cpu = 0; - - sb.append(" "); - sb.append(" "); - sb.append("[******]"); - sb.append(" "); - sb.append(DateUtil.getLogTime(stime)); - sb.append(" "); - sb.append(String.format("%6s", "0")); - sb.append(" "); - sb.append(String.format("%6s", "0")); - sb.append(" start transaction \n"); - // sr.add(style(slen, sb.length() - slen, dblue, SWT.NORMAL)); - - long tm = xperf.p.endTime; - long cpu = xperf.p.cpu; - int sumCnt = 1; - HashMap indent = new HashMap(); - for (int i = 0; i < profiles.length; i++) { - - if (truncated) - break; - - if (profiles[i] instanceof StepSummary) { - sb.append(" ").append(" "); - sb.append(String.format("[%06d]", sumCnt++)); - sb.append(" "); - - StepSummary sum = (StepSummary) profiles[i]; - switch (sum.getStepType()) { - case StepEnum.METHOD_SUM: - XLogProfileView.isSummary = true; - - MethodSum p = (MethodSum) sum; - slen = sb.length(); - - String m = TextProxy.method.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append(m).append(" "); - - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - - sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); - sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); - - sb.append("\n"); - break; - case StepEnum.SQL_SUM: - XLogProfileView.isSummary = true; - SqlSum sql = (SqlSum) sum; - slen = sb.length(); - toString(sb, sql, serverId); - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.APICALL_SUM: - XLogProfileView.isSummary = true; - ApiCallSum apicall = (ApiCallSum) sum; - slen = sb.length(); - toString(sb, apicall); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.SOCKET_SUM: - XLogProfileView.isSummary = true; - SocketSum socketSum = (SocketSum) sum; - slen = sb.length(); - toString(sb, socketSum); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.CONTROL: - - sb.delete(sb.length() - 9, sb.length()); - - sb.append("[******]"); - sb.append(" "); - sb.append(DateUtil.getLogTime(tm)); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); - sb.append(" "); - slen = sb.length(); - toString(sb, (StepControl) sum); - sr.add(style(slen, sb.length() - slen, dred, SWT.NORMAL)); - sb.append("\n"); - - truncated = true; - - break; - } - continue; - } - - StepSingle stepSingle = (StepSingle) profiles[i]; - tm = stepSingle.start_time + stime; - cpu = stepSingle.start_cpu; - - // sr.add(style(sb.length(), 6, blue, SWT.NORMAL)); - int p1 = sb.length(); - String pid = String.format("[%06d]", stepSingle.parent); - sb.append((stepSingle.parent == -1) ? " - " : pid); - sb.append(" "); - sb.append(String.format("[%06d]", stepSingle.index)); - sb.append(" "); - sb.append(DateUtil.getLogTime(tm)); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); - sb.append(" "); - int lineHead = sb.length() - p1; - - int space = 0; - if (indent.containsKey(stepSingle.parent)) { - space = indent.get(stepSingle.parent) + spaceCnt; - } - indent.put(stepSingle.index, space); - while (space > 0) { - sb.append(" "); - space--; - } - - switch (stepSingle.getStepType()) { - case StepEnum.METHOD: - toString(sb, (MethodStep) stepSingle); - break; - case StepEnum.METHOD2: - toString(sb, (MethodStep) stepSingle); - MethodStep2 m2 = (MethodStep2) stepSingle; - if (m2.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(m2.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.SQL: - case StepEnum.SQL2: - SqlStep sql = (SqlStep) stepSingle; - slen = sb.length(); - toString(sb, sql, serverId, lineHead); - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - if (sql.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(sql.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.MESSAGE: - slen = sb.length(); - toString(sb, (MessageStep) stepSingle); - sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); - break; - case StepEnum.HASHED_MESSAGE: - slen = sb.length(); - toString(sb, (HashedMessageStep) stepSingle); - sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); - break; - case StepEnum.APICALL: - ApiCallStep apicall = (ApiCallStep) stepSingle; - slen = sb.length(); - toString(sb, apicall); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - if (apicall.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(apicall.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.THREAD_SUBMIT: - ThreadSubmitStep threadSubmit = (ThreadSubmitStep) stepSingle; - slen = sb.length(); - toString(sb, threadSubmit); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - if (threadSubmit.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(threadSubmit.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.SOCKET: - SocketStep socket = (SocketStep) stepSingle; - slen = sb.length(); - toString(sb, socket); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - if (socket.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(socket.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - } - sb.append("\n"); - prev_cpu = cpu; - prev_tm = tm; - } - - if (!truncated) { - - tm = xperf.p.endTime; - cpu = xperf.p.cpu; - sb.append(" "); - sb.append(" "); - sb.append("[******]"); - sb.append(" "); - sb.append(DateUtil.getLogTime(tm)); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); - sb.append(" end of transaction \n"); - - } - sb.append("------------------------------------------------------------------------------------------\n"); - - text.setText(sb.toString()); - text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); - - } - - public static void buildThreadProfile(XLogData data, StyledText text, Step[] profiles) { - if (profiles == null) { - profiles = new Step[0]; - } - int serverId = data.serverId; - String date = DateUtil.yyyymmdd(data.p.endTime); - profiles = SortUtil.sort(profiles); - XLogUtil.loadStepText(serverId, date, profiles); - Color blue = text.getDisplay().getSystemColor(SWT.COLOR_BLUE); - Color dmagenta = text.getDisplay().getSystemColor(SWT.COLOR_DARK_MAGENTA); - Color red = text.getDisplay().getSystemColor(SWT.COLOR_RED); - Color dred = text.getDisplay().getSystemColor(SWT.COLOR_DARK_RED); - Color dgreen = text.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); - java.util.List sr = new ArrayList(); - int slen = 0; - final StringBuffer sb = new StringBuffer(); - - sb.append("------------------------------------------------------------------------------------------\n"); - sb.append(" p# # TIME T-GAP CPU CONTENTS\n"); - sb.append("------------------------------------------------------------------------------------------\n"); - if (profiles.length == 0) { - sb.append("\n ( No xlog profile collected ) "); - text.setText(sb.toString()); - text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); - return; - } - - long stime = data.p.endTime - data.p.elapsed; - long prev_tm = stime; - long tm = stime; - int prev_cpu = -1; - int cpu = 0; - int sumCnt = 1; - HashMap indent = new HashMap(); - for (int i = 0; i < profiles.length; i++) { - if (profiles[i] instanceof StepSummary) { - sb.append(" ").append(" "); - sb.append(String.format("[%06d]", sumCnt++)); - sb.append(" "); - - StepSummary sum = (StepSummary) profiles[i]; - switch (sum.getStepType()) { - case StepEnum.METHOD_SUM: - MethodSum p = (MethodSum) sum; - slen = sb.length(); - String m = TextProxy.method.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append(m).append(" "); - - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - - sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); - sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); - - sb.append("\n"); - break; - case StepEnum.SQL_SUM: - SqlSum sql = (SqlSum) sum; - slen = sb.length(); - toString(sb, sql, serverId); - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.APICALL_SUM: - ApiCallSum apicall = (ApiCallSum) sum; - slen = sb.length(); - toString(sb, apicall); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.SOCKET_SUM: - SocketSum socketSum = (SocketSum) sum; - slen = sb.length(); - toString(sb, socketSum); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - sb.append("\n"); - break; - case StepEnum.CONTROL: - sb.delete(sb.length() - 9, sb.length()); - sb.append("[******]"); - sb.append(" "); - sb.append(DateUtil.getLogTime(data.p.endTime)); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(data.p.elapsed, "#,##0"))); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(data.p.cpu, "#,##0"))); - sb.append(" "); - slen = sb.length(); - toString(sb, (StepControl) sum); - sr.add(style(slen, sb.length() - slen, dred, SWT.NORMAL)); - sb.append("\n"); - break; - } - continue; - } - - StepSingle stepSingle = (StepSingle) profiles[i]; - tm = stime + stepSingle.start_time; - cpu = stepSingle.start_cpu; - - // sr.add(style(sb.length(), 6, blue, SWT.NORMAL)); - int p1 = sb.length(); - String pid = String.format("[%06d]", stepSingle.parent); - sb.append((stepSingle.parent == -1) ? " - " : pid); - sb.append(" "); - sb.append(String.format("[%06d]", stepSingle.index)); - sb.append(" "); - sb.append(DateUtil.getLogTime(tm)); - sb.append(" "); - sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); - sb.append(" "); - if (prev_cpu == -1) { - sb.append(String.format("%6s", FormatUtil.print(0, "#,##0"))); - } else { - sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); - } - - sb.append(" "); - int lineHead = sb.length() - p1; - - int space = 0; - if (indent.containsKey(stepSingle.parent)) { - space = indent.get(stepSingle.parent) + 1; - } - indent.put(stepSingle.index, space); - while (space > 0) { - sb.append(" "); - space--; - } - - switch (stepSingle.getStepType()) { - case StepEnum.METHOD: - toString(sb, (MethodStep) stepSingle); - break; - case StepEnum.METHOD2: - toString(sb, (MethodStep) stepSingle); - MethodStep2 m2 = (MethodStep2) stepSingle; - if (m2.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(m2.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.SQL: - case StepEnum.SQL2: - SqlStep sql = (SqlStep) stepSingle; - slen = sb.length(); - toString(sb, sql, serverId, lineHead); - sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); - if (sql.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(sql.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.MESSAGE: - slen = sb.length(); - toString(sb, (MessageStep) stepSingle); - sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); - break; - case StepEnum.HASHED_MESSAGE: - slen = sb.length(); - toString(sb, (HashedMessageStep) stepSingle); - sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); - break; - case StepEnum.APICALL: - ApiCallStep apicall = (ApiCallStep) stepSingle; - slen = sb.length(); - toString(sb, apicall); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - if (apicall.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(apicall.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.THREAD_SUBMIT: - ThreadSubmitStep threadSubmit = (ThreadSubmitStep) stepSingle; - slen = sb.length(); - toString(sb, threadSubmit); - sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); - if (threadSubmit.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(threadSubmit.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - case StepEnum.SOCKET: - SocketStep socket = (SocketStep) stepSingle; - slen = sb.length(); - toString(sb, socket); - sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); - if (socket.error != 0) { - slen = sb.length(); - sb.append("\n").append(TextProxy.error.getText(socket.error)); - sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); - } - break; - } - sb.append("\n"); - prev_cpu = cpu; - prev_tm = tm; - } - - sb.append("------------------------------------------------------------------------------------------\n"); - - text.setText(sb.toString()); - text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); - } - - public static void toString(StringBuffer sb, ApiCallStep p) { - String m = TextProxy.apicall.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append("call: ").append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - if (p.txid != 0) { - sb.append(" <" + Hexa32.toString32(p.txid) + ">"); - } - } - public static void toString(StringBuffer sb, HashedMessageStep p) { - String m = TextProxy.hashMessage.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append(m).append(" #").append(FormatUtil.print(p.value, "#,##0")).append(" ").append(FormatUtil.print(p.time, "#,##0")).append(" ms"); - } - - public static void toString(StringBuffer sb, ThreadSubmitStep p) { - String m = TextProxy.apicall.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append("thread: ").append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - if (p.txid != 0) { - sb.append(" <" + Hexa32.toString32(p.txid) + ">"); - } - } - - public static void toString(StringBuffer sb, SocketStep p) { - String ip = IPUtil.toString(p.ipaddr); - sb.append("socket: ").append(ip == null ? "unknown" : ip).append(":").append(p.port + " ") - .append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - } - - public static void toString(StringBuffer sb, ApiCallSum p) { - String m = TextProxy.apicall.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append("call: ").append(m).append(" "); - sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); - sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); - if (p.error > 0) { - sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); - } - } - - public static void toString(StringBuffer sb, SocketSum p) { - String ip = IPUtil.toString(p.ipaddr); - sb.append("socket: ").append(ip == null ? "unknown" : ip).append(":").append(p.port + " "); - sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); - sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - if (p.error > 0) { - sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); - } - } - - public static void toString(StringBuffer sb, SqlStep p, int serverId, int lineHead) { - if (p instanceof SqlStep2) { - sb.append(SqlXType.toString(((SqlStep2) p).xtype)); - } - String m = TextProxy.sql.getText(p.hash); - m = spacing(m, lineHead); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append(m); - if (StringUtil.isEmpty(p.param) == false) { - sb.append("\n").append(StringUtil.leftPad("", lineHead)); - Server server = ServerManager.getInstance().getServer(serverId); - boolean showParam = true; - if(server != null){ - showParam = server.isAllowAction(GroupPolicyConstants.ALLOW_SQLPARAMETER); - } - sb.append("[").append(showParam ? p.param : "******").append("]"); - } - sb.append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - } - - public static String spacing(String m, int lineHead) { - if (m == null) - return m; - String dummy = StringUtil.leftPad("", lineHead); - StringBuffer sb = new StringBuffer(); - try { - BufferedReader sr = new BufferedReader(new StringReader(m)); - String s = null; - while ((s = sr.readLine()) != null) { - s = StringUtil.trim(s); - if (s.length() > 0) { - if (sb.length() > 0) { - sb.append("\n").append(dummy); - } - sb.append(s); - } - - } - } catch (Exception e) { - } - return sb.toString(); - } - - public static void toString(StringBuffer sb, SqlSum p, int serverId) { - String m = TextProxy.sql.getText(p.hash); - if (m == null) - m = Hexa32.toString32(p.hash); - sb.append(m); - if (StringUtil.isEmpty(p.param) == false) { - Server server = ServerManager.getInstance().getServer(serverId); - boolean showParam = server.isAllowAction(GroupPolicyConstants.ALLOW_SQLPARAMETER); - sb.append(" [").append(showParam ? p.param : "******").append("]"); - } - sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); - sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); - if (p.error > 0) { - sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); - } - } - - public static void toString(StringBuffer sb, MessageStep p) { - sb.append(p.message); - } - - public static void toString(StringBuffer sb, StepControl p) { - sb.append(p.message); - } - - public static void toString(StringBuffer sb, MethodStep p) { - String m = TextProxy.method.getText(p.hash); - if (m == null) { - m = Hexa32.toString32(p.hash); - } - sb.append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); - } - - public static StyleRange style(int start, int length, Color c, int f) { - StyleRange t = new StyleRange(); - t.start = start; - t.length = length; - t.foreground = c; - t.fontStyle = f; - return t; - } - - public static StyleRange style(int start, int length, Color c, int f, Color backc) { - StyleRange t = new StyleRange(); - t.start = start; - t.length = length; - t.foreground = c; - t.fontStyle = f; - t.background = backc; - return t; - } - - public static StyleRange underlineStyle(int start, int length, Color c, int fontStyle, int underlineStyle) { - StyleRange t = new StyleRange(); - t.start = start; - t.length = length; - t.foreground = c; - t.fontStyle = fontStyle; - t.underline = true; - t.underlineStyle = underlineStyle; - return t; - } + if (xperf.p.sqlCount > 0) { + sb.append("\n► sqlCount=" + xperf.p.sqlCount + ", "); + sb.append("sqlTime=" + FormatUtil.print(xperf.p.sqlTime, "#,##0") + " ms"); + } + if (xperf.p.apicallCount > 0) { + sb.append("\n► ApiCallCount=" + xperf.p.apicallCount + ", "); + sb.append("ApiCallTime=" + FormatUtil.print(xperf.p.apicallTime, "#,##0") + " ms"); + } + + String t = TextProxy.userAgent.getLoadText(date, xperf.p.userAgent, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► userAgent=" + t); + } + + t = TextProxy.referer.getLoadText(date, xperf.p.referer, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► referer=" + t); + } + + t = TextProxy.group.getLoadText(date, xperf.p.group, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► group=" + t); + } + if (StringUtil.isNotEmpty(xperf.p.countryCode)) { + sb.append("\n► country=" + CountryCode.getCountryName(xperf.p.countryCode)); + } + t = TextProxy.city.getLoadText(date, xperf.p.city, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► city=" + t); + } + t = TextProxy.web.getLoadText(date, xperf.p.webHash, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► webName=" + t).append(" webTime=" + xperf.p.webTime + " ms"); + } + t = TextProxy.login.getLoadText(date, xperf.p.login, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► login=" + t); + } + t = TextProxy.desc.getLoadText(date, xperf.p.desc, serverId); + if (StringUtil.isNotEmpty(t)) { + sb.append("\n► desc=" + t); + } + sb.append("\n"); + + sb.append("------------------------------------------------------------------------------------------\n"); + sb.append(" p# # TIME T-GAP CPU CONTENTS\n"); + sb.append("------------------------------------------------------------------------------------------\n"); + if (profiles.length == 0) { + sb.append("\n ( No xlog profile collected ) "); + text.setText(sb.toString()); + // for (int i = 0; i < sr.size(); i++) { + text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); + // } + return; + } + + long stime = xperf.p.endTime - xperf.p.elapsed; + long prev_tm = stime; + long prev_cpu = 0; + + sb.append(" "); + sb.append(" "); + sb.append("[******]"); + sb.append(" "); + sb.append(DateUtil.getLogTime(stime)); + sb.append(" "); + sb.append(String.format("%6s", "0")); + sb.append(" "); + sb.append(String.format("%6s", "0")); + sb.append(" start transaction \n"); + // sr.add(style(slen, sb.length() - slen, dblue, SWT.NORMAL)); + + long tm = xperf.p.endTime; + long cpu = xperf.p.cpu; + int sumCnt = 1; + HashMap indent = new HashMap(); + for (int i = 0; i < profiles.length; i++) { + + if (truncated) + break; + + if (profiles[i] instanceof StepSummary) { + sb.append(" ").append(" "); + sb.append(String.format("[%06d]", sumCnt++)); + sb.append(" "); + + StepSummary sum = (StepSummary) profiles[i]; + switch (sum.getStepType()) { + case StepEnum.METHOD_SUM: + XLogProfileView.isSummary = true; + + MethodSum p = (MethodSum) sum; + slen = sb.length(); + + String m = TextProxy.method.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append(m).append(" "); + + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + + sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); + sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); + + sb.append("\n"); + break; + case StepEnum.SQL_SUM: + XLogProfileView.isSummary = true; + SqlSum sql = (SqlSum) sum; + slen = sb.length(); + toString(sb, sql, serverId); + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.APICALL_SUM: + XLogProfileView.isSummary = true; + ApiCallSum apicall = (ApiCallSum) sum; + slen = sb.length(); + toString(sb, apicall); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.SOCKET_SUM: + XLogProfileView.isSummary = true; + SocketSum socketSum = (SocketSum) sum; + slen = sb.length(); + toString(sb, socketSum); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.CONTROL: + + sb.delete(sb.length() - 9, sb.length()); + + sb.append("[******]"); + sb.append(" "); + sb.append(DateUtil.getLogTime(tm)); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); + sb.append(" "); + slen = sb.length(); + toString(sb, (StepControl) sum); + sr.add(style(slen, sb.length() - slen, dred, SWT.NORMAL)); + sb.append("\n"); + + truncated = true; + + break; + } + continue; + } + + StepSingle stepSingle = (StepSingle) profiles[i]; + tm = stepSingle.start_time + stime; + cpu = stepSingle.start_cpu; + + // sr.add(style(sb.length(), 6, blue, SWT.NORMAL)); + int p1 = sb.length(); + String pid = String.format("[%06d]", stepSingle.parent); + sb.append((stepSingle.parent == -1) ? " - " : pid); + sb.append(" "); + sb.append(String.format("[%06d]", stepSingle.index)); + sb.append(" "); + sb.append(DateUtil.getLogTime(tm)); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); + sb.append(" "); + int lineHead = sb.length() - p1; + + int space = 0; + if (indent.containsKey(stepSingle.parent)) { + space = indent.get(stepSingle.parent) + spaceCnt; + } + indent.put(stepSingle.index, space); + lineHead += space; + while (space > 0) { + sb.append(" "); + space--; + } + + switch (stepSingle.getStepType()) { + case StepEnum.METHOD: + toString(sb, (MethodStep) stepSingle); + break; + case StepEnum.METHOD2: + toString(sb, (MethodStep) stepSingle); + MethodStep2 m2 = (MethodStep2) stepSingle; + if (m2.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(m2.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.SQL: + case StepEnum.SQL2: + case StepEnum.SQL3: + SqlStep sql = (SqlStep) stepSingle; + slen = sb.length(); + toString(sb, sql, serverId, lineHead); + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + if (sql.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(sql.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.MESSAGE: + slen = sb.length(); + toString(sb, (MessageStep) stepSingle); + sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); + break; + case StepEnum.HASHED_MESSAGE: + slen = sb.length(); + toString(sb, (HashedMessageStep) stepSingle); + sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); + break; + case StepEnum.APICALL: + ApiCallStep apicall = (ApiCallStep) stepSingle; + slen = sb.length(); + toString(sb, apicall); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + if (apicall.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(apicall.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.THREAD_SUBMIT: + ThreadSubmitStep threadSubmit = (ThreadSubmitStep) stepSingle; + slen = sb.length(); + toString(sb, threadSubmit); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + if (threadSubmit.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(threadSubmit.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.SOCKET: + SocketStep socket = (SocketStep) stepSingle; + slen = sb.length(); + toString(sb, socket); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + if (socket.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(socket.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + } + sb.append("\n"); + prev_cpu = cpu; + prev_tm = tm; + } + + if (!truncated) { + + tm = xperf.p.endTime; + cpu = xperf.p.cpu; + sb.append(" "); + sb.append(" "); + sb.append("[******]"); + sb.append(" "); + sb.append(DateUtil.getLogTime(tm)); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); + sb.append(" end of transaction \n"); + + } + sb.append("------------------------------------------------------------------------------------------\n"); + + text.setText(sb.toString()); + text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); + + } + + public static void buildThreadProfile(XLogData data, StyledText text, Step[] profiles) { + if (profiles == null) { + profiles = new Step[0]; + } + int serverId = data.serverId; + String date = DateUtil.yyyymmdd(data.p.endTime); + profiles = SortUtil.sort(profiles); + XLogUtil.loadStepText(serverId, date, profiles); + Color blue = text.getDisplay().getSystemColor(SWT.COLOR_BLUE); + Color dmagenta = text.getDisplay().getSystemColor(SWT.COLOR_DARK_MAGENTA); + Color red = text.getDisplay().getSystemColor(SWT.COLOR_RED); + Color dred = text.getDisplay().getSystemColor(SWT.COLOR_DARK_RED); + Color dgreen = text.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN); + java.util.List sr = new ArrayList(); + int slen = 0; + final StringBuffer sb = new StringBuffer(); + + sb.append("------------------------------------------------------------------------------------------\n"); + sb.append(" p# # TIME T-GAP CPU CONTENTS\n"); + sb.append("------------------------------------------------------------------------------------------\n"); + if (profiles.length == 0) { + sb.append("\n ( No xlog profile collected ) "); + text.setText(sb.toString()); + text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); + return; + } + + long stime = data.p.endTime - data.p.elapsed; + long prev_tm = stime; + long tm = stime; + int prev_cpu = -1; + int cpu = 0; + int sumCnt = 1; + HashMap indent = new HashMap(); + for (int i = 0; i < profiles.length; i++) { + if (profiles[i] instanceof StepSummary) { + sb.append(" ").append(" "); + sb.append(String.format("[%06d]", sumCnt++)); + sb.append(" "); + + StepSummary sum = (StepSummary) profiles[i]; + switch (sum.getStepType()) { + case StepEnum.METHOD_SUM: + MethodSum p = (MethodSum) sum; + slen = sb.length(); + String m = TextProxy.method.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append(m).append(" "); + + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + + sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); + sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); + + sb.append("\n"); + break; + case StepEnum.SQL_SUM: + SqlSum sql = (SqlSum) sum; + slen = sb.length(); + toString(sb, sql, serverId); + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.APICALL_SUM: + ApiCallSum apicall = (ApiCallSum) sum; + slen = sb.length(); + toString(sb, apicall); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.SOCKET_SUM: + SocketSum socketSum = (SocketSum) sum; + slen = sb.length(); + toString(sb, socketSum); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + sb.append("\n"); + break; + case StepEnum.CONTROL: + sb.delete(sb.length() - 9, sb.length()); + sb.append("[******]"); + sb.append(" "); + sb.append(DateUtil.getLogTime(data.p.endTime)); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(data.p.elapsed, "#,##0"))); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(data.p.cpu, "#,##0"))); + sb.append(" "); + slen = sb.length(); + toString(sb, (StepControl) sum); + sr.add(style(slen, sb.length() - slen, dred, SWT.NORMAL)); + sb.append("\n"); + break; + } + continue; + } + + StepSingle stepSingle = (StepSingle) profiles[i]; + tm = stime + stepSingle.start_time; + cpu = stepSingle.start_cpu; + + // sr.add(style(sb.length(), 6, blue, SWT.NORMAL)); + int p1 = sb.length(); + String pid = String.format("[%06d]", stepSingle.parent); + sb.append((stepSingle.parent == -1) ? " - " : pid); + sb.append(" "); + sb.append(String.format("[%06d]", stepSingle.index)); + sb.append(" "); + sb.append(DateUtil.getLogTime(tm)); + sb.append(" "); + sb.append(String.format("%6s", FormatUtil.print(tm - prev_tm, "#,##0"))); + sb.append(" "); + if (prev_cpu == -1) { + sb.append(String.format("%6s", FormatUtil.print(0, "#,##0"))); + } else { + sb.append(String.format("%6s", FormatUtil.print(cpu - prev_cpu, "#,##0"))); + } + + sb.append(" "); + int lineHead = sb.length() - p1; + + int space = 0; + if (indent.containsKey(stepSingle.parent)) { + space = indent.get(stepSingle.parent) + 1; + } + indent.put(stepSingle.index, space); + lineHead += space; + while (space > 0) { + sb.append(" "); + space--; + } + + switch (stepSingle.getStepType()) { + case StepEnum.METHOD: + toString(sb, (MethodStep) stepSingle); + break; + case StepEnum.METHOD2: + toString(sb, (MethodStep) stepSingle); + MethodStep2 m2 = (MethodStep2) stepSingle; + if (m2.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(m2.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.SQL: + case StepEnum.SQL2: + case StepEnum.SQL3: + SqlStep sql = (SqlStep) stepSingle; + slen = sb.length(); + toString(sb, sql, serverId, lineHead); + sr.add(style(slen, sb.length() - slen, blue, SWT.NORMAL)); + if (sql.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(sql.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.MESSAGE: + slen = sb.length(); + toString(sb, (MessageStep) stepSingle); + sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); + break; + case StepEnum.HASHED_MESSAGE: + slen = sb.length(); + toString(sb, (HashedMessageStep) stepSingle); + sr.add(style(slen, sb.length() - slen, dgreen, SWT.NORMAL)); + break; + case StepEnum.APICALL: + ApiCallStep apicall = (ApiCallStep) stepSingle; + slen = sb.length(); + toString(sb, apicall); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + if (apicall.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(apicall.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.THREAD_SUBMIT: + ThreadSubmitStep threadSubmit = (ThreadSubmitStep) stepSingle; + slen = sb.length(); + toString(sb, threadSubmit); + sr.add(underlineStyle(slen, sb.length() - slen, dmagenta, SWT.NORMAL, SWT.UNDERLINE_LINK)); + if (threadSubmit.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(threadSubmit.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + case StepEnum.SOCKET: + SocketStep socket = (SocketStep) stepSingle; + slen = sb.length(); + toString(sb, socket); + sr.add(style(slen, sb.length() - slen, dmagenta, SWT.NORMAL)); + if (socket.error != 0) { + slen = sb.length(); + sb.append("\n").append(TextProxy.error.getText(socket.error)); + sr.add(style(slen, sb.length() - slen, red, SWT.NORMAL)); + } + break; + } + sb.append("\n"); + prev_cpu = cpu; + prev_tm = tm; + } + + sb.append("------------------------------------------------------------------------------------------\n"); + + text.setText(sb.toString()); + text.setStyleRanges(sr.toArray(new StyleRange[sr.size()])); + } + + public static void toString(StringBuffer sb, ApiCallStep p) { + String m = TextProxy.apicall.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append("call: ").append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + if (p.txid != 0) { + sb.append(" <" + Hexa32.toString32(p.txid) + ">"); + } + } + + public static void toString(StringBuffer sb, HashedMessageStep p) { + String m = TextProxy.hashMessage.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append(m).append(" #").append(FormatUtil.print(p.value, "#,##0")).append(" ").append(FormatUtil.print(p.time, "#,##0")).append(" ms"); + } + + public static void toString(StringBuffer sb, ThreadSubmitStep p) { + String m = TextProxy.apicall.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append("thread: ").append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + if (p.txid != 0) { + sb.append(" <" + Hexa32.toString32(p.txid) + ">"); + } + } + + public static void toString(StringBuffer sb, SocketStep p) { + String ip = IPUtil.toString(p.ipaddr); + sb.append("socket: ").append(ip == null ? "unknown" : ip).append(":").append(p.port + " ") + .append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + } + + public static void toString(StringBuffer sb, ApiCallSum p) { + String m = TextProxy.apicall.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append("call: ").append(m).append(" "); + sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); + sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); + if (p.error > 0) { + sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); + } + } + + public static void toString(StringBuffer sb, SocketSum p) { + String ip = IPUtil.toString(p.ipaddr); + sb.append("socket: ").append(ip == null ? "unknown" : ip).append(":").append(p.port + " "); + sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); + sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + if (p.error > 0) { + sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); + } + } + + public static void toString(StringBuffer sb, SqlStep p, int serverId, int lineHead) { + if (p instanceof SqlStep2) { + sb.append(SqlXType.toString(((SqlStep2) p).xtype)); + } + String m = TextProxy.sql.getText(p.hash); + m = spacing(m, lineHead); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append(m); + if (StringUtil.isEmpty(p.param) == false) { + sb.append("\n").append(StringUtil.leftPad("", lineHead)); + Server server = ServerManager.getInstance().getServer(serverId); + boolean showParam = true; + if (server != null) { + showParam = server.isAllowAction(GroupPolicyConstants.ALLOW_SQLPARAMETER); + } + sb.append("[").append(showParam ? p.param : "******").append("]"); + } + sb.append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + if (p instanceof SqlStep3) { + int updatedCount = ((SqlStep3) p).updated; + if (updatedCount > -1) { + sb.append("\n"); + sb.append(StringUtil.leftPad("", lineHead)); + sb.append(""); + } else if (updatedCount == -2) { + sb.append("\n"); + sb.append(StringUtil.leftPad("", lineHead)); + sb.append(""); + } +// switch (SqlXType.getMethodType(((SqlStep3) p).xtype)) { +// case SqlXType.METHOD_UPDATE: +// sb.append("\n"); +// sb.append(StringUtil.leftPad("", lineHead)); +// sb.append(""); +// break; +// case SqlXType.METHOD_EXECUTE: +// sb.append("\n"); +// sb.append(StringUtil.leftPad("", lineHead)); +// sb.append(""); +// break; +// } +// } + } + } + + public static String spacing(String m, int lineHead) { + if (m == null) + return m; + String dummy = StringUtil.leftPad("", lineHead); + StringBuffer sb = new StringBuffer(); + try { + BufferedReader sr = new BufferedReader(new StringReader(m)); + String s = null; + while ((s = sr.readLine()) != null) { + s = StringUtil.trim(s); + if (s.length() > 0) { + if (sb.length() > 0) { + sb.append("\n").append(dummy); + } + sb.append(s); + } + + } + } catch (Exception e) { + } + return sb.toString(); + } + + public static void toString(StringBuffer sb, SqlSum p, int serverId) { + String m = TextProxy.sql.getText(p.hash); + if (m == null) + m = Hexa32.toString32(p.hash); + sb.append(m); + if (StringUtil.isEmpty(p.param) == false) { + Server server = ServerManager.getInstance().getServer(serverId); + boolean showParam = server.isAllowAction(GroupPolicyConstants.ALLOW_SQLPARAMETER); + sb.append(" [").append(showParam ? p.param : "******").append("]"); + } + sb.append(" count=").append(FormatUtil.print(p.count, "#,##0")); + sb.append(" time=").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + sb.append(" cpu=").append(FormatUtil.print(p.cputime, "#,##0")); + if (p.error > 0) { + sb.append(" error=").append(FormatUtil.print(p.error, "#,##0")); + } + } + + public static void toString(StringBuffer sb, MessageStep p) { + sb.append(p.message); + } + + public static void toString(StringBuffer sb, StepControl p) { + sb.append(p.message); + } + + public static void toString(StringBuffer sb, MethodStep p) { + String m = TextProxy.method.getText(p.hash); + if (m == null) { + m = Hexa32.toString32(p.hash); + } + sb.append(m).append(" ").append(FormatUtil.print(p.elapsed, "#,##0")).append(" ms"); + } + + public static StyleRange style(int start, int length, Color c, int f) { + StyleRange t = new StyleRange(); + t.start = start; + t.length = length; + t.foreground = c; + t.fontStyle = f; + return t; + } + + public static StyleRange style(int start, int length, Color c, int f, Color backc) { + StyleRange t = new StyleRange(); + t.start = start; + t.length = length; + t.foreground = c; + t.fontStyle = f; + t.background = backc; + return t; + } + + public static StyleRange underlineStyle(int start, int length, Color c, int fontStyle, int underlineStyle) { + StyleRange t = new StyleRange(); + t.start = start; + t.length = length; + t.foreground = c; + t.fontStyle = fontStyle; + t.underline = true; + t.underlineStyle = underlineStyle; + return t; + } } diff --git a/scouter.client/src/scouter/client/xlog/ProfileTextFull.java b/scouter.client/src/scouter/client/xlog/ProfileTextFull.java index 55b042cdd..125623d38 100644 --- a/scouter.client/src/scouter/client/xlog/ProfileTextFull.java +++ b/scouter.client/src/scouter/client/xlog/ProfileTextFull.java @@ -300,6 +300,7 @@ public static void buildProfile(final String date, StyledText text, XLogPack pac break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: SqlStep sql = (SqlStep) stepSingle; slen = sb.length(); ProfileText.toString(sb, sql, serverId, lineHead); diff --git a/scouter.client/src/scouter/client/xlog/XLogUtil.java b/scouter.client/src/scouter/client/xlog/XLogUtil.java index 0f889a5bb..a035d802c 100644 --- a/scouter.client/src/scouter/client/xlog/XLogUtil.java +++ b/scouter.client/src/scouter/client/xlog/XLogUtil.java @@ -60,6 +60,7 @@ public static void loadStepText(int serverId, String yyyymmdd, Step[] p) { switch (p[i].getStepType()) { case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: if (TextProxy.sql.getText(((SqlStep) p[i]).hash) == null) { sqlSet.add(((SqlStep) p[i]).hash); } @@ -129,6 +130,7 @@ public static int getStepElaspedTime(Step p) { switch (p.getStepType()) { case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: SqlStep ss = (SqlStep) p; return ss.elapsed; case StepEnum.SOCKET: @@ -162,6 +164,8 @@ public static String toStringStepSingleType(StepSingle step) { return "SQL"; case StepEnum.SQL2: return "SQL2"; + case StepEnum.SQL3: + return "SQL3"; case StepEnum.SOCKET: return "SCK"; case StepEnum.APICALL: @@ -396,6 +400,7 @@ public static String xLogToHtml(XLogPack pack, Step[] profiles, final int server break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: SqlStep sql = (SqlStep) stepSingle; toString(sb, sql, serverId); if (sql.error != 0) { diff --git a/scouter.client/src/scouter/client/xlog/dialog/XLogFilterDialog.java b/scouter.client/src/scouter/client/xlog/dialog/XLogFilterDialog.java index 81787e434..8f4d11b7d 100644 --- a/scouter.client/src/scouter/client/xlog/dialog/XLogFilterDialog.java +++ b/scouter.client/src/scouter/client/xlog/dialog/XLogFilterDialog.java @@ -92,6 +92,7 @@ public void modifyText(ModifyEvent arg0) { label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, false)); serviceTxt = new Text(filterGrp, SWT.BORDER | SWT.SINGLE); serviceTxt.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + serviceTxt.setText(status.service); serviceTxt.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent arg0) { newStatus.service = serviceTxt.getText(); diff --git a/scouter.client/src/scouter/client/xlog/dialog/XlogSummarySQLDialog.java b/scouter.client/src/scouter/client/xlog/dialog/XlogSummarySQLDialog.java index 8a0e81833..2520e689f 100644 --- a/scouter.client/src/scouter/client/xlog/dialog/XlogSummarySQLDialog.java +++ b/scouter.client/src/scouter/client/xlog/dialog/XlogSummarySQLDialog.java @@ -202,6 +202,7 @@ protected void processSqlData(){ switch(stepSingle.getStepType()){ case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: sql = (SqlStep)stepSingle; sqlSumData = sqlMap.get(sql.hash); diff --git a/scouter.client/src/scouter/client/xlog/views/XLogDependencyView.java b/scouter.client/src/scouter/client/xlog/views/XLogDependencyView.java index 30b17411a..f8cad6f8f 100644 --- a/scouter.client/src/scouter/client/xlog/views/XLogDependencyView.java +++ b/scouter.client/src/scouter/client/xlog/views/XLogDependencyView.java @@ -337,6 +337,7 @@ private void stepToElement(final DependencyElement serviceElement, Step step, fi break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: SqlStep sqlstep = (SqlStep) step; DependencyElement sqlElement = new DependencyElement(ElementType.SQL, sqlstep.hash); sqlElement.elapsed = sqlstep.elapsed; diff --git a/scouter.client/src/scouter/client/xlog/views/XLogFullProfileView.java b/scouter.client/src/scouter/client/xlog/views/XLogFullProfileView.java index 6fe224f68..7364954a8 100644 --- a/scouter.client/src/scouter/client/xlog/views/XLogFullProfileView.java +++ b/scouter.client/src/scouter/client/xlog/views/XLogFullProfileView.java @@ -549,6 +549,7 @@ public void run() { break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: SqlStep sql = (SqlStep) step; m = TextProxy.sql.getText(sql.hash); @@ -685,6 +686,7 @@ protected void getSummary() { break; case StepEnum.SQL: case StepEnum.SQL2: + case StepEnum.SQL3: putSummary(summary, (SqlStep)step); break; case StepEnum.MESSAGE: diff --git a/scouter.common/src/scouter/lang/pack/AlertPack.java b/scouter.common/src/scouter/lang/pack/AlertPack.java index 57dab5afc..be83d6940 100644 --- a/scouter.common/src/scouter/lang/pack/AlertPack.java +++ b/scouter.common/src/scouter/lang/pack/AlertPack.java @@ -1,38 +1,61 @@ -/* - * 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. - */ - +/* + * 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.lang.pack; -import java.io.IOException; - -import scouter.io.DataInputX; -import scouter.io.DataOutputX; -import scouter.lang.value.MapValue; -import scouter.util.DateUtil; -import scouter.util.Hexa32; +import scouter.io.DataInputX; +import scouter.io.DataOutputX; +import scouter.lang.value.MapValue; +import scouter.util.DateUtil; +import scouter.util.Hexa32; +import java.io.IOException; +/** + * Object that contains one alert information + */ public class AlertPack implements Pack { + /** + * Alert time + */ public long time; + /** + * Object type + */ public String objType; + /** + * Object ID + */ public int objHash; + /** + * Alert level. 0:Info, 1:Warn, 2:Error, 3:Fatal + */ public byte level; + /** + * Alert title + */ public String title; + /** + * Alert message + */ public String message; + /** + * More info + */ public MapValue tags = new MapValue(); public String toString() { diff --git a/scouter.common/src/scouter/lang/pack/ObjectPack.java b/scouter.common/src/scouter/lang/pack/ObjectPack.java index c2b8a4c37..1ee0c3364 100644 --- a/scouter.common/src/scouter/lang/pack/ObjectPack.java +++ b/scouter.common/src/scouter/lang/pack/ObjectPack.java @@ -25,17 +25,42 @@ import scouter.lang.value.MapValue; import scouter.util.Hexa32; +/** + * Object that contains one agent(called object) information + */ public class ObjectPack implements Pack { + /** + * Object type + */ public String objType; + /** + * Object ID + */ public int objHash; + /** + * Object full name + */ public String objName; + /** + * IP address + */ public String address; + /** + * Version + */ public String version; - + /** + * Whether alive + */ public boolean alive = true; + /** + * Last wake up time + */ public long wakeup; - + /** + * More info + */ public MapValue tags = new MapValue(); transient public int updated; diff --git a/scouter.common/src/scouter/lang/pack/PerfCounterPack.java b/scouter.common/src/scouter/lang/pack/PerfCounterPack.java index 0f657593d..a7f63fab9 100644 --- a/scouter.common/src/scouter/lang/pack/PerfCounterPack.java +++ b/scouter.common/src/scouter/lang/pack/PerfCounterPack.java @@ -27,11 +27,26 @@ import scouter.lang.value.Value; import scouter.util.DateUtil; +/** + * Object that contains multiple counter information + */ public class PerfCounterPack implements Pack { + /** + * Counter time + */ public long time; + /** + * Object name + */ public String objName; + /** + * Time type. 1:Real-time, 2:OneMin, 3:FiveMin, 4:TenMin, 5:Hour, 6:Day + */ public byte timetype; + /** + * Multiple counter data. Key is counter name. ref.)scouter.lang.value.MapValue + */ public MapValue data = new MapValue(); public String toString() { diff --git a/scouter.common/src/scouter/lang/pack/SummaryPack.java b/scouter.common/src/scouter/lang/pack/SummaryPack.java index 50447f9b0..2c2b1c834 100644 --- a/scouter.common/src/scouter/lang/pack/SummaryPack.java +++ b/scouter.common/src/scouter/lang/pack/SummaryPack.java @@ -28,13 +28,31 @@ import scouter.util.DateUtil; import scouter.util.Hexa32; +/** + * Object that contains multiple summary information + */ public class SummaryPack implements Pack { + /** + * Summary time + */ public long time; + /** + * Object ID + */ public int objHash; + /** + * Object type + */ public String objType; + /** + * Summary Type. 1:App, 2:SQL, 3:Alert, 4:Ip, 5:ApiCall, 8:User-Agent.... + */ public byte stype; - public MapValue table = new MapValue(); + /** + * Summary data. ref.)scouter.lang.value.MapValue + */ + public MapValue table = new MapValue(); public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/scouter.common/src/scouter/lang/pack/XLogPack.java b/scouter.common/src/scouter/lang/pack/XLogPack.java index e42d42b6b..52d33dc21 100644 --- a/scouter.common/src/scouter/lang/pack/XLogPack.java +++ b/scouter.common/src/scouter/lang/pack/XLogPack.java @@ -24,40 +24,119 @@ import scouter.util.DateUtil; import scouter.util.Hexa32; +/** + * Object that contains one transaction information + */ public class XLogPack implements Pack { + /** + * Transaction endtime + */ public long endTime; + /** + * Object ID + */ public int objHash; + /** + * Transaction name Hash + */ public int service; + /** + * Transaction ID + */ public long txid; + /** + * Caller ID + */ public long caller; + /** + * Global transaction ID + */ public long gxid; + /** + * Elapsed time(ms) + */ public int elapsed; + /** + * Error hash + */ public int error; - + /** + * Cpu time(ms) + */ public int cpu; + /** + * SQL count + */ public int sqlCount; + /** + * SQL time(ms) + */ public int sqlTime; + /** + * Remote ip address + */ public byte[] ipaddr; + /** + * Allocated memory(byte) + */ public int bytes; + /** + * Http status + */ + @Deprecated public int status; + /** + * User ID + */ public long userid; + /** + * User-agent hash + */ public int userAgent; + /** + * Referer hash + */ public int referer; + /** + * Group hash + */ public int group; + /** + * ApiCall count + */ public int apicallCount; + /** + * ApiCall time(ms) + */ public int apicallTime; - - // TOP100 + /** + * Country code + */ public String countryCode; // CountryCode.getCountryName(countryCode); + /** + * City hash + */ public int city; + /** + * XLog type. WebService:0, AppService:1, BackgroundThread:2 + */ public byte xType; // see XLogTypes - + /** + * Login hash + */ public int login; + /** + * Description hash + */ public int desc; - - // WEB TIME + /** + * WebServer object ID + */ public int webHash; // WEB서버의 ObjectHash + /** + * WebServer -> WAS time(ms) + */ public int webTime; // WEB서버 --> WAS 시작 시점까지의 시간 public String toString() { diff --git a/scouter.common/src/scouter/lang/pack/XLogProfilePack.java b/scouter.common/src/scouter/lang/pack/XLogProfilePack.java index 49b953591..95ea5955a 100644 --- a/scouter.common/src/scouter/lang/pack/XLogProfilePack.java +++ b/scouter.common/src/scouter/lang/pack/XLogProfilePack.java @@ -1,36 +1,57 @@ -/* - * 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. - */ - +/* + * 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.lang.pack; -import java.io.IOException; - -import scouter.io.DataInputX; -import scouter.io.DataOutputX; -import scouter.util.DateUtil; -import scouter.util.Hexa32; +import java.io.IOException; + +import scouter.io.DataInputX; +import scouter.io.DataOutputX; +import scouter.util.DateUtil; +import scouter.util.Hexa32; +/** + * Object that contains a part of full profile + */ public class XLogProfilePack implements Pack { + /** + * Profile time + */ public long time; - public int objHash; - public int service; - public long txid; - public int elapsed; + /** + * Object ID + */ + public int objHash; + /** + * Related transaction name hash + */ + public int service; + /** + * Related transaction ID + */ + public long txid; + /** + * Elapsed time until this step(ms) + */ + public int elapsed; + /** + * Byte array of profile steps + */ public byte[] profile; public byte getPackType() { @@ -49,15 +70,15 @@ public String toString() { public void write(DataOutputX dout) throws IOException { dout.writeDecimal(time); - dout.writeDecimal(objHash); - dout.writeDecimal(service); + dout.writeDecimal(objHash); + dout.writeDecimal(service); dout.writeLong(txid); dout.writeBlob(profile); } public Pack read(DataInputX din) throws IOException { this.time = din.readDecimal(); - this.objHash = (int) din.readDecimal(); + this.objHash = (int) din.readDecimal(); this.service= (int) din.readDecimal(); this.txid = din.readLong(); this.profile = din.readBlob(); diff --git a/scouter.common/src/scouter/lang/step/SqlStep3.java b/scouter.common/src/scouter/lang/step/SqlStep3.java new file mode 100644 index 000000000..e2dd045cf --- /dev/null +++ b/scouter.common/src/scouter/lang/step/SqlStep3.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015 Scouter Project. + * + * 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.lang.step; + +import scouter.io.DataInputX; +import scouter.io.DataOutputX; + +import java.io.IOException; + +/** + * SqlStep version 3 (for barward compatibility) + * the local variable 'updated' added + * @author Gun Lee (gunlee01@gmail.com) + * @author Eunsu Kim + */ +public class SqlStep3 extends SqlStep2 { + + /** + * zero & positive : affected row count + * -1 : return type of stmt.execute is a resultset. + * -2 : return type of stmt.execute is a udpate count but 'getUpdateCount' have not been triggered. + * -3 : SQL exception + */ + public int updated; + + public byte getStepType() { + return StepEnum.SQL3; + } + + public void write(DataOutputX out) throws IOException { + super.write(out); + out.writeDecimal(updated); + } + + public Step read(DataInputX in) throws IOException { + super.read(in); + this.updated = (int) in.readDecimal(); + return this; + } + +} \ No newline at end of file diff --git a/scouter.common/src/scouter/lang/step/SqlXType.java b/scouter.common/src/scouter/lang/step/SqlXType.java index 54c134498..ecc11f69e 100644 --- a/scouter.common/src/scouter/lang/step/SqlXType.java +++ b/scouter.common/src/scouter/lang/step/SqlXType.java @@ -1,19 +1,29 @@ package scouter.lang.step; public class SqlXType { - public final static byte STMT = 0; - public final static byte PREPARED = 1; - public final static byte DYNA = 2; + public final static byte STMT = 0x0; + public final static byte PREPARED = 0x1; + public final static byte DYNA = 0x2; - public static String toString(byte xtype) { - switch (xtype) { - case STMT: - return "STM> "; - case PREPARED: - return "PRE> "; - case DYNA: - return "DYN> "; - } - return "STM> "; - } + + public final static byte METHOD_KNOWN = 0x00; + public final static byte METHOD_EXECUTE = 0x10; + public final static byte METHOD_UPDATE = 0x20; + public final static byte METHOD_QUERY = 0x30; + + public static String toString(byte xtype) { + switch (xtype & 0x0f) { + case STMT: + return "STM> "; + case PREPARED: + return "PRE> "; + case DYNA: + return "DYN> "; + } + return "STM> "; + } + + public static byte getMethodType(byte xtype) { + return (byte) (xtype & 0xf0); + } } diff --git a/scouter.common/src/scouter/lang/step/StepEnum.java b/scouter.common/src/scouter/lang/step/StepEnum.java index fb50f0e1b..8c34d78d1 100644 --- a/scouter.common/src/scouter/lang/step/StepEnum.java +++ b/scouter.common/src/scouter/lang/step/StepEnum.java @@ -25,6 +25,7 @@ public class StepEnum { public final static byte METHOD2 = 10; public final static byte SQL = 2; public final static byte SQL2 = 8; + public final static byte SQL3 = 16; public final static byte MESSAGE = 3; public final static byte SOCKET = 5; public final static byte APICALL = 6; @@ -51,6 +52,8 @@ public static Step create(byte type) throws IOException { return new SqlStep(); case SQL2: return new SqlStep2(); + case SQL3: + return new SqlStep3(); case SOCKET: return new SocketStep(); case APICALL: diff --git a/scouter.common/src/scouter/util/StringSet.java b/scouter.common/src/scouter/util/StringSet.java index 673bd6b33..7034a0090 100644 --- a/scouter.common/src/scouter/util/StringSet.java +++ b/scouter.common/src/scouter/util/StringSet.java @@ -109,7 +109,8 @@ public String put(String key) { } /** - * add a key to StringSet and return hashcode of the key + * add a key to StringSet and return the key + * If this set has same string value it returns the reference already hava had. * @param key String * @return String - parameter key */ diff --git a/scouter.deploy/build.xml b/scouter.deploy/build.xml index 68686732c..ba1d4ba5b 100644 --- a/scouter.deploy/build.xml +++ b/scouter.deploy/build.xml @@ -4,7 +4,7 @@ - + diff --git a/scouter.document/main/Quick-Start.md b/scouter.document/main/Quick-Start.md index f21a262e1..ff135c53f 100644 --- a/scouter.document/main/Quick-Start.md +++ b/scouter.document/main/Quick-Start.md @@ -1,23 +1,23 @@ # Quick Start ![Englsh](https://img.shields.io/badge/language-English-red.svg) [![Korean](https://img.shields.io/badge/language-Korean-blue.svg)](Quick-Start_kr.md) -If you meet the Scouter APM for the first time, you can easily try to install and run it through this page . +If you meet Scouter APM for the first time, you can easily try to install and run it through this page. -Here is already created the sample system that can be seen to verify the functionality of the Scouter. +Here is already created sample system that can be seen to verify the functionality of Scouter. You can download, install and run it within a few minutes. This quick Start proceeds in the following order. > 1. **Download** integrated demonstration environment and a client program -> 2. decompress download file. - **Installation completed!** -> 3. Run Scouter Server(Collector) -> 4. Run Client(Viewer) -> 5. Run Host Agent - optional -> 6. Run demonstration system (Tomcat with WAR) -> 7. **Demonstration system access via a web browser** -> 8. load test by the jmeter - -## Requirement +> 2. Decompress the downloaded file. - **The installation is completed!** +> 3. Run the scouter server(Collector) +> 4. Run the scouter client(Viewer) +> 5. Run the host Agent - optional +> 6. Run the demonstration system (Tomcat with WAR) +> 7. **Browse the demonstration system via a web browser** +> 8. Do a load test by apache jmeter + +## Requirements * JDK 7+ (& environment variable JAVA_HOME to be set) * Windows / Linux / OS X @@ -38,8 +38,8 @@ Client(Viewer) | Client program to check the collected performance informatio #### (1) **Download** integrated demonstration environment and a client program - Download integrated demonstration environment - - [Download demo-env1.tar.gz](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.3/demo-env1.tar.gz) (Collector Server, Host Agent, Java Agent, Tomcat, 샘플 시스템, 설정, 기동 스크립트가 포함됨) - - Windows Case [demo-env1.zip 다운로드](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.3/demo-env1.zip) + - [Download demo-env1.tar.gz](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.3/demo-env1.tar.gz) (It includes collector server, host agent, java agent, tomcat for demo system and start scripts...) + - Windows Case : [Download demo-env1.zip](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.3/demo-env1.zip) - Download a client program - download a client for your environment. @@ -48,11 +48,11 @@ Client(Viewer) | Client program to check the collected performance informatio - [scouter.client.product-macosx.cocoa.x86_64.tar.gz](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.1/scouter.client.product-macosx.cocoa.x86_64.tar.gz) - [scouter.client.product-linux.gtk.x86_64.tar.gz](https://github.com/scouter-project/scouter-demo/releases/download/v0.0.1/scouter.client.product-linux.gtk.x86_64.tar.gz) -#### (2) decompress downloaded file. +#### (2) Decompress the downloaded file. decompress file and all installation is done. decompress demo-env1.tar.gz to any directory you want to. -#### (3) Run scouter Server(Collector) +#### (3) Run the scouter server(Collector) run the command below at the directory you decompressed file. ```bash start-scouter-server.sh @@ -62,16 +62,16 @@ Client(Viewer) | Client program to check the collected performance informatio > start-scouter-server.bat > ``` -#### (4) Run Client(Viewer) +#### (4) Run the scouter client(Viewer) decompress the client file you downloaded. - Click scouter client execution file and run. + Click the scouter client execution file and run. On the login form, you can login with 127.0.0.1:6100 for collector server and admin/admin for default id/password. ![client login](../img/client/client-login.png) -#### (5) Run Host Agent(Optional) - Run host agent for monitoring CPU, memory, IO and more of the OS. +#### (5) Run the host agent(Optional) + Run the host agent for monitoring CPU, memory, IO and more of the OS. ```bash start-scouter-host.sh ``` @@ -80,7 +80,7 @@ Client(Viewer) | Client program to check the collected performance informatio > start-scouter-host.bat > ``` -#### (6) Run demonstration system (Tomcat with WAR) +#### (6) Run the demonstration system (Tomcat with WAR) ```bash start-tomcat.sh ``` @@ -111,14 +111,14 @@ startup.bat cd /D %originDir% ``` -#### (7) Demonstration system access via a web browser +#### (7) Browse the demonstration system via a web browser Run a browser(chrome, safari...) and you can see the demo system while access http://127.0.0.1:8080/jpetstore. And also you can see the web service request you triggered on the scouter client within 2 seconds. ![jpetstore main](../img/quickstart/jpet-main.png) ![jpetstore main](../img/quickstart/client-jpet-demo1.png) -#### (8) load test by the jmeter +#### (8) Do a load test by apache jmeter You can make virtual load for verifying scouter's funtionality. run the command below, will load by jmeter in 5 minutes. If you want to stop jmeter load, please press CTRL+C. @@ -133,7 +133,7 @@ start-jmeter.sh ![jpetstore main](../img/quickstart/client-jmeter-demo1.png) -# Scouter Client Quick Guide +# Scouter client at a glance This section will describe how the monitoring application via the scouter. ## 1. How to check running thread details @@ -144,13 +144,13 @@ It display yellow color if the service is over than 3 seconds and red color 8 se ![active service](../img/quickstart/active-service.png) -## 2. Service anlaysis by the XLog profiling data +## 2. Service analysis by the XLog profiling data The XLog graph shows completed request and more detail profiles when drag the area you want to see detail. ![active service](../img/quickstart/xlog1.png) ![active service](../img/quickstart/profile1.png) -## 3. Trace chained service ( Service architecture lik SOA, MSA ... ) +## 3. Trace chained services ( Service architecture like SOA, MSA ... ) set `trace_interservice_enabled=true` on java agent configuration to enable HTTP inter-service trace. You can see the profile below when you drag XLog and select `e2e.jsp` @@ -168,14 +168,14 @@ The flag (S/U/D) by a table name means Select, Update, Delete query each. ![profile2](../img/quickstart/topology-table.png) -## 4. Advanced features of the Scouter +## 4. Advanced features of scouter Please read the detail manual pages for advanced features. function | description ------------ | -------------- -SFA (Stack Frequency Analyzer) | Thread Stack의 통계 분석을 통한 부하 코드 식별 -[Trace connection Leak](../tech/JDBC-Connection-Leak-Trace.md) | Database Connection Leak 추적 +SFA (Stack Frequency Analyzer) | the SFA gather thread stacks for a while, then analyze and make statistics for finding out unefficient codes that make system run slow. +[Trace connection Leak](../tech/JDBC-Connection-Leak-Trace.md) | Trace Database Connection Leak Add user id on a profile | profile customizing with a plugin scripting feature. method profiling | how to profile deeper - method level profiling [Trace Non-Servlet Java application](../use-case/NON-HTTP-Service-Trace.md) | how to monitoring Non-Servlet Java application like socket deamons. diff --git a/scouter.server/plugin/readme.md b/scouter.server/plugin/readme.md index ed0181519..962bc37d8 100644 --- a/scouter.server/plugin/readme.md +++ b/scouter.server/plugin/readme.md @@ -77,5 +77,24 @@ > } +### API + +#### Common API + - void log(Object c) : Logger를 통한 log + - void println(Object c) : System.out를 통한 log + - void logTo(String file, String msg) : 특정 file에 msg를 logging + +#### XLog or XLogDB Plugin API + - String objName(XLogPack p) : XLog의 Object Name을 반환 + - String objType(XLogPack p) : XLog의 Object Type을 반환 + - String service(XLogPack p) : XLog의 service를 반환 + - String error(XLogPack p) : XLog의 error를 반환 + - String userAgent(XLogPack p) : XLog의 user-agent를 반환 + - String referer(XLogPack p) : XLog의 referer를 반환 + - String login(XLogPack p) : XLog의 login 값을 반환 + - String desc(XLogPack p) : XLog의 desc 값을 반환 + - String group(XLogPack p) : XLog의 group 값을 반환 + ### AlertRule Plugin - **TBD** \ No newline at end of file + **TBD** + diff --git a/scouter.server/scripts/sample2.readlink.sh b/scouter.server/scripts/sample2.readlink.sh old mode 100755 new mode 100644 diff --git a/scouter.server/src/scouter/server/db/SummaryRD.scala b/scouter.server/src/scouter/server/db/SummaryRD.scala index e9853a8b1..3b9f2b944 100644 --- a/scouter.server/src/scouter/server/db/SummaryRD.scala +++ b/scouter.server/src/scouter/server/db/SummaryRD.scala @@ -18,8 +18,8 @@ package scouter.server.db; -import scouter.server.db.status.SummaryIndex -import scouter.server.db.status.SummaryReader +import scouter.server.db.summary.SummaryIndex +import scouter.server.db.summary.SummaryReader import scouter.util.DateUtil import scouter.util.FileUtil import java.io.File diff --git a/scouter.server/src/scouter/server/db/SummaryWR.scala b/scouter.server/src/scouter/server/db/SummaryWR.scala index 116bc56da..5030281a6 100644 --- a/scouter.server/src/scouter/server/db/SummaryWR.scala +++ b/scouter.server/src/scouter/server/db/SummaryWR.scala @@ -19,8 +19,8 @@ package scouter.server.db; import scouter.lang.pack.SummaryPack import scouter.io.DataOutputX import scouter.server.Logger -import scouter.server.db.status.SummaryIndex -import scouter.server.db.status.SummaryWriter +import scouter.server.db.summary.SummaryIndex +import scouter.server.db.summary.SummaryWriter import scouter.util.DateUtil import scouter.util.FileUtil import scouter.util.IClose diff --git a/scouter.server/src/scouter/server/db/summary/SummaryIndex.scala b/scouter.server/src/scouter/server/db/summary/SummaryIndex.scala index 455b78e15..1b0ac831d 100644 --- a/scouter.server/src/scouter/server/db/summary/SummaryIndex.scala +++ b/scouter.server/src/scouter/server/db/summary/SummaryIndex.scala @@ -1,22 +1,22 @@ -/* -* 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. - * - */ +/* +* 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.status; +package scouter.server.db.summary; import java.io.IOException; import java.util.Hashtable; diff --git a/scouter.server/src/scouter/server/db/summary/SummaryReader.scala b/scouter.server/src/scouter/server/db/summary/SummaryReader.scala index 3b1ba9110..7e580e6f2 100644 --- a/scouter.server/src/scouter/server/db/summary/SummaryReader.scala +++ b/scouter.server/src/scouter/server/db/summary/SummaryReader.scala @@ -1,22 +1,22 @@ -/* -* 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. - * - */ +/* +* 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.status; +package scouter.server.db.summary; import java.io.IOException; import java.io.RandomAccessFile; @@ -50,14 +50,14 @@ class SummaryReader(file: String) extends IClose { def read(point: Long): Array[Byte] = { try { this.synchronized { - pointFile.seek(point); + pointFile.seek(point); val len = pointFile.readInt(); val buffer = new Array[Byte](len); pointFile.read(buffer); return buffer; } } catch { - case e: IOException => + case e: IOException => throw new RuntimeException(e); } } diff --git a/scouter.server/src/scouter/server/db/summary/SummaryWriter.scala b/scouter.server/src/scouter/server/db/summary/SummaryWriter.scala index cd1cd265f..4c4d49991 100644 --- a/scouter.server/src/scouter/server/db/summary/SummaryWriter.scala +++ b/scouter.server/src/scouter/server/db/summary/SummaryWriter.scala @@ -1,22 +1,22 @@ -/* -* 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. - * - */ +/* +* 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.status; +package scouter.server.db.summary; import java.io.IOException; import java.util.Hashtable; diff --git a/scouter.server/src/scouter/server/netio/service/handle/LoginService.scala b/scouter.server/src/scouter/server/netio/service/handle/LoginService.scala index e96925938..b91ef6010 100644 --- a/scouter.server/src/scouter/server/netio/service/handle/LoginService.scala +++ b/scouter.server/src/scouter/server/netio/service/handle/LoginService.scala @@ -45,7 +45,7 @@ class LoginService { val id = m.getText("id"); val passwd = m.getText("pass"); val ip = m.getText("ip"); - val name = m.getText("server_id"); + val name = m.getText("hostname"); val clientVer = m.getText("version"); val session = LoginManager.login(id, passwd, ip); m.put("session", session); @@ -56,7 +56,7 @@ class LoginService { user.hostname = name; user.version = clientVer; m.put("time", System.currentTimeMillis()); - m.put("server_id", getHostName()); + m.put("server_id", getServerId()); m.put("type", user.group); m.put("version", Version.getServerFullVersion()); val acc = AccountManager.getAccount(id); @@ -115,7 +115,7 @@ class LoginService { dout.writePack(m); } - def getHostName(): String = { + def getServerId(): String = { Configure.getInstance().server_id; } } \ No newline at end of file diff --git a/scouter.server/src/scouter/server/plugin/IXLog.java b/scouter.server/src/scouter/server/plugin/IXLog.java index 573385eed..12cf326cb 100644 --- a/scouter.server/src/scouter/server/plugin/IXLog.java +++ b/scouter.server/src/scouter/server/plugin/IXLog.java @@ -62,7 +62,7 @@ public String error(XLogPack p) { return TextRD.getString(DateUtil.yyyymmdd(p.endTime), TextTypes.ERROR, p.error); } - public String useAgent(XLogPack p) { + public String userAgent(XLogPack p) { return TextPermRD.getString(TextTypes.USER_AGENT, p.userAgent); } diff --git a/scouter.server/src/scouter/server/plugin/PlugInLoader.java b/scouter.server/src/scouter/server/plugin/PlugInLoader.java index c6317dd4c..f471b56f4 100644 --- a/scouter.server/src/scouter/server/plugin/PlugInLoader.java +++ b/scouter.server/src/scouter/server/plugin/PlugInLoader.java @@ -47,73 +47,74 @@ public void run() { ThreadUtil.sleep(5000); try { File root = new File(Configure.getInstance().plugin_dir); - checkModified(root); + reloadIfModified(root); } catch (Throwable t) { t.printStackTrace(); } } } - private void checkModified(File root) { - File script = new File(root, "alert.plug"); - if (script.canRead() == false) { + private void reloadIfModified(File root) { + File scriptFile = new File(root, "alert.plug"); + if (scriptFile.canRead() == false) { PlugInManager.alerts = null; } else { - if (PlugInManager.alerts == null || PlugInManager.alerts.lastModified != script.lastModified()) { - PlugInManager.alerts = (IAlert) create(script, "AlertImpl", IAlert.class, AlertPack.class); + if (PlugInManager.alerts == null || PlugInManager.alerts.lastModified != scriptFile.lastModified()) { + PlugInManager.alerts = (IAlert) create(scriptFile, "AlertImpl", IAlert.class, AlertPack.class); } } - script = new File(root, "counter.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "counter.plug"); + if (scriptFile.canRead() == false) { PlugInManager.counters = null; } else { - if (PlugInManager.counters == null || PlugInManager.counters.lastModified != script.lastModified()) { - PlugInManager.counters = (ICounter) create(script, "CounterImpl", ICounter.class, PerfCounterPack.class); + if (PlugInManager.counters == null || PlugInManager.counters.lastModified != scriptFile.lastModified()) { + PlugInManager.counters = (ICounter) create(scriptFile, "CounterImpl", ICounter.class, PerfCounterPack.class); } } - script = new File(root, "object.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "object.plug"); + if (scriptFile.canRead() == false) { PlugInManager.objects = null; } else { - if (PlugInManager.objects == null || PlugInManager.objects.lastModified != script.lastModified()) { - PlugInManager.objects = (IObject) create(script, "ObjectImpl", IObject.class, ObjectPack.class); + if (PlugInManager.objects == null || PlugInManager.objects.lastModified != scriptFile.lastModified()) { + PlugInManager.objects = (IObject) create(scriptFile, "ObjectImpl", IObject.class, ObjectPack.class); } } - script = new File(root, "xlog.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "xlog.plug"); + if (scriptFile.canRead() == false) { PlugInManager.xlog = null; } else { - if (PlugInManager.xlog == null || PlugInManager.xlog.lastModified != script.lastModified()) { - PlugInManager.xlog = (IXLog) create(script, "XLogImpl", IXLog.class, XLogPack.class); + if (PlugInManager.xlog == null || PlugInManager.xlog.lastModified != scriptFile.lastModified()) { + PlugInManager.xlog = (IXLog) create(scriptFile, "XLogImpl", IXLog.class, XLogPack.class); } } - script = new File(root, "xlogdb.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "xlogdb.plug"); + if (scriptFile.canRead() == false) { PlugInManager.xlogdb = null; } else { - if (PlugInManager.xlogdb == null || PlugInManager.xlogdb.lastModified != script.lastModified()) { - PlugInManager.xlogdb = (IXLog) create(script, "XLogDBImpl", IXLog.class, XLogPack.class); + if (PlugInManager.xlogdb == null || PlugInManager.xlogdb.lastModified != scriptFile.lastModified()) { + PlugInManager.xlogdb = (IXLog) create(scriptFile, "XLogDBImpl", IXLog.class, XLogPack.class); } } - script = new File(root, "xlogprofile.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "xlogprofile.plug"); + if (scriptFile.canRead() == false) { PlugInManager.xlogProfiles = null; } else { - if (PlugInManager.xlogProfiles == null || PlugInManager.xlogProfiles.lastModified != script.lastModified()) { - PlugInManager.xlogProfiles = (IXLogProfile) create(script, "XLogProfileImpl", IXLogProfile.class, + if (PlugInManager.xlogProfiles == null || PlugInManager.xlogProfiles.lastModified != scriptFile.lastModified()) { + PlugInManager.xlogProfiles = (IXLogProfile) create(scriptFile, "XLogProfileImpl", IXLogProfile.class, XLogProfilePack.class); } } - script = new File(root, "summary.plug"); - if (script.canRead() == false) { + scriptFile = new File(root, "summary.plug"); + if (scriptFile.canRead() == false) { PlugInManager.summary = null; } else { - if (PlugInManager.summary == null || PlugInManager.summary.lastModified != script.lastModified()) { - PlugInManager.summary = (ISummary) create(script, "SummaryImpl", ISummary.class, + if (PlugInManager.summary == null || PlugInManager.summary.lastModified != scriptFile.lastModified()) { + PlugInManager.summary = (ISummary) create(scriptFile, "SummaryImpl", ISummary.class, SummaryPack.class); } } } - // 반복적인 컴파일 시도를 막기위해 한번 실패한 파일은 컴파일을 다시 시도하지 않도록 한다. + + // Do Not retry compiling the file failed to compile before to prevent compiling broken files permanently. private LongSet compileErrorFiles = new LongSet(); private IPlugIn create(File file, String className, Class superClass, Class paramClass) { long fileSignature = fileSign(file); diff --git a/scouter.server/src/scouter/server/plugin/alert/AlertEngine.java b/scouter.server/src/scouter/server/plugin/alert/AlertEngine.java index a996ba8a9..223ab2e6b 100644 --- a/scouter.server/src/scouter/server/plugin/alert/AlertEngine.java +++ b/scouter.server/src/scouter/server/plugin/alert/AlertEngine.java @@ -23,33 +23,31 @@ public class AlertEngine { - static LinkedMap realTime = new LinkedMap().setMax(3000); + static LinkedMap realTimeMap = new LinkedMap().setMax(3000); public static void putRealTime(CounterKey key, Value value) { AlertRuleLoader loader = AlertRuleLoader.getInstance(); AlertRule rule = loader.alertRuleTable.get(key.counter); if (rule == null) return; - - RealCounter c = realTime.get(key); - if (c == null) { - c = new RealCounter( key); + + RealCounter counter = realTimeMap.get(key); + if (counter == null) { + counter = new RealCounter(key); AlertConf conf = loader.alertConfTable.get(key.counter); - //일시적으로 삭제되었을 가능성에 대비 + //defensive code for abnormal deletion if (conf == null) { conf = new AlertConf(); } - c.historySize(conf.history_size); - c.silentTime(conf.silent_time); - realTime.put(key, c); + counter.historySize(conf.history_size); + counter.silentTime(conf.silent_time); + realTimeMap.put(key, counter); } - c.value(value); - rule.process(c); - c.addValueHistory((Number) value); + counter.value(value); + rule.process(counter); + counter.addValueHistory((Number) value); } - - public static void load() { AlertRuleLoader.getInstance(); } diff --git a/scouter.server/src/scouter/server/plugin/alert/AlertRuleLoader.java b/scouter.server/src/scouter/server/plugin/alert/AlertRuleLoader.java index 4bf20b633..eabacf7ca 100644 --- a/scouter.server/src/scouter/server/plugin/alert/AlertRuleLoader.java +++ b/scouter.server/src/scouter/server/plugin/alert/AlertRuleLoader.java @@ -86,6 +86,7 @@ public boolean accept(File dir, String name) { private void clear(String name) { alertRuleTable.remove(name); alertConfTable.remove(name); + Logger.println("S217", "Clear alert rule : " + name); } private void checkModified(File root) { StringEnumer en = alertRuleTable.keys(); @@ -182,6 +183,7 @@ private AlertRule createRule(String name, File ruleFile) { c = impl.toClass(new URLClassLoader(new URL[0], this.getClass().getClassLoader()), null); AlertRule rule = (AlertRule) c.newInstance(); rule.lastModified = ruleFile.lastModified(); + Logger.println("S215", "Detected new alert rule : " + ruleFile.getName()); return rule; } catch (javassist.CannotCompileException ee) { compileErrorFiles.add(fileSignature); diff --git a/scouter.server/src/scouter/server/plugin/alert/RealCounter.java b/scouter.server/src/scouter/server/plugin/alert/RealCounter.java index f71f49b3d..a66d5b274 100644 --- a/scouter.server/src/scouter/server/plugin/alert/RealCounter.java +++ b/scouter.server/src/scouter/server/plugin/alert/RealCounter.java @@ -129,7 +129,7 @@ public long historyOldestTime() { return 0; long tm = _history.getLastKey(); long now = System.currentTimeMillis(); - return (now - _history.getLastKey()) / 1000; + return (now - tm) / 1000; } public int historyCount(int sec) { diff --git a/scouter.server/src/scouter/server/util/cardinality/HyperLogLog.java b/scouter.server/src/scouter/server/util/cardinality/HyperLogLog.java old mode 100755 new mode 100644 diff --git a/scouter.server/src/scouter/server/util/cardinality/MurmurHash.java b/scouter.server/src/scouter/server/util/cardinality/MurmurHash.java old mode 100755 new mode 100644 diff --git a/scouter.server/src/scouter/server/util/cardinality/RegisterSet.java b/scouter.server/src/scouter/server/util/cardinality/RegisterSet.java old mode 100755 new mode 100644