如何从多个 python-flask 子进程收集普罗米修斯指标?

Sah*_*ani 6 python metrics multiple-processes python-3.x prometheus

我有 main() 函数,它生成两个单独的子进程。这两个子流程共享指标。如何共享两个流程的指标并保持更新?这是我的片段,以供更多理解。

from multiprocessing import Process
import prometheus_client as prom
from prometheus_client import Counter

# Metrics
c1 = prom.gauge('Counter1', 'Number of Request')
c2 = prom.gauge('Gauge1', 'Processing time in Seconds')

def process_abc():
  while True:
    #Some operations
    c1.set(some_value)
    c2.set(some_value)
    time.sleep(10)

def process_xyz():
   while True:
     #Some operations
     c1.set(some_value)
     c2.set(some_value)
     time.sleep(10)

def main():
  prom.start_http_server(8080)

  Process(target=process_abc).start()
  Process(target=process_xyz).start()

if __name__ == "__main__":
  main()
Run Code Online (Sandbox Code Playgroud)

我能够在端点看到指标名称,但计数始终为零意味着它永远不会被子流程更新。

Mic*_*bez 1

prometheus_client文档解决了这种情况

Prometheus 客户端库假定采用线程模型,其中指标在工作人员之间共享。这对于 Python 等语言来说效果不太好,因为在这种语言中,通常使用进程而不是线程来处理大量工作负载。

我不会在这里复制解释(针对gunicorn)用例,但基本上,您需要:

  • 定义一个包含要使用的目录的环境变量:由于您正在使用Process自己,因此可以在代码中设置它
os.environ["PROMETHEUS_MULTIPROC_DIR"] = "/path/to/writeable/tmp/"
Run Code Online (Sandbox Code Playgroud)
  • 每个进程必须有自己的收集器,在启动时注册它并在退出时注销它:
from prometheus_client import multiprocess

def called_from_process():
    registry = CollectorRegistry()
    multiprocess.MultiProcessCollector(CollectorRegistry())

def process_exit(process):
    if process.pid is not None:
        multiprocess.mark_process_dead(process.pid)

p = Process(target=f)
# f calls called_from_process
p.start()
p.join()
process_exit(process)
Run Code Online (Sandbox Code Playgroud)

请参阅有关如何处理仪表和任何其他怪癖的完整文档。

我希望PROMETHEUS_MULTIPROC_DIR在应用程序启动时清理它,以处理应用程序先前运行无法执行此操作的奇怪情况。