[Stats] Basic Metrics Infrastructure (Metrics Agent + Prometheus Exporter) (#9607)

This commit is contained in:
SangBin Cho
2020-07-28 10:28:01 -07:00
committed by GitHub
parent feb3751824
commit 7e3ba289dc
18 changed files with 868 additions and 289 deletions
+30 -6
View File
@@ -10,13 +10,17 @@ import platform
import subprocess
import sys
from concurrent import futures
import ray
import psutil
import ray.ray_constants as ray_constants
import ray.services
import ray.utils
from ray.core.generated import reporter_pb2
from ray.core.generated import reporter_pb2_grpc
from ray.dashboard.util import get_unused_port
from ray.metrics_agent import MetricsAgent
# Logger for this module. It should be configured at the entry point
# into the program using Ray. Ray provides a default configuration at
@@ -32,8 +36,8 @@ except ImportError:
class ReporterServer(reporter_pb2_grpc.ReporterServiceServicer):
def __init__(self):
pass
def __init__(self, metrics_agent):
self.metrics_agent = metrics_agent
def GetProfilingStats(self, request, context):
pid = request.pid
@@ -56,8 +60,22 @@ class ReporterServer(reporter_pb2_grpc.ReporterServiceServicer):
profiling_stats=profiling_stats, std_out=stdout, std_err=stderr)
def ReportMetrics(self, request, context):
# TODO(sang): Process metrics here.
return reporter_pb2.ReportMetricsReply()
# NOTE: Exceptions are not propagated properly
# when we don't catch them here.
try:
metrcs_description_required = (
self.metrics_agent.record_metrics_points(
request.metrics_points))
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())
# If metrics description is missing, we should notify cpp processes
# that we need them. Cpp processes will then report them to here.
# We need it when (1) a new metric is reported (application metric)
# (2) a reporter goes down and restarted (currently not implemented).
return reporter_pb2.ReportMetricsReply(
metrcs_description_required=metrcs_description_required)
def recursive_asdict(o):
@@ -104,6 +122,11 @@ class Reporter:
self.ip = ray.services.get_node_ip_address()
self.hostname = platform.node()
self.port = port
metrics_agent_port = os.getenv("METRICS_AGENT_PORT")
if not metrics_agent_port:
metrics_agent_port = get_unused_port()
self.metrics_agent = MetricsAgent(metrics_agent_port)
self.reporter_grpc_server = ReporterServer(self.metrics_agent)
_ = psutil.cpu_percent() # For initialization
@@ -225,13 +248,14 @@ class Reporter:
)
def run(self):
"""Publish the port."""
thread_pool = futures.ThreadPoolExecutor(max_workers=10)
server = grpc.server(thread_pool, options=(("grpc.so_reuseport", 0), ))
reporter_pb2_grpc.add_ReporterServiceServicer_to_server(
ReporterServer(), server)
self.reporter_grpc_server, server)
port = server.add_insecure_port("[::]:{}".format(self.port))
server.start()
# Publish the port.
self.redis_client.set("REPORTER_PORT:{}".format(self.ip), port)
"""Run the reporter."""
while True: