龙空技术网

Spring Boot打印完整的SQL,并得知从那个请求过来的

纯属虚构161857617 2975

前言:

当前咱们对“spring 数据源配置打印sql”可能比较注重,小伙伴们都想要知道一些“spring 数据源配置打印sql”的相关知识。那么小编也在网络上收集了一些对于“spring 数据源配置打印sql””的相关资讯,希望兄弟们能喜欢,我们快快来学习一下吧!

随着业务复杂度的增加,需要对Controller做一下监控controller调用时间调用了那些sql调用了那些方法等而上面这些,实际上阿里的arms是可以监控的,但是arms不能监控执行了那SQL我们来写一个拦截器,实现以下功能请求调用时间打印请求的traceId,以便跟踪根据traceId得到一个请求调用了那些sql 打印完整的SQL

直接上代码:

@Slf4jpublic class DruidSlf4jLoggerFilterExtension extends Slf4jLogFilter {    @Resource    private HttpServletRequest request;    @Resource    private UrlPathHelper urlPathHelper;    private final SQLUtils.FormatOption statementSqlFormatOption = new SQLUtils.FormatOption(true, true);    @Override    protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {        try {            // 请求地址            final String reqUri = Optional.ofNullable(request).map((request) -> urlPathHelper.getRequestUri(request))                    .orElse("");            final String cxtPath = Optional.ofNullable(request).map((request) -> urlPathHelper.getContextPath(request))                    .orElse("");            final String finalUrl = cxtPath + "/" + reqUri;            statement.setLastExecuteTimeNano();            double nanos = statement.getLastExecuteTimeNano();            double millis = nanos / (1000 * 1000);            int parametersSize = statement.getParametersSize();            List<Object> parameters = new ArrayList<>(parametersSize);            for (int i = 0; i < parametersSize; ++i) {                JdbcParameter jdbcParam = statement.getParameter(i);                parameters.add(jdbcParam != null ? jdbcParam.getValue() : null);            }            // 打印完整的SQL带TraceId            String formattedSql = StringUtil.addPrefixOnLine(formatParamSql(sql, parametersSize, statement, parameters),                    TraceHelper.getTraceId() + " " + finalUrl + "\t");            log.info("{conn-{}, {}} executed. {} millis. \n{}", statement.getConnectionProxy().getId(),                    stmtId(statement), String.format("%.2f", millis), formattedSql);        } catch (Exception ex) {            // 注意一定要拦截所有异常,不影响业务的执行            TraceHelper.error("SQL格式化异常", ex);        }    }    // 格式化成完整的SQL    private String formatParamSql(String sql, int parametersSize, StatementProxy statement, List<Object> parameters) {        String formattedSql = sql;        if (parametersSize > 0) {            String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();            formattedSql = SQLUtils.format(sql, dbType, parameters, this.statementSqlFormatOption);        }        return formattedSql;    }    private String stmtId(StatementProxy statement) {        StringBuilder buf = new StringBuilder();        if (statement instanceof CallableStatementProxy) {            buf.append("cstmt-");        } else if (statement instanceof PreparedStatementProxy) {            buf.append("pstmt-");        } else {            buf.append("stmt-");        }        buf.append(statement.getId());        return buf.toString();    }} 

TraceHelper类

@Slf4j@Componentpublic class TraceHelper {    private TraceHelper() {    }    public static void error(Exception ex) {        // 完整的异常堆栈信息,包含traceId        String errorStackTrace = StringUtil.addPrefixOnLine(Throwables.getStackTraceAsString(ex), getTraceId() + "\t");        log.error(errorStackTrace);    }    public static void error(String message, Exception ex) {        // 完整的异常堆栈信息,包含traceId        String errorStackTrace = StringUtil.addPrefixOnLine(Throwables.getStackTraceAsString(ex), getTraceId() + "\t");        log.error(getTraceId() + "\t" + message + "\n" + errorStackTrace);    }    public static String getTraceId() {        Tracer tracer = SpringContextUtil.getBean(Tracer.class);        if (tracer == null) {            return "000000000";        }        return Optional.ofNullable(tracer.getCurrentSpan()).map(Span::traceIdString).orElse("");    }}

标签: #spring 数据源配置打印sql #spring打印sql语句 #spring配置打印sql