前言:
当前咱们对“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(""); }}