使用 Prometheus Client SDK 开发 Java 应用自定义指标

1. 添加依赖

在 Maven 项目中添加 Prometheus Java 客户端依赖:

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient</artifactId>
    <version>0.16.0</version>
</dependency>
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_httpserver</artifactId>
    <version>0.16.0</version>
</dependency>

2. 核心指标类型
类型 用途 特点
计数器 累计值 只增不减(如请求总数)
仪表盘 瞬时值 可增减(如内存使用量)
直方图 分布统计 自动分桶(如响应时间分布)
摘要 分位数统计 客户端计算分位数
3. 定义自定义指标
import io.prometheus.client.*;

// 计数器示例:统计订单创建总数
static final Counter ordersCreated = Counter.build()
    .name("orders_created_total")
    .help("Total created orders")
    .register();

// 仪表盘示例:当前活跃用户数
static final Gauge activeUsers = Gauge.build()
    .name("active_users")
    .help("Currently active users")
    .register();

// 直方图示例:API响应时间分布
static final Histogram responseTime = Histogram.build()
    .name("http_response_time_seconds")
    .help("HTTP response time distribution")
    .buckets(0.1, 0.5, 1, 2, 5)  // 自定义桶边界
    .register();

4. 在业务代码中更新指标
// 订单创建时增加计数器
void createOrder(Order order) {
    // 业务逻辑...
    ordersCreated.inc();  // 计数器+1
}

// 用户登录/登出时更新仪表盘
void userLogin(User user) {
    activeUsers.inc();  // 活跃用户+1
}

void userLogout(User user) {
    activeUsers.dec();  // 活跃用户-1
}

// 记录API响应时间
void handleRequest() {
    Histogram.Timer timer = responseTime.startTimer();
    try {
        // 处理请求...
    } finally {
        timer.observeDuration();  // 自动计算耗时
    }
}

5. 暴露指标端点
public class MetricsExporter {
    public static void main(String[] args) throws Exception {
        // 创建HTTP服务器监听9090端口
        HTTPServer server = new HTTPServer(9090);
        
        // 注册JVM默认指标(可选)
        DefaultExports.initialize();

        System.out.println("Metrics server running at http://localhost:9090/metrics");
    }
}

6. 指标元数据最佳实践
  1. 命名规范

    • 使用_total后缀表示计数器
    • 使用_seconds表示时间单位
    • 采用snake_case命名法
    • 示例:http_requests_total
  2. 标签使用

    static final Counter httpRequests = Counter.build()
        .name("http_requests_total")
        .help("HTTP requests count")
        .labelNames("method", "path", "status")  // 定义标签维度
        .register();
    
    // 使用标签
    void handleHttpRequest(String method, String path, int status) {
        httpRequests.labels(method, path, String.valueOf(status)).inc();
    }
    

7. Prometheus 配置示例

在 Prometheus 的 prometheus.yml 中添加:

scrape_configs:
  - job_name: 'java_app'
    static_configs:
      - targets: ['localhost:9090']

8. 验证指标

启动应用后访问:http://localhost:9090/metrics 将看到类似输出:

# HELP orders_created_total Total created orders
# TYPE orders_created_total counter
orders_created_total 42.0

# HELP active_users Currently active users
# TYPE active_users gauge
active_users 15.0

9. 高级用法
  1. 自定义收集器

    class CustomCollector extends Collector {
        public List<MetricFamilySamples> collect() {
            List<MetricFamilySamples> mfs = new ArrayList<>();
            // 添加自定义指标逻辑
            mfs.add(new GaugeMetricFamily("custom_metric", "Help text", 42));
            return mfs;
        }
    }
    new CustomCollector().register();
    

  2. 与 Spring Boot 集成: 添加依赖:

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
    

    application.properties 中启用端点:

    management.endpoints.web.exposure.include=prometheus
    

10. 注意事项
  1. 避免创建过多标签组合(防止基数爆炸)
  2. 指标名称全局唯一
  3. 耗时单位统一使用秒
  4. 重要指标添加告警规则:
    # alert.rules
    ALERT HighErrorRate
      IF http_requests_total{status="500"} > 100
      FOR 5m
    

通过以上步骤,即可为 Java 应用实现灵活的自定义监控指标,并通过 Prometheus 进行采集和可视化。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐