Maven依赖(根据个人情况使用具体版本,我这儿因为框架关系,有默认版本,可不写)
1. <dependency>2. <groupId>org.springframework.boot</groupId>3. <artifactId>spring-boot-starter-web</artifactId>4. </dependency>5. <dependency>6. <groupId>io.micrometer</groupId>7. <artifactId>micrometer-registry-prometheus</artifactId>8. </dependency>9. <dependency>10. <groupId>org.springframework.boot</groupId>11. <artifactId>spring-boot-starter-actuator</artifactId>12. </dependency>
配置文件(yml为例)
1. management:2. endpoints:3. web:4. exposure:5. include: '*' # info, health, beans, env, metrics, mappings, scheduledtasks, threaddump,prometheus6. base-path: /actuator7. metrics:8. tags:9. application: ${artifactId} # 公共标签
全局标签
1. @Bean2. MeterRegistryCustomizer<MeterRegistry> configurer(@Value("${spring.application.name}") String applicationName) {3. return registry -> registry.config().commonTags("application", applicationName);4. }
自定义指标代码示例(DemoTable是个实体,DemoTableService是个借口,DemoTableServiceImpl是个接口实现类,缺的东西要么自行创建,要么根据情况忽略掉也可以)
TestMetric.java(代码中对指标的阐释-摘抄自互联网,,,忘了哪儿了。。。)
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.capitek.cloud.sub.server.entity.DemoTable;import com.capitek.cloud.sub.server.service.DemoTableService;import io.micrometer.core.instrument.*;5. import org.springframework.beans.factory.annotation.Autowired;6. import org.springframework.stereotype.Component;7.8. import javax.annotation.PostConstruct;9.10. @Component11. public class TestMetric {12.13. @Autowired14. private DemoTableService demoTableService;15.16. @Autowired17. private MeterRegistry meterRegistry;18.19. // 只增的指标20. // 以下4个counter指标名称相同,标签不同,根据标签可区分彼此21. public Counter boyJavaCounter;22. public Counter boyCPlusCounter;23. public Counter girlJavaCounter;24. public Counter girlCPlusCounter;25.26. // 可增减的指标27. public Gauge demoGauge;28.29. // 计时器30. public Timer demoTimer;31.32. // 计算分布使用此指标33. public DistributionSummary demoSummary;34.35. @PostConstruct36. private void init() {37.38. /**----------------------------------------------↓Counter↓---------------------------------------------------*/39.40. /**41. * Counter是一种比较简单的Meter,它是一种单值的度量类型,或者说是一个单值计数器。42. * Counter的作用是记录总量或者计数值,适用于一些单向增长类型的统计,例如下单、支付次数、接口请求总量记录等等,43. * 通过Tag可以区分不同的场景,对于下单,可以使用不同的Tag标记不同的业务来源或者是按日期划分,44. * 对于Http请求总量记录,可以使用Tag区分不同的URL。45. *46. * 定义四个Counter指标,按照性别与技术栈分组(分组是根据标签任意自定义,自己觉得合理即可),当然,如指标不需要分组,则定义一个Counter即可。47. * 注意:description没什么实际作用,且同一指标名只能拥有一个description,后设置的无效,因此description应设置为一种通用的描述性文字。如下为设置效果。48. * 其中application标签是全局标签,全局标签会作用于每一个指标中49. */50. /**51. # HELP employee_count_total 性别为boy,技术栈为java的人数52. # TYPE employee_count_total counter53. employee_count_total{application="subsystem-demo",job="c++",sex="girl",} 0.054. employee_count_total{application="subsystem-demo",job="c++",sex="boy",} 0.055. employee_count_total{application="subsystem-demo",job="java",sex="girl",} 0.056. employee_count_total{application="subsystem-demo",job="java",sex="boy",} 0.057. */58. boyJavaCounter = Counter.builder("employee.count").tags(Tags.of("sex", "boy", "job", "java")).description("性别为boy,技术栈为java的人数").register(meterRegistry);59. boyCPlusCounter = Counter.builder("employee.count").tags(Tags.of("sex", "boy", "job", "c++")).description("性别为boy,技术栈为c++的人数").register(meterRegistry);60. girlJavaCounter = Counter.builder("employee.count").tags(Tags.of("sex", "girl", "job", "java")).description("性别为girl,技术栈为java的人数").register(meterRegistry);61. girlCPlusCounter = Counter.builder("employee.count").tags(Tags.of("sex", "girl", "job", "c++")).description("性别为girl,技术栈为c++的人数").register(meterRegistry);62.63. /**----------------------------------------------↑Counter↑----------------------------------------------------*/64.65. /**----------------------------------------------↓Gauge↓------------------------------------------------------*/66.67. // 定义一个Gauge指标,每次拉取指标时,gauge的值会从demoTableService::getTest接口中获取68. demoGauge = Gauge.builder("employee_online", demoTableService::getTest).description("this is demo gauge description").register(meterRegistry);69. // 如下为设置效果70. /**71. * # HELP employee_online this is demo gauge description72. * # TYPE employee_online gauge73. * employee_online{application="subsystem-demo",} 4.074. */75.76. /**----------------------------------------------↑Gauge↑------------------------------------------------------*/77.78. /**----------------------------------------------↓Summary↓----------------------------------------------------*/79.80. // 计算分布情况81. /**82. * 计算分布情况,不依赖于时间83. * Summary(摘要)主要用于跟踪事件的分布,在Micrometer中,对应的类是DistributionSummary(分发摘要)。84. * 它的使用方式和Timer十分相似,但是它的记录值并不依赖于时间单位。85. */86. demoSummary = DistributionSummary.builder("demo.summary")87. .tag("summary_tag", "summary_tag_value")88. .description("this is a demo summary metric")89. .register(meterRegistry);90. demoSummary.record(3D);91. demoSummary.record(4D);92. demoSummary.record(5D);93. demoSummary.record(6D);94. demoSummary.record(10D);95. // 如下为设置效果96. /**97. * # HELP demo_summary this is a demo summary metric98. * # TYPE demo_summary summary99. * demo_summary_count{application="subsystem-demo",summary_tag="summary_tag_value",} 5.0100. * demo_summary_sum{application="subsystem-demo",summary_tag="summary_tag_value",} 28.0101. * # HELP demo_summary_max this is a demo summary metric102. * # TYPE demo_summary_max gauge103. * demo_summary_max{application="subsystem-demo",summary_tag="summary_tag_value",} 10.0104. */105.106. /**----------------------------------------------↑Summary↑----------------------------------------------------*/107.108. /**----------------------------------------------↓Timer↓------------------------------------------------------*/109.110. /**111. * 计算分布情况,依赖于时间112. * Timer(计时器)适用于记录耗时比较短的事件的执行时间,通过时间分布展示事件的序列和发生频率。113. * 所有的Timer的实现至少记录了发生的事件的数量和这些事件的总耗时,从而生成一个时间序列。114. * Timer的基本单位基于服务端的指标而定,但是实际上我们不需要过于关注Timer的基本单位,因为Micrometer在存储生成的时间序列的时候会自动选择适当的基本单位。115. *116. * 如果一个任务的耗时很长,直接使用 Timer 并不是一个好的选择,因为 Timer 只有在任务完成之后才会记录时间。117. * 更好的选择是使用 LongTaskTimer。LongTaskTimer 可以在任务进行中记录已经耗费的时间118. */119. demoTimer = Timer.builder("demo.timer")120. .tag("demo_timer_tag", "demo_timer_tag_value")121. .description("this is a demo timer")122. .register(meterRegistry);123. demoTimer.record(() -> {124. demoTableService.getTest();125. });126. // 如下为设置效果127. /**128. * # HELP demo_timer_seconds this is a demo timer129. * # TYPE demo_timer_seconds summary130. * demo_timer_seconds_count{application="subsystem-demo",demo_timer_tag="demo_timer_tag_value",} 1.0131. * demo_timer_seconds_sum{application="subsystem-demo",demo_timer_tag="demo_timer_tag_value",} 0.035948626132. * # HELP demo_timer_seconds_max this is a demo timer133. * # TYPE demo_timer_seconds_max gauge134. * demo_timer_seconds_max{application="subsystem-demo",demo_timer_tag="demo_timer_tag_value",} 0.035948626135. */136.137. /**----------------------------------------------↑Timer↑------------------------------------------------------*/138.139. }140. }
DemoTableServiceImpl.java
1. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;2. import com.baomidou.mybatisplus.core.metadata.IPage;3. import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;4. import com.capitek.cloud.common.constants.CommonConstants;5. import com.capitek.cloud.common.model.PageParams;6. import com.capitek.cloud.common.mybatis.base.service.impl.BaseServiceImpl;7. import com.capitek.cloud.sub.server.annotation.DataFilter;8. import com.capitek.cloud.sub.server.entity.DemoTable;9. import com.capitek.cloud.sub.server.mapper.DemoTableMapper;10. import com.capitek.cloud.sub.server.monitor.TestMetric;11. import com.capitek.cloud.sub.server.service.DemoTableService;12. import org.springframework.beans.factory.annotation.Autowired;13. import org.springframework.stereotype.Service;14. import org.springframework.transaction.annotation.Transactional;15.16. @Service17. @Transactional(rollbackFor = Exception.class)18. public class DemoTableServiceImpl extends BaseServiceImpl<DemoTableMapper, DemoTable> implements DemoTableService {19.20. @Autowired21. private TestMetric testMetric;22.23. @Override24. @DataFilter(user = true)25. public IPage<DemoTable> findListPage(PageParams<DemoTable> pageParams) {26. DemoTable query = pageParams.mapToObject(DemoTable.class);27. QueryWrapper<DemoTable> queryWrapper = new QueryWrapper<DemoTable>();28. queryWrapper.lambda()29. .like(ObjectUtils.isNotEmpty(query.getName()), DemoTable::getName, query.getName())30. .apply(ObjectUtils.isNotEmpty(pageParams.getRequestMap().get(CommonConstants.SQL_FILTER)), (String)pageParams.getRequestMap().get(CommonConstants.SQL_FILTER));31. // 此处只是测试,某些指标值的修改应在合理的地方去触发32. testMetric.boyJavaCounter.increment();33. testMetric.boyCPlusCounter.increment();34. testMetric.girlJavaCounter.increment();35. testMetric.girlCPlusCounter.increment();36. return page(pageParams, queryWrapper);37. }38.39. // 只是一个简单的接口,返回个数儿给指标40. @Override41. public int getTest(){42. return baseMapper.selectCount(new QueryWrapper<>());43. }44.45. }
