我在一个有几个容器的docker项目中工作,我想使用python Prometheus库来监控容器中的一些度量,在docker网络内的本地端口上公开每个容器的度量,并将它们收集到另一个名为Prometheus_exporter的容器中。
为此,我在我的FastAPI上定义了几个Prometheus度量,我想在http服务器上用PrometheusLibrary的";start_http_server";方法下面是我的API代码以及如何使用它:
api.py :在这个文件中,我定义了我的api及其端点
from prometheus_client import Counter, Histogram, start_http_server
app = FastAPI()
num_q = Counter('api_num_queries','counts number of requests sent to API', ['endpoint'])
num_err = Counter('api_num_errors','counts number of errors occurred')
latency = Histogram('api_latency', 'latency calculator')
@app.get('/userdata/{uid}')
@latency.time()
@num_err.count_exceptions()
def get_user_data(uid):
udata = redis.get(uid)
return udata
@app.get('/bookdata/{bid}')
@latency.time()
@num_err.count_exceptions()
def get_book_data(bid):
bdata = redis.get(bid)
return bdata
main.py:在这个文件中,我发布了我的API
import uvicorn
from api import app
from prometheus_client import start_http_server
if __name__ == '__main__':
uvicorn.run("main:app", host="0.0.0.0", port=8080, workers=10)
问题是,当我将start_http_server(8000)
放在main.py文件中时,如下所示:
import uvicorn
from api import app
from prometheus_client import start_http_server
if __name__ == '__main__':
start_http_server(8000)
uvicorn.run("main:app", host="0.0.0.0", port=8080, workers=10)
度量是公开的,但当度量在api.py中变化时,它们不会更新并保持在初始零值。
我尝试的另一种方法是在api.py:中使用start_http
server(8000)
from prometheus_client import Counter, Histogram, start_http_server
app = FastAPI()
num_q = Counter('api_num_queries','counts number of requests sent to API', ['endpoint'])
num_err = Counter('api_num_errors','counts number of errors occurred')
latency = Histogram('api_latency', 'latency calculator')
@app.get('/userdata/{uid}')
@latency.time()
@num_err.count_exceptions()
def get_user_data(uid):
udata = redis.get(uid)
start_http_server(8000)
return udata
@app.get('/bookdata/{bid}')
@latency.time()
@num_err.count_exceptions()
def get_book_data(bid):
bdata = redis.get(bid)
start_http_server(8000)
return bdata
这在第一次运行时很好,并且度量以其最新值公开,但当我发送新请求时,我得到"Port Already in use">错误。
我应该做什么以及如何正确地公开我的度量?
好吧,我想好了。这不是一个真正的解决方案,但它有效!出现此问题的原因是http_start_server()
命令没有自动重置或更新端口上的信息,这是prometheus_client
库的问题。
要解决此问题,您可以在API中定义一个新的metrics
端点,如下所示,并在每次发送请求时返回您的指标:
from prometheus_client import generate_latest, CollectorRegistry
metrics_reg = CollectorRegistry()
#define your metrics and specify all the metrics registrys to be metrics_reg
@app.get('/metrics')
def get_metrics():
return generate_latest(metrics_reg)
此解决方案仅适用于API模块