From 9d7b001b7e746bd0ce10fb8ec557628b78c7729c Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Mon, 26 Jan 2026 10:01:40 -0800 Subject: [PATCH] server/json-rpc: Add request logging middleware Because of limitations in the jsonrpsee API, it's not possible to log HTTP request information and the actual JSON-RPC payload in one log message; but the two log messages should appear right next to each other. Logging both together would require a more complex upgrade to a newer jsonrpsee version. --- server/json-rpc/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/server/json-rpc/src/lib.rs b/server/json-rpc/src/lib.rs index 970bb3959d3..1bd6769f3b8 100644 --- a/server/json-rpc/src/lib.rs +++ b/server/json-rpc/src/lib.rs @@ -1,4 +1,5 @@ use graph::prelude::{Value as GraphValue, *}; +use jsonrpsee::core::middleware::{Headers, HttpMiddleware, MethodKind, Params}; use jsonrpsee::core::Error as JsonRpcError; use jsonrpsee::http_server::{HttpServerBuilder, HttpServerHandle}; use jsonrpsee::types::error::CallError; @@ -9,6 +10,43 @@ use serde_json::{self, Value as JsonValue}; use std::collections::BTreeMap; use std::net::{Ipv4Addr, SocketAddr}; +/// Middleware for logging JSON-RPC requests. +/// +/// Logs incoming HTTP requests with remote address and proxy headers, +/// and logs each JSON-RPC method call with its parameters. +#[derive(Clone)] +struct RpcLogger { + logger: Logger, +} + +impl HttpMiddleware for RpcLogger { + type Instant = (); + + fn on_request(&self, remote_addr: SocketAddr, headers: &Headers) -> Self::Instant { + info!( + &self.logger, + "JSON-RPC request"; + "remote_addr" => %remote_addr, + "x_forwarded_for" => headers.get("x-forwarded-for").and_then(|v| v.to_str().ok()), + "x_real_ip" => headers.get("x-real-ip").and_then(|v| v.to_str().ok()), + "x_forwarded_proto" => headers.get("x-forwarded-proto").and_then(|v| v.to_str().ok()) + ); + } + + fn on_call(&self, method_name: &str, params: Params, _kind: MethodKind) { + info!( + &self.logger, + "JSON-RPC call"; + "method" => method_name, + "params" => ?params + ); + } + + fn on_result(&self, _method_name: &str, _success: bool, _started_at: Self::Instant) {} + + fn on_response(&self, _result: &str, _started_at: Self::Instant) {} +} + type JsonRpcResult = Result; pub struct JsonRpcServer { @@ -43,7 +81,12 @@ impl JsonRpcServer { }; let socket_addr: SocketAddr = (Ipv4Addr::new(0, 0, 0, 0), port).into(); - let http_server = HttpServerBuilder::default().build(socket_addr).await?; + let http_server = HttpServerBuilder::default() + .set_middleware(RpcLogger { + logger: state.logger.clone(), + }) + .build(socket_addr) + .await?; let mut rpc_module = RpcModule::new(state); rpc_module