##prometheus 主动采集 springboot
maven dependency
org.springframework.boot spring-boot-actuator ${spring-boot.version} com.moelholm prometheus-spring-boot-starter 1.0.1
实现逻辑
将springboot内部的publicMetrics转为prometheus 格式.
@Componentpublic class SpringBootMetricsCollector extends Collector { private final CollectionpublicMetrics; @Autowired public SpringBootMetricsCollector(Collection publicMetrics) { this.publicMetrics = publicMetrics; } @Override public List collect() { ArrayList samples = new ArrayList (); for (PublicMetrics publicMetrics : this.publicMetrics) { for (Metric metric : publicMetrics.metrics()) { String name = Collector.sanitizeMetricName(metric.getName()); double value = metric.getValue().doubleValue(); MetricFamilySamples metricFamilySamples = new MetricFamilySamples( name, Type.GAUGE, name, Collections.singletonList( new MetricFamilySamples.Sample(name, new ArrayList (), new ArrayList (), value))); samples.add(metricFamilySamples); } } return samples; }}
prometheus 通过访问/prometheus节点采集。
git库地址:
springboot 推送metrics 到 pushGateway,然后prometheus 去pushGateway采集。
org.springframework.boot spring-boot-actuator ${spring-boot.version} io.prometheus simpleclient_pushgateway 0.0.21 io.prometheus simpleclient_spring_boot 0.0.21
具体代码
@Configuration@ComponentScan("io.prometheus.client.spring.boot")public class PrometheusConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(PrometheusConfiguration.class); @Value("${spring.application.name}") String applicationName; @Value("${prometheus.pushgateway.host}") String pushHost; @Value("${prometheus.pushgateway.intervalInMillis:10000}") long intervalInMillis; @Autowired private SpringBootMetricsCollector springBootMetricsCollector; @PostConstruct public void initialize() { Mapmap = new HashMap<>(); //这里存在问题,在docker中获得的是1@localhost map.put("instance", ManagementFactory.getRuntimeMXBean().getName()); PushGateway prometheusPush = new PushGateway(pushHost); Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { try { LOGGER.debug("prometheus push"); prometheusPush.push(springBootMetricsCollector, applicationName,map); } catch (Exception e) { LOGGER.error("prometheus push error", e); } }, 5000, intervalInMillis, TimeUnit.MILLISECONDS); }}
修改上述代码,使之适用dcos,docker环境
当服务部署在dcos上时,端口是不固定,数量是不固定的.这时候就需要通过主动推送到pushGateway后,交由prometheus 采集.
@Configurationpublic class SystemConfiguration implements EnvironmentAware { private static final Logger LOGGER = LoggerFactory.getLogger(SystemConfiguration.class); private String host;//docker 传入的宿主机ip private String port0; private String prot1; @Value("${server.port}") private String serverPort; @Override public void setEnvironment(Environment environment) { /** * 在docker中.目的是从环境变量中获得传入的宿主机ip和端口. */ this.host = environment.getProperty("HOST"); this.port0 = environment.getProperty("PORT0"); this.prot1 = environment.getProperty("PORT1"); LOGGER.info("-------------------------environment"); LOGGER.info("host:"+host); LOGGER.info("port0:"+ port0); LOGGER.info("prot1:"+ prot1); } @PostConstruct public void init(){ if(StringUtils.isEmpty(host)){ //未能从环境变量中获得host try { this.host = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { LOGGER.error("获得host失败",e); } this.port0 = serverPort; } LOGGER.info("-------------------------postConstruct"); LOGGER.info("host:"+this.host); LOGGER.info("port0:"+this.port0); } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public String getPort0() { return port0; } public void setPort0(String port0) { this.port0 = port0; } public String getProt1() { return prot1; } public void setProt1(String prot1) { this.prot1 = prot1; } public String getServerPort() { return serverPort; } public void setServerPort(String serverPort) { this.serverPort = serverPort; }}@Configuration@ComponentScan("io.prometheus.client.spring.boot")public class PrometheusConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(PrometheusConfiguration.class); @Value("${spring.application.name}") String applicationName; @Value("${prometheus.pushgateway.host}") String pushHost; @Value("${prometheus.pushgateway.intervalInMillis:10000}") long intervalInMillis; @Autowired private SystemConfiguration systemConfiguration; @Autowired private SpringBootMetricsCollector springBootMetricsCollector; @PostConstruct public void initialize() { Mapmap = new HashMap<>(); map.put("instance", systemConfiguration.getHost()+"@"+systemConfiguration.getPort0()); PushGateway prometheusPush = new PushGateway(pushHost); Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { try { LOGGER.debug("prometheus push"); prometheusPush.push(springBootMetricsCollector, applicationName,map); } catch (Exception e) { LOGGER.error("prometheus push error", e); } }, 5000, intervalInMillis, TimeUnit.MILLISECONDS); }}