Quellcode durchsuchen

加入调用链监控 sql 信息 耗时

java110 vor 4 Jahren
Ursprung
Commit
885fb5ddfb

+ 33 - 0
java110-bean/src/main/java/com/java110/dto/trace/TraceDbDto.java

@@ -0,0 +1,33 @@
+package com.java110.dto.trace;
+
+import java.io.Serializable;
+
+public class TraceDbDto implements Serializable {
+    private String sql;
+    private String params;
+    private long duration;
+
+    public String getSql() {
+        return sql;
+    }
+
+    public void setSql(String sql) {
+        this.sql = sql;
+    }
+
+    public String getParams() {
+        return params;
+    }
+
+    public void setParams(String params) {
+        this.params = params;
+    }
+
+    public long getDuration() {
+        return duration;
+    }
+
+    public void setDuration(long duration) {
+        this.duration = duration;
+    }
+}

+ 9 - 0
java110-bean/src/main/java/com/java110/dto/trace/TraceDto.java

@@ -11,6 +11,7 @@ public class TraceDto implements Serializable {
     private long timestamp;
 
     private List<TraceAnnotationsDto> annotations;
+    private List<TraceDbDto> dbs;
 
     private TraceParamDto param;
 
@@ -70,4 +71,12 @@ public class TraceDto implements Serializable {
     public void setParam(TraceParamDto param) {
         this.param = param;
     }
+
+    public List<TraceDbDto> getDbs() {
+        return dbs;
+    }
+
+    public void setDbs(List<TraceDbDto> dbs) {
+        this.dbs = dbs;
+    }
 }

+ 22 - 4
java110-core/src/main/java/com/java110/core/trace/Java110TraceFactory.java

@@ -3,10 +3,7 @@ package com.java110.core.trace;
 import com.alibaba.fastjson.JSONObject;
 import com.java110.core.factory.GenerateCodeFactory;
 import com.java110.core.log.LoggerFactory;
-import com.java110.dto.trace.TraceAnnotationsDto;
-import com.java110.dto.trace.TraceDto;
-import com.java110.dto.trace.TraceEndpointDto;
-import com.java110.dto.trace.TraceParamDto;
+import com.java110.dto.trace.*;
 import com.java110.utils.constant.CommonConstant;
 import com.java110.utils.constant.EnvironmentConstant;
 import com.java110.utils.factory.ApplicationContextFactory;
@@ -152,6 +149,8 @@ public class Java110TraceFactory {
         traceDto.setAnnotations(traceAnnotationsDtos);
         traceDto.setTraceId(traceId);
 
+        traceDto.setDbs(new ArrayList<>());
+
         put(traceDto.getId(), traceDto);
         putSpanId(SPAN_ID, traceDto.getId());
         return traceDto.getId();
@@ -228,6 +227,25 @@ public class Java110TraceFactory {
         clearSpanId();
     }
 
+    /**
+     * 添加db
+     *
+     * @param sql
+     */
+    public static void putDbs(String sql, String param, long duration) {
+        TraceDto traceDto = getTraceDto();
+
+        if (traceDto == null) {
+            return;
+        }
+        List<TraceDbDto> dbs = traceDto.getDbs();
+        TraceDbDto traceDbDto = new TraceDbDto();
+        traceDbDto.setSql(sql);
+        traceDbDto.setParams(param);
+        traceDbDto.setDuration(duration);
+        dbs.add(traceDbDto);
+    }
+
     /**
      * 清理事务
      */

+ 156 - 0
java110-core/src/main/java/com/java110/core/trace/Java110TraceSqlInterceptor.java

@@ -0,0 +1,156 @@
+package com.java110.core.trace;
+
+import com.java110.core.log.LoggerFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.ParameterMapping;
+import org.apache.ibatis.mapping.ParameterMode;
+import org.apache.ibatis.plugin.*;
+import org.apache.ibatis.reflection.MetaObject;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.RowBounds;
+import org.apache.ibatis.type.TypeHandlerRegistry;
+import org.slf4j.Logger;
+import sun.plugin2.main.server.ResultHandler;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+@Intercepts
+        ({
+                @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
+                @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
+        })
+public class Java110TraceSqlInterceptor implements Interceptor {
+
+    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
+        Object parameterObject = null;
+        if (invocation.getArgs().length > 1) {
+            parameterObject = invocation.getArgs()[1];
+        }
+
+        long start = System.currentTimeMillis();
+
+        Object result = invocation.proceed();
+
+        //String statementId = mappedStatement.getId();
+        BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
+        Configuration configuration = mappedStatement.getConfiguration();
+
+        long end = System.currentTimeMillis();
+        long timing = end - start;
+
+        Java110TraceFactory.putDbs(boundSql.getSql(), getSqlParam(boundSql, parameterObject, configuration), timing);
+
+        return result;
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        if (target instanceof Executor) {
+            return Plugin.wrap(target, this);
+        }
+        return target;
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+    }
+
+    private String getSqlParam(BoundSql boundSql, Object parameterObject, Configuration configuration) {
+
+        List<String> values = new ArrayList<>();
+        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
+        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
+        if (parameterMappings != null) {
+            for (int i = 0; i < parameterMappings.size(); i++) {
+                ParameterMapping parameterMapping = parameterMappings.get(i);
+                if (parameterMapping.getMode() != ParameterMode.OUT) {
+                    Object value;
+                    String propertyName = parameterMapping.getProperty();
+                    if (boundSql.hasAdditionalParameter(propertyName)) {
+                        value = boundSql.getAdditionalParameter(propertyName);
+                    } else if (parameterObject == null) {
+                        value = null;
+                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
+                        value = parameterObject;
+                    } else {
+                        MetaObject metaObject = configuration.newMetaObject(parameterObject);
+                        value = metaObject.getValue(propertyName);
+                    }
+                    values.add(getValue(value));
+                }
+            }
+        }
+        return StringUtils.join(values, "|");
+    }
+
+    private String getValue(Object propertyValue) {
+        String result;
+        if (propertyValue != null) {
+            if (propertyValue instanceof String) {
+                result = "'" + propertyValue + "'";
+            } else if (propertyValue instanceof Date) {
+                result = "'" + DATE_FORMAT.format(propertyValue) + "'";
+            } else {
+                result = propertyValue.toString();
+            }
+        } else {
+            result = "null";
+        }
+        return result;
+    }
+
+//    private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {
+//        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
+//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
+//        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
+//        if (parameterMappings != null) {
+//            for (int i = 0; i < parameterMappings.size(); i++) {
+//                ParameterMapping parameterMapping = parameterMappings.get(i);
+//                if (parameterMapping.getMode() != ParameterMode.OUT) {
+//                    Object value;
+//                    String propertyName = parameterMapping.getProperty();
+//                    if (boundSql.hasAdditionalParameter(propertyName)) {
+//                        value = boundSql.getAdditionalParameter(propertyName);
+//                    } else if (parameterObject == null) {
+//                        value = null;
+//                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
+//                        value = parameterObject;
+//                    } else {
+//                        MetaObject metaObject = configuration.newMetaObject(parameterObject);
+//                        value = metaObject.getValue(propertyName);
+//                    }
+//                    sql = replacePlaceholder(sql, value);
+//                }
+//            }
+//        }
+//        return sql;
+//    }
+
+//    private String replacePlaceholder(String sql, Object propertyValue) {
+//        String result;
+//        if (propertyValue != null) {
+//            if (propertyValue instanceof String) {
+//                result = "'" + propertyValue + "'";
+//            } else if (propertyValue instanceof Date) {
+//                result = "'" + DATE_FORMAT.format(propertyValue) + "'";
+//            } else {
+//                result = propertyValue.toString();
+//            }
+//        } else {
+//            result = "null";
+//        }
+//        return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));
+//    }
+}

+ 3 - 1
java110-db/src/main/java/com/java110/db/MyBatisConfig.java

@@ -1,6 +1,7 @@
 package com.java110.db;
 
 import com.java110.config.properties.code.Java110Properties;
+import com.java110.core.trace.Java110TraceSqlInterceptor;
 import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.SqlSessionFactoryBean;
@@ -50,7 +51,8 @@ public class MyBatisConfig implements TransactionManagementConfigurer {
         SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
         bean.setDataSource(dataSource);
         bean.setTypeAliasesPackage("tk.mybatis.springboot.model");
-        bean.setPlugins(new Interceptor[]{new Java110MybatisInterceptor()});
+        //bean.setPlugins(new Interceptor[]{new Java110MybatisInterceptor()});
+        bean.setPlugins(new Interceptor[]{new Java110MybatisInterceptor(),new Java110TraceSqlInterceptor()});
 
         //添加XML目录
         ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();