diff --git a/Cargo.lock b/Cargo.lock index 4e4768ed..99a53d03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -767,6 +767,7 @@ version = "4.6.0-test.1" dependencies = [ "aes-kw", "anyhow", + "chirpstack_api", "chrono", "hex", "httpmock", diff --git a/chirpstack/src/backend/joinserver.rs b/chirpstack/src/backend/joinserver.rs index 93e972f5..e8239770 100644 --- a/chirpstack/src/backend/joinserver.rs +++ b/chirpstack/src/backend/joinserver.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, RwLock}; use anyhow::Result; use tracing::info; -use crate::config; +use crate::{config, stream}; use backend::{Client, ClientConfig}; use lrwn::{EUI64Prefix, EUI64}; @@ -28,6 +28,9 @@ pub fn setup() -> Result<()> { tls_cert: js.tls_cert.clone(), tls_key: js.tls_key.clone(), async_timeout: js.async_timeout, + request_log_fn: Some(Box::new(move |log| { + Box::pin(async move { stream::backend_interfaces::log_request(log).await }) + })), ..Default::default() })?; diff --git a/chirpstack/src/backend/roaming.rs b/chirpstack/src/backend/roaming.rs index bdb34f9c..f67058d5 100644 --- a/chirpstack/src/backend/roaming.rs +++ b/chirpstack/src/backend/roaming.rs @@ -8,8 +8,8 @@ use chrono::{Duration, DurationRound}; use prost::Message; use tracing::{debug, info, span, Level}; -use crate::config; use crate::gpstime::ToGpsTime; +use crate::{config, stream}; use backend::{Client, ClientConfig, GWInfoElement, ULMetaData}; use chirpstack_api::{common, gw}; use lrwn::{region, DevAddr, NetID, EUI64}; @@ -56,6 +56,9 @@ pub fn setup() -> Result<()> { Some(s.authorization_header.clone()) }, async_timeout: s.async_timeout, + request_log_fn: Some(Box::new(move |log| { + Box::pin(async move { stream::backend_interfaces::log_request(log).await }) + })), })?; set(&s.net_id, c); @@ -103,6 +106,9 @@ pub fn get(net_id: &NetID) -> Result> { Some(conf.roaming.default.authorization_header.clone()) }, async_timeout: conf.roaming.default.async_timeout, + request_log_fn: Some(Box::new(move |log| { + Box::pin(async move { stream::backend_interfaces::log_request(log).await }) + })), })?; return Ok(Arc::new(c)); diff --git a/chirpstack/src/cmd/configfile.rs b/chirpstack/src/cmd/configfile.rs index e2c0a664..69b84f96 100644 --- a/chirpstack/src/cmd/configfile.rs +++ b/chirpstack/src/cmd/configfile.rs @@ -273,7 +273,12 @@ pub fn run() { # # If not set, this endpoint will be disabled. bind="{{ monitoring.bind }}" - + + # Backend Interfaces log max history. + # + # This defines the max number of Backend Interface request records that will be persisted + # in Redis Streams. Setting this value to 0 disables this features. + backend_interfaces_log_max_history={{ monitoring.backend_interfaces_log_max_history }} # Meta-log max history. # diff --git a/chirpstack/src/config.rs b/chirpstack/src/config.rs index 9e695d37..481de18d 100644 --- a/chirpstack/src/config.rs +++ b/chirpstack/src/config.rs @@ -195,6 +195,7 @@ impl Default for Scheduler { pub struct Monitoring { pub bind: String, pub api_request_log_max_history: usize, + pub backend_interfaces_log_max_history: usize, pub meta_log_max_history: usize, pub gateway_frame_log_max_history: usize, pub device_frame_log_max_history: usize, @@ -215,6 +216,7 @@ impl Default for Monitoring { Monitoring { bind: "".to_string(), api_request_log_max_history: 10, + backend_interfaces_log_max_history: 10, meta_log_max_history: 10, gateway_frame_log_max_history: 10, device_frame_log_max_history: 10, diff --git a/chirpstack/src/stream/backend_interfaces.rs b/chirpstack/src/stream/backend_interfaces.rs new file mode 100644 index 00000000..80b35506 --- /dev/null +++ b/chirpstack/src/stream/backend_interfaces.rs @@ -0,0 +1,34 @@ +use anyhow::Result; +use prost::Message; +use tokio::task; + +use crate::config; +use crate::storage::{get_redis_conn, redis_key}; +use chirpstack_api::stream; + +pub async fn log_request(pl: stream::BackendInterfacesRequest) -> Result<()> { + task::spawn_blocking({ + move || -> Result<()> { + let conf = config::get(); + let mut c = get_redis_conn()?; + + if conf.monitoring.backend_interfaces_log_max_history == 0 { + return Ok(()); + } + + let key = redis_key("backend_interfaces::stream::request".to_string()); + let b = pl.encode_to_vec(); + redis::cmd("XADD") + .arg(&key) + .arg("MAXLEN") + .arg(conf.monitoring.backend_interfaces_log_max_history) + .arg("*") + .arg("request") + .arg(&b) + .query(&mut *c)?; + + Ok(()) + } + }) + .await? +} diff --git a/chirpstack/src/stream/mod.rs b/chirpstack/src/stream/mod.rs index fca3a724..54515caa 100644 --- a/chirpstack/src/stream/mod.rs +++ b/chirpstack/src/stream/mod.rs @@ -1,4 +1,5 @@ pub mod api_request; +pub mod backend_interfaces; pub mod event; pub mod frame; pub mod meta;