From 394c955031828ccc399108d33ec38139dc164ec3 Mon Sep 17 00:00:00 2001 From: Killian Delarue Date: Fri, 16 Sep 2022 14:17:39 +0200 Subject: [PATCH 1/2] Node, lib_rpc_http: Add rpc_metrics_transform_callback to RPC_metrics --- src/bin_node/node_run_command.ml | 35 +++++++---------------------- src/lib_rpc_http/RPC_middleware.ml | 25 +++++++++++++++++++++ src/lib_rpc_http/RPC_middleware.mli | 14 +++++++++++- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/bin_node/node_run_command.ml b/src/bin_node/node_run_command.ml index 3a2aecd57ac3..1829e1aea3fe 100644 --- a/src/bin_node/node_run_command.ml +++ b/src/bin_node/node_run_command.ml @@ -366,7 +366,7 @@ let sanitize_cors_headers ~default headers = |> String.Set.(union (of_list default)) |> String.Set.elements -let metric = +let rpc_metrics = Prometheus.Summary.v_labels ~label_names:["endpoint"; "method"] ~help:"RPC endpoint call counts and sum of execution times." @@ -404,31 +404,6 @@ let launch_rpc_server ~acl_policy ~media_types (config : Node_config_file.t) let cors_headers = sanitize_cors_headers ~default:["Content-Type"] rpc_config.cors_headers in - let transform_callback callback connection request body = - let open Lwt_result_syntax in - let do_call () = callback connection request body in - let cohttp_meth = Cohttp.Request.meth request in - let uri = Cohttp.Request.uri request in - let path = Uri.path uri in - let decoded = Resto.Utils.decode_split_path path in - let*! description = - let* resto_meth = - match cohttp_meth with - | #Resto.meth as meth -> Lwt.return_ok meth - | _ -> Lwt.return_error @@ `Method_not_allowed [] - in - let* uri_desc = RPC_directory.lookup_uri_desc dir () resto_meth decoded in - Lwt.return_ok (uri_desc, Resto.string_of_meth resto_meth) - in - match description with - | Ok (uri, meth) -> - (* We update the metric only if the URI can succesfully - be matched in the directory tree. *) - Prometheus.Summary.(time (labels metric [uri; meth]) Sys.time do_call) - | Error _ -> - (* Otherwise, the call must be done anyway. *) - do_call () - in let cors = RPC_server. { @@ -443,7 +418,13 @@ let launch_rpc_server ~acl_policy ~media_types (config : Node_config_file.t) ~media_types:(Media_type.Command_line.of_command_line media_types) dir in - let callback = transform_callback (RPC_server.resto_callback server) in + let update_metrics uri meth = + Prometheus.Summary.(time (labels rpc_metrics [uri; meth]) Sys.time) + in + let callback = + RPC_middleware.rpc_metrics_transform_callback ~update_metrics dir + @@ RPC_server.resto_callback server + in Lwt.catch (fun () -> let*! () = RPC_server.launch ~host server ~callback mode in diff --git a/src/lib_rpc_http/RPC_middleware.ml b/src/lib_rpc_http/RPC_middleware.ml index 90b5b197b0eb..c5b83ca54d85 100644 --- a/src/lib_rpc_http/RPC_middleware.ml +++ b/src/lib_rpc_http/RPC_middleware.ml @@ -46,5 +46,30 @@ let make_transform_callback forwarding_endpoint callback conn req body = overriding) )) else Lwt.return answer +let rpc_metrics_transform_callback ~update_metrics dir callback conn req body = + let open Lwt_result_syntax in + let do_call () = callback conn req body in + let cohttp_meth = Cohttp.Request.meth req in + let uri = Cohttp.Request.uri req in + let path = Uri.path uri in + let decoded = Resto.Utils.decode_split_path path in + let*! description = + let* resto_meth = + match cohttp_meth with + | #Resto.meth as meth -> Lwt.return_ok meth + | _ -> Lwt.return_error @@ `Method_not_allowed [] + in + let* uri_desc = RPC_directory.lookup_uri_desc dir () resto_meth decoded in + Lwt.return_ok (uri_desc, Resto.string_of_meth resto_meth) + in + match description with + | Ok (uri, meth) -> + (* We update the metric only if the URI can succesfully + be matched in the directory tree. *) + update_metrics uri meth do_call + | Error _ -> + (* Otherwise, the call must be done anyway. *) + do_call () + let proxy_server_query_forwarder forwarding_endpoint = make_transform_callback forwarding_endpoint diff --git a/src/lib_rpc_http/RPC_middleware.mli b/src/lib_rpc_http/RPC_middleware.mli index 405721b22cf9..1906081cb469 100644 --- a/src/lib_rpc_http/RPC_middleware.mli +++ b/src/lib_rpc_http/RPC_middleware.mli @@ -26,8 +26,20 @@ (** This module provides middlewares that is used by the RPC servers to forward unsupported RPCs to a full node. *) -(** A Resto middleware that transform any callback to an other +(** A Resto middleware that transforms any callback to an other that rewrites queries that the proxy server cannot handle and forwards them to the full node at the given [Uri.t]. *) val proxy_server_query_forwarder : Uri.t -> RPC_server.callback -> RPC_server.callback + +(** A Resto middleware that transforms any server callback to an other + that handles RPC metrics *) +val rpc_metrics_transform_callback : + update_metrics: + (string -> + string -> + (unit -> Cohttp_lwt_unix.Server.response_action Lwt.t) -> + Cohttp_lwt_unix.Server.response_action Lwt.t) -> + unit RPC_directory.t -> + RPC_server.callback -> + RPC_server.callback -- GitLab From a1b807536a6d26806fd80596a5bff4ae48d4ac1e Mon Sep 17 00:00:00 2001 From: Killian Delarue Date: Thu, 13 Oct 2022 15:53:03 +0200 Subject: [PATCH 2/2] Node: Metrics in rpc server --- src/bin_node/node_run_command.ml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/bin_node/node_run_command.ml b/src/bin_node/node_run_command.ml index 1829e1aea3fe..1f67c659f6d8 100644 --- a/src/bin_node/node_run_command.ml +++ b/src/bin_node/node_run_command.ml @@ -374,6 +374,8 @@ let rpc_metrics = ~subsystem:"rpc" "calls" +module Metrics_server = Prometheus_app.Cohttp (Cohttp_lwt_unix.Server) + let launch_rpc_server ~acl_policy ~media_types (config : Node_config_file.t) node (addr, port) = let open Lwt_result_syntax in @@ -418,12 +420,18 @@ let launch_rpc_server ~acl_policy ~media_types (config : Node_config_file.t) ~media_types:(Media_type.Command_line.of_command_line media_types) dir in + let callback (conn : Cohttp_lwt_unix.Server.conn) req body = + let path = Cohttp_lwt.Request.uri req |> Uri.path in + if path = "/metrics" then + let*! response = Metrics_server.callback conn req body in + Lwt.return (`Response response) + else Tezos_rpc_http_server.RPC_server.resto_callback server conn req body + in let update_metrics uri meth = Prometheus.Summary.(time (labels rpc_metrics [uri; meth]) Sys.time) in let callback = - RPC_middleware.rpc_metrics_transform_callback ~update_metrics dir - @@ RPC_server.resto_callback server + RPC_middleware.rpc_metrics_transform_callback ~update_metrics dir callback in Lwt.catch (fun () -> @@ -455,8 +463,6 @@ let init_rpc (config : Node_config_file.t) node = addrs) config.rpc.listen_addrs -module Metrics_server = Prometheus_app.Cohttp (Cohttp_lwt_unix.Server) - let metrics_serve metrics_addrs = let open Lwt_result_syntax in let* addrs = -- GitLab