##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);
}
}