Prometheus进阶

自定义http_sd_config

配置方式如下:

  - job_name: 'http_sd'
    metrics_path: "/prometheus"
    http_sd_configs:
     - url: http://localhost:8080/prometheus/endpoints

接口json格式

[
{
  "target": ["192.168.0.1:8080",...],
  "labels": {
    "__a__": "aa",
    "a": "a", ...
  }
},...
]

实现http接口(springboot)

@Slf4j
@RestController
@RequestMapping("/prometheus")
@ConditionalOnProperty(prefix = "http_sd", name = "enabled", havingValue = "true")
public class PrometheusHttpServiceDiscovery {

    private final int OFF_PORT = 0;
    @Value("${http_sd.a1.serverUrl}")
    private String a1Service;

    @Autowired
    private WorkerServerService workerServerService;

    @GetMapping("/endpoints")
    public List<NodeService> endpoints() {
        List<NodeService> services = new ArrayList<>();
        NodeService a1 = NodeService.builder().labels(new HashMap<>()).targets(Collections.singletonList(a1Service)).build();

        services.add(a1);

        List<WorkerServer> workerServerList = workerServerService.findWorkerServerList(OnlineEnum.ONLINE, null);
        NodeService bCluster = NodeService.builder().labels(new HashMap<>()).targets(
                        service.stream().map(ws -> ws.getIp() + ":" + (ws.getPort() + OFF_PORT)).collect(Collectors.toList()))
                .build();

        services.add(bCluster );

        log.info("refresh tick services info: {}", services);
        return services;
    }
}

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
class NodeService {
    private List<String> targets;
    private Map<String, String> labels;
}

application.yaml

http_sd.enabled = true
http_sd.a1.serverUrl = localhost:9001

标签重置每个目标的metrics_path

配置方式如下:

scrape_configs:
- job_name: 'file_sd' 
  file_sd_configs:
  - files: 
    - targets.json
  relabel_configs:
  - source_labels: [__address__]
    regex: (http://)([^:]+)
    target_label: __address__ 
    replacement: http://${2}
  - source_labels: [__port__] 
    regex: (\d+)
    target_label: __port__
    replacement: ':${1}'   
  - source_labels: [__module__] 
    regex: ([a-z0-9-]+)  
    target_label: __module__
    replacement: /${1}
  - source_labels: [__module__]
    target_label: metrics_path

这里:

  • 通过前 3 个 relabel_config 从 addressport 标签生成 host 和 port
  • module 标签的值通过最后一个 relabel_config 直接作为 metrics_path
  • 所以 module 标签的值会覆盖通过 regex 生成的默认路径
    例如,targets.json 中有以下目标:
[
  {
    "targets": ["http://host1:9090"],
    "labels": {
      "__module__": "app1" 
    }
  },
  {
    "targets": ["http://host2:9091"],
    "labels": {
      "__module__": "app2"
    }
  }
]

那么 Prometheus 最终会使用以下 metrics_path:

  • /app1
  • /app2
    因为 module 标签的值会直接作为 metrics_path,覆盖 regex 生成的默认值。

具体我的配置示例:
JSON文件中:

[
  {
    "targets": [
      "127.0.0.1:8080"
    ],
    "labels": {
      "module": "customer"
    }
  },
  {
    "targets": [
      "127.0.0.1:8081"
    ],
    "labels": {
      "module": "web"
    }
  }
 ]

Prometheus中scrape_configs中配置file_sd_config:

scrape_configs:
  - job_name: 'App-service_job'
    file_sd_configs:
      - files:
          - /xxx/targets.json
    relabel_configs:
      - target_label: __metrics_path__
        source_labels: [module]
        replacement: /${1}/actuator/prometheus

source_labels: 源标签名称 [module]是用于获取JSON文件中配置目标的标签“target”
target_label:目标标签名称
replacement:替换值