​https://github.com/prometheus/prometheus/blob/main/CHANGELOG.md​

在2.28.0 / 2021-06-21 这个版本里面,引入了http的动态发现



fastapi写个接口,代码如下:


main.py 

from fastapi import FastAPI,Response

app = FastAPI()

es_body = [
{
"targets":[
"172.30.11.87:9924",
"172.30.11.87:9142"
],
"labels":{
"__meta_datacenter":"nanjing",
"__meta_prometheus_job":"ElasticSearch"
}
}
]

ecs_body = [
{
"targets":[
"172.30.12.15:9100",
"172.30.12.14:9100",
],
"labels":{
"__meta_datacenter":"nanjing",
"__meta_prometheus_job":"ECS"
}
}
]

@app.get("/ecs")
async def ecs_list():
print(json.dumps(ecs_body))
return Response(content=json.dumps(ecs_body),media_type="application/json")

@app.get("/es")
async def es_list():
print(json.dumps(es_body))
return Response(content=json.dumps(es_body),media_type="application/json")


启动服务

uvicorn main:app --reload --host 0.0.0.0 --port 8000



prometheus配置如下:


$ cat prometheus.yml 
global:
scrape_interval: 15s
evaluation_interval: 15s

alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093

rule_files:
# - "first_rules.yml"
# - "second_rules.yml"

scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]

- job_name: "es"
http_sd_configs:
- url: "http://172.17.8.148:8000/es"
refresh_interval: 30s
- job_name: "ecs"
http_sd_configs:
- url: "http://172.17.8.148:8000/ecs"
refresh_interval: 30s


启动prometheus:

./prometheus --web.listen-address="0.0.0.0:9191" --log.level=


最终效果如下:

prometheus基于http的target动态发现_动态发现





上面这种写法,有个不好的地方,就是我们如果需要增加job,还是需要改prometheus的配置文件。


这里想到了一种折中的方法:

全部target都通过http sd config来自动发现,在http接口里面,我们给target加上label(类似  "__meta_prometheus_job":"ECS"),通过label来区分属于哪个job,这样就只用维护 http接口的数据准确性就可以了。 http接口数据我们可以跟 cmdb那边联动获取到(新增主机或服务会在cmdb插入记录,我们http接口服务可以定期捞最新的主机列表 然后渲染成json提供给prometheus去拉取)