如何在Prometheus中配置模块执行时间?指标页面空白问题求助
问题排查:Prometheus指标页面空白的解决方法
核心问题分析
- 注册表实例不统一:每次执行
execute()都会新建PrometheusMeterRegistry,而启动的HTTPServer使用的是Prometheus默认的CollectorRegistry,两者完全独立,导致采集的指标无法被暴露的HTTP服务读取。 - Micrometer与Prometheus集成错误:直接使用原生Prometheus的
HTTPServer,没有关联Micrometer的注册表,无法将Micrometer收集的指标导出。
修复方案
1. 统一注册表实例
将PrometheusMeterRegistry声明为类成员变量,确保整个应用生命周期内只有一个实例,避免重复创建。
2. 关联Micrometer与Prometheus注册表
把Micrometer的注册表注册到Prometheus默认的CollectorRegistry中,让HTTPServer能获取到指标数据。
3. 优化计时逻辑(可选)
使用Micrometer原生的计时API替代手动计算时间差,代码更简洁规范。
修复后的完整代码
import java.util.Calendar; import java.util.Date; import com.documentum.bps.utils.PasswordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.documentum.fc.client.DfQuery; import com.documentum.fc.client.IDfCollection; import com.documentum.fc.client.IDfQuery; import com.documentum.fc.client.IDfSession; import com.documentum.fc.common.DfException; import com.pgi.tasks.bt.common.CreateSession; import io.micrometer.prometheus.PrometheusConfig; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.exporter.HTTPServer; import io.prometheus.client.CollectorRegistry; import java.util.concurrent.TimeUnit; import io.micrometer.core.instrument.Timer; @Component("VerifySessionCreationSpentTime") public class VerifySessionCreationSpentTime extends AbstractTask { private static final Logger log = LoggerFactory.getLogger(VerifySessionCreationSpentTime.class); private static final String DQL_GET_TEST_RESULT = "SELECT r_object_id FROM dm_document WHERE 1=0"; // 全局唯一的Prometheus注册表实例 private final PrometheusMeterRegistry prometheusRegistry; // 构造函数初始化注册表并关联到Prometheus默认CollectorRegistry public VerifySessionCreationSpentTime() { this.prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); CollectorRegistry.defaultRegistry.register(this.prometheusRegistry.getPrometheusRegistry()); } @Override public void execute() throws Exception { log.debug("VerifySessionCreationSpentTime: begin"); System.out.println(1); IDfCollection collection = null; IDfSession session=null; CreateSession call = new CreateSession(); // 使用Micrometer Timer自动记录耗时 Timer.Sample sample = Timer.start(prometheusRegistry); try { session = call.privateGetSession(); log.debug("Running test query : " + DQL_GET_TEST_RESULT, null, null); IDfQuery query = new DfQuery(); query.setDQL(DQL_GET_TEST_RESULT); collection = query.execute(session, IDfQuery.DF_READ_QUERY); } catch (DfException de) { log.error("DFC Exception during test execution " + de.getMessage(), null, null); } catch (Exception e) { log.error("The following error ocurred: ", e); } finally { try { if (collection != null) { collection.close(); } call.releasesession(); } catch (Exception e) { ; } // 结束计时并记录指标 sample.stop(prometheusRegistry.timer("processingDuration")); } log.debug("VerifySessionCreationSpentTime: end"); } public static void main(String[] args) throws Exception { // 启动HTTPServer,使用默认的CollectorRegistry new HTTPServer(8000); VerifySessionCreationSpentTime task = new VerifySessionCreationSpentTime(); task.execute(); // 保持程序运行,避免执行完就退出 Thread.currentThread().join(); } }
额外注意点
- 主方法中添加
Thread.currentThread().join(),避免程序执行完execute()后立即退出,导致HTTPServer也随之关闭。 - 如果是在Spring环境中,建议通过
@Bean方式注册PrometheusMeterRegistry和HTTPServer,利用Spring的生命周期管理更规范。
内容的提问来源于stack exchange,提问作者Q_Q_
相关产品推荐
相关产品推荐

