本文采用 Java 的实现方式针对 prometheus 监控
需要新建 Mybatis 的代理类

  1. import java.util.Properties;
  2. import org.apache.ibatis.cache.CacheKey;
  3. import org.apache.ibatis.executor.Executor;
  4. import org.apache.ibatis.mapping.BoundSql;
  5. import org.apache.ibatis.mapping.MappedStatement;
  6. import org.apache.ibatis.plugin.Interceptor;
  7. import org.apache.ibatis.plugin.Intercepts;
  8. import org.apache.ibatis.plugin.Invocation;
  9. import org.apache.ibatis.plugin.Plugin;
  10. import org.apache.ibatis.plugin.Signature;
  11. import org.apache.ibatis.session.ResultHandler;
  12. import org.apache.ibatis.session.RowBounds;
  13. import org.springframework.stereotype.Component;
  14. import com.didapinche.server.commons.common.metrics.InterfaceMonitor;
  15. import com.didapinche.server.commons.common.metrics.base.CommonUtils;
  16. import io.prometheus.client.SimpleTimer;
  17. import io.prometheus.client.Summary;
  18. /**
  19. * mybatis拦截器实现prometheus监控sql层
  20. *
  21. * @author 刘昌飞(liuchangfei @ didachuxing.com)
  22. * 2018年10月10日 下午1:53:13
  23. */
  24. @Intercepts({
  25. @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
  26. @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
  27. @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
  28. })
  29. @Component
  30. public class MybatisExecuteInterceptor implements Interceptor {
  31. private static final String MYBATIS = "mybatis";
  32. private static final Summary sqlLatency = Summary
  33. .build("server_sql_duration_seconds", "about sql execute duration")
  34. .labelNames("host", "app", "method")
  35. .quantile(0.8, 0.01).quantile(0.9, 0.01).quantile(0.99, 0.01)
  36. .register();
  37. @Override
  38. public Object intercept(Invocation invocation) throws Throwable {
  39. MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
  40. String id = ms.getId();
  41. String[] split = id.split("\\.");
  42. String methodName = split[split.length - 2] + ":" + split[split.length - 1];
  43. InterfaceMonitor.getInstance().addTotal(methodName, MYBATIS);
  44. SimpleTimer st = new SimpleTimer();
  45. Object proceed = null;
  46. try {
  47. proceed = invocation.proceed();
  48. } catch (Exception e) {
  49. InterfaceMonitor.getInstance().addFail(methodName, MYBATIS);
  50. throw e;
  51. }
  52. sqlLatency.labels(CommonUtils.getHostName(), CommonUtils.getAppName(), methodName).observe(st.elapsedSeconds());
  53. return proceed;
  54. }
  55. @Override
  56. public Object plugin(Object target) {
  57. return Plugin.wrap(target, this);
  58. }
  59. @Override
  60. public void setProperties(Properties properties) {
  61. }
  62. }

Grafana 监控如下
Promethus 监控 - MyBatis - 图2

  • Counter 监控 QPS 或者 QPM

Promethus 监控 - MyBatis - 图3