separate signal-gateway binary from the library, and its deps

This commit is contained in:
Chris Beck
2025-12-05 00:46:09 -07:00
parent 028af2b7fb
commit ae26faa045
8 changed files with 85 additions and 72 deletions
Generated
+3
View File
@@ -1645,6 +1645,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
name = "signal-gateway"
version = "0.1.0"
dependencies = [
"bytes",
"chrono",
"chrono-tz",
"conf",
@@ -1652,6 +1653,8 @@ dependencies = [
"displaydoc",
"dotenvy",
"futures-util",
"http",
"http-body",
"http-body-util",
"humantime",
"hyper",
+4 -1
View File
@@ -24,6 +24,7 @@ result_large_err = "allow"
prometheus-http-client = { path = "prometheus-http-client", default-features = false }
async-trait = "0.1"
bytes = "1"
chrono = { version = "0.4", default-features = false, features = ["clock", "serde", "std"] }
chrono-tz = "0.10"
conf = "0.4"
@@ -31,6 +32,8 @@ conf-extra = "0.1"
displaydoc = "0.2"
dotenvy = "0.15"
futures-util = "0.3"
http = "1"
http-body = "1"
http-body-util = "0.1"
humantime = "2"
hyper = { version = "1.7", features = ["server", "http1", "http2"] }
@@ -43,7 +46,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
syslog_rfc5424 = "0.10"
thiserror = "2"
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "signal", "sync", "time"] }
tokio = { version = "1", features = ["io-util", "macros", "net", "rt-multi-thread", "signal", "sync", "time"] }
tokio-util = { version = "0.7", features = ["codec"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
+16 -4
View File
@@ -10,20 +10,26 @@ workspace = true
default = ["plot"]
plot = ["prometheus-http-client/plot", "dep:chrono-tz", "dep:rand", "dep:walkdir"]
rustls-tls = ["prometheus-http-client/rustls-tls"]
bin = ["dep:dotenvy", "dep:hyper", "dep:hyper-util", "dep:tracing-subscriber"]
[[bin]]
name = "signal-gateway"
path = "src/bin/main.rs"
required-features = ["bin"]
[dependencies]
prometheus-http-client = { workspace = true, default-features = false }
bytes = { workspace = true }
chrono = { workspace = true }
conf = { workspace = true }
conf-extra = { workspace = true }
displaydoc = { workspace = true }
dotenvy = { workspace = true }
futures-util = { workspace = true }
http = { workspace = true }
http-body = { workspace = true }
http-body-util = { workspace = true }
humantime = { workspace = true }
hyper = { workspace = true }
hyper-util = { workspace = true }
jsonrpsee = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
@@ -32,9 +38,15 @@ thiserror = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
url = { workspace = true }
# Optional dependencies for bin feature
dotenvy = { workspace = true, optional = true }
hyper = { workspace = true, optional = true }
hyper-util = { workspace = true, optional = true }
tracing-subscriber = { workspace = true, optional = true }
# Optional dependencies for plot feature
chrono-tz = { workspace = true, optional = true }
rand = { workspace = true, optional = true }
walkdir = { workspace = true, optional = true }
@@ -2,27 +2,60 @@ use conf::Conf;
use hyper::service::service_fn;
use hyper_util::rt::TokioIo;
use hyper_util::server::conn::auto;
use std::{str::FromStr, sync::Arc, time::Duration};
use signal_gateway::{Gateway, GatewayConfig};
use std::{net::SocketAddr, str::FromStr, sync::Arc, time::Duration};
use syslog_rfc5424::SyslogMessage;
use tokio::net::{TcpListener, UdpSocket};
use tokio_util::sync::CancellationToken;
use tracing::{error, info, warn};
use tracing_subscriber::EnvFilter;
pub mod config;
pub mod gateway;
pub mod http;
mod human_duration;
mod init_logging;
pub mod jsonrpc;
pub mod prometheus;
pub mod transports;
#[derive(Conf, Debug)]
struct Config {
/// If true, just validate config and don't start
#[conf(long)]
dry_run: bool,
/// Socket to listen for HTTP requests (GET /health, POST /alert)
#[conf(long, env, default_value = "0.0.0.0:8000")]
http_listen_addr: SocketAddr,
/// Socket to listen for UDP messages, in syslog RFC 5424 format
#[conf(long, env, default_value = "0.0.0.0:5424")]
udp_listen_addr: SocketAddr,
#[conf(flatten)]
gateway: GatewayConfig,
}
use config::Config;
use gateway::Gateway;
fn init_logging() {
// Build a default tracing subscriber, writing to STDERR
// Uses RUST_LOG env var for filtering, defaults to "info" if not set
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_file(true)
.with_line_number(true)
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
)
.init();
// load dotenv file
match dotenvy::dotenv() {
Ok(path) => info!("Read dotenv file from: {}", path.display()),
Err(dotenvy::Error::Io(io_error)) => {
if matches!(io_error.kind(), std::io::ErrorKind::NotFound) {
info!("Couldn't find a dotenv file");
} else {
panic!("Io error when reading dot env file: {io_error}")
}
}
Err(err) => {
panic!("Error reading dotenv file: {err}")
}
}
}
#[tokio::main]
async fn main() {
init_logging::init_logging();
init_logging();
let config = Config::parse();
-18
View File
@@ -1,18 +0,0 @@
use crate::gateway::GatewayConfig;
use conf::Conf;
use std::net::SocketAddr;
#[derive(Conf, Debug)]
pub struct Config {
/// If true, just validate config and don't start
#[conf(long)]
pub dry_run: bool,
/// Socket to listen for HTTP requests (GET /health, POST /alert)
#[conf(long, env, default_value = "0.0.0.0:8000")]
pub http_listen_addr: SocketAddr,
/// Socket to listen for UDP messages, in syslog RFC 5424 format
#[conf(long, env, default_value = "0.0.0.0:5424")]
pub udp_listen_addr: SocketAddr,
#[conf(flatten)]
pub gateway: GatewayConfig,
}
+9 -5
View File
@@ -3,10 +3,12 @@ use crate::{
jsonrpc::{Envelope, RpcClient, RpcClientError, SignalMessage, connect_tcp},
prometheus::{Prometheus, PrometheusConfig},
};
use bytes::Buf;
use conf::{Conf, Subcommands};
use futures_util::FutureExt;
pub use http::{Method, Request, Response, StatusCode};
use http_body::Body;
use http_body_util::BodyExt;
use hyper::{Method, Request, Response, StatusCode, body::Incoming};
use prometheus_http_client::{AlertStatus, ExtractLabels};
//use jsonrpsee::async_client::{Client as JsonRpcClient, Error as JsonRpcError};
use chrono::Utc;
@@ -393,10 +395,12 @@ impl Gateway {
}
// Handler function that processes incoming http requests (push's from alertmanager expected)
pub async fn handle_http_request(
&self,
req: Request<Incoming>,
) -> Result<Response<String>, String> {
pub async fn handle_http_request<B>(&self, req: Request<B>) -> Result<Response<String>, String>
where
B: Body + Send,
B::Data: Buf + Send,
B::Error: std::fmt::Display,
{
info!(
"Received http request: {} {} (version: {:?})",
req.method(),
-32
View File
@@ -1,32 +0,0 @@
//! Logging initialization for signal-gateway
use tracing::info;
use tracing_subscriber::EnvFilter;
pub fn init_logging() {
// Build a default tracing subscriber, writing to STDERR
// Uses RUST_LOG env var for filtering, defaults to "info" if not set
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_file(true)
.with_line_number(true)
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
)
.init();
// load dotenv file
match dotenvy::dotenv() {
Ok(path) => info!("Read dotenv file from: {}", path.display()),
Err(dotenvy::Error::Io(io_error)) => {
if matches!(io_error.kind(), std::io::ErrorKind::NotFound) {
info!("Couldn't find a dotenv file");
} else {
panic!("Io error when reading dot env file: {io_error}")
}
}
Err(err) => {
panic!("Error reading dotenv file: {err}")
}
}
}
+8
View File
@@ -0,0 +1,8 @@
pub mod gateway;
pub mod http;
pub mod human_duration;
pub mod jsonrpc;
pub mod prometheus;
pub mod transports;
pub use gateway::{Gateway, GatewayConfig};