prometheus收集springboot指标
prometheus收集springboot指标
super-wen 发表于6个月前
prometheus收集springboot指标
  • 发表于 6个月前
  • 阅读 88
  • 收藏 2
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

##prometheus 主动采集 springboot

maven dependency

          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-actuator</artifactId>
                <version>${spring-boot.version}</version>
         </dependency>

        <dependency>
            <groupId>com.moelholm</groupId>
            <artifactId>prometheus-spring-boot-starter</artifactId>
            <version>1.0.1</version>
        </dependency>

实现逻辑

将springboot内部的publicMetrics转为prometheus 格式.

@Component
public class SpringBootMetricsCollector extends Collector {
  private final Collection<PublicMetrics> publicMetrics;

  @Autowired
  public SpringBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
    this.publicMetrics = publicMetrics;
  }

  @Override
  public List<MetricFamilySamples> collect() {
    ArrayList<MetricFamilySamples> samples = new ArrayList<MetricFamilySamples>();
    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<String>(), new ArrayList<String>(), value)));
        samples.add(metricFamilySamples);
      }
    }
    return samples;
  }
}

prometheus 通过访问/prometheus节点采集。

git库地址:https://github.com/thomasdarimont/prometheus-spring-boot-starter

springboot 推送metrics 到 pushGateway,然后prometheus 去pushGateway采集。

          <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-actuator</artifactId>
                <version>${spring-boot.version}</version>
         </dependency>

            <dependency>
                <groupId>io.prometheus</groupId>
                <artifactId>simpleclient_pushgateway</artifactId>
                <version>0.0.21</version>
            </dependency>
             <dependency>
                <groupId>io.prometheus</groupId>
                <artifactId>simpleclient_spring_boot</artifactId>
                <version>0.0.21</version>
            </dependency>
            

具体代码

@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() {
        Map<String,String> map = 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 采集.

@Configuration
public 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() {


        Map<String,String> map = 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);
    }


}
共有 人打赏支持
粉丝 5
博文 31
码字总数 10771
×
super-wen
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: