Add structs/logging docs, wiki/07-notes with Spew architecture, fix Home index
- src/config/structs.rs: full file header + rustdoc on every struct and field - src/logging.rs: full file header + rustdoc on init_from_config(), inline comments - wiki/07-notes.md: design notes page — Spew/no-nazi-twitter concept documented (Justin Bieber fan-out problem, KWIC moderation gate, IPFS media storage, timeline assembly tradeoffs, open questions, architecture diagram) - wiki/Home.md: corrected broken 07-broker-calls.md link; added notes section - README.md: added wiki/07-notes.md to wiki index Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,78 +1,189 @@
|
||||
//! # config/structs.rs — BEDS Configuration Structs
|
||||
//!
|
||||
//! Typed configuration structs for all sections of `beds.toml`. Every struct
|
||||
//! derives `serde::Deserialize` so the `config` crate can deserialise the
|
||||
//! merged TOML directly into strongly-typed values. No runtime string lookups.
|
||||
//!
|
||||
//! ## Calling Agents
|
||||
//! - `config/mod.rs` — deserialises into `BedsConfig` via `try_deserialize()`
|
||||
//! - All service modules — receive sub-structs as `&cfg.broker_services`, etc.
|
||||
//!
|
||||
//! **Author:** mks
|
||||
//! **Version:** 1.0
|
||||
//!
|
||||
//! ## History
|
||||
//! * `2026-04-02` - mks - original coding
|
||||
//! * `2026-04-04` - mks - added RecNodeConfig, RelNodeConfig, RelInstanceConfig
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Top-level BEDS configuration. Deserialised from the merged
|
||||
/// `beds.toml` + `env_{name}.toml` at IPL step 1.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BedsConfig {
|
||||
/// Node identity — env name, version string, wbid
|
||||
pub id: IdConfig,
|
||||
|
||||
/// Enables verbose debug output when true
|
||||
pub debug: bool,
|
||||
|
||||
/// Enables journald syslog output when true
|
||||
pub syslog: bool,
|
||||
|
||||
/// When true, log events also echo to stdout even when syslog is active
|
||||
pub syslog_mirror_console: bool,
|
||||
|
||||
/// Enables audit trail logging for all data mutations
|
||||
pub audit_on: bool,
|
||||
|
||||
/// Enables journal event recording
|
||||
pub journal_on: bool,
|
||||
|
||||
/// RabbitMQ broker connection settings
|
||||
pub broker_services: BrokerServicesConfig,
|
||||
|
||||
/// MongoDB (REC) node configs keyed by service name (e.g. "app_server")
|
||||
pub rec_services: HashMap<String, RecNodeConfig>,
|
||||
|
||||
/// MariaDB (REL) node configs keyed by service name (e.g. "app_server")
|
||||
pub rel_services: HashMap<String, RelNodeConfig>,
|
||||
}
|
||||
|
||||
/// Node identity block. Identifies this node's role and environment.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct IdConfig {
|
||||
/// Environment name — matches the env override file suffix (dev, qa, production)
|
||||
pub env_name: String,
|
||||
|
||||
/// Application version string
|
||||
pub version: String,
|
||||
|
||||
/// BEDS node identifier — unique name for this node in the cluster
|
||||
pub wbid: String,
|
||||
}
|
||||
|
||||
/// RabbitMQ broker connection settings and broker pool sizing.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BrokerServicesConfig {
|
||||
pub queue_tag : String,
|
||||
/// Queue name prefix — prepended to all queue names to isolate environments.
|
||||
/// Example: "prod_" produces queues like "prod_rec.read", "prod_log"
|
||||
pub queue_tag: String,
|
||||
|
||||
/// RabbitMQ virtual host — isolates traffic between environments
|
||||
pub vhost: String,
|
||||
|
||||
/// Timer violation threshold in seconds — broker tasks exceeding this are logged
|
||||
pub timer_violation: u32,
|
||||
|
||||
/// Maximum records transferred per AMQP message
|
||||
pub records_per_xfer: u32,
|
||||
|
||||
/// Enables TCP keepalive on the broker connection
|
||||
pub keepalive: bool,
|
||||
|
||||
/// AMQP heartbeat interval in seconds
|
||||
pub heartbeat: u32,
|
||||
|
||||
/// Enables TLS on the broker connection
|
||||
pub use_ssl: bool,
|
||||
|
||||
/// Path to TLS certificate file (only used when use_ssl is true)
|
||||
pub cert_path: String,
|
||||
|
||||
/// Connection config for the primary broker node
|
||||
pub app_server: BrokerNodeConfig,
|
||||
}
|
||||
|
||||
/// Connection and pool sizing config for a single RabbitMQ node.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BrokerNodeConfig {
|
||||
/// Broker hostname or IP address
|
||||
pub host: String,
|
||||
|
||||
/// AMQP port (default: 5672)
|
||||
pub port: u16,
|
||||
|
||||
/// RabbitMQ management API port (optional — used for health checks and admin)
|
||||
pub api_port: Option<u16>,
|
||||
|
||||
/// AMQP authentication username
|
||||
pub user: String,
|
||||
|
||||
/// AMQP authentication password
|
||||
pub pass: String,
|
||||
|
||||
/// Records per instance — used for per-broker throughput calculations
|
||||
pub rpi: u32,
|
||||
|
||||
/// Broker instance counts for this node
|
||||
pub instances: BrokerInstancesConfig,
|
||||
}
|
||||
|
||||
/// Number of concurrent broker task instances per type on a single node.
|
||||
///
|
||||
/// Each instance is a separate Tokio task. Increase these values when a node
|
||||
/// has spare CPU/memory and a queue is saturating.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct BrokerInstancesConfig {
|
||||
/// Number of read broker (rBroker) instances
|
||||
pub r_broker: u32,
|
||||
|
||||
/// Number of write broker (wBroker) instances
|
||||
pub w_broker: u32,
|
||||
|
||||
/// Number of migration/object broker (mBroker) instances
|
||||
pub m_broker: u32,
|
||||
}
|
||||
|
||||
/// Connection config for a single MongoDB (REC) node.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RecNodeConfig {
|
||||
/// MongoDB hostname or IP address
|
||||
pub host: String,
|
||||
|
||||
/// MongoDB port (default: 27017)
|
||||
pub port: u16,
|
||||
|
||||
/// Authentication username
|
||||
pub user: String,
|
||||
|
||||
/// Authentication password
|
||||
pub pass: String,
|
||||
|
||||
/// Default database name for this node
|
||||
pub database: String,
|
||||
|
||||
/// Enables TLS on the MongoDB connection
|
||||
pub use_ssl: bool,
|
||||
}
|
||||
|
||||
/// Config for a MariaDB (REL) node. A node has a required master instance
|
||||
/// and an optional secondary (read replica).
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RelNodeConfig {
|
||||
/// Primary master instance — all writes go here
|
||||
pub master: RelInstanceConfig,
|
||||
|
||||
/// Optional read replica — absence or unreachability is non-fatal
|
||||
pub secondary: Option<RelInstanceConfig>,
|
||||
}
|
||||
|
||||
/// Connection config for a single MariaDB instance (master or secondary).
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
pub struct RelInstanceConfig {
|
||||
/// MariaDB hostname or IP address
|
||||
pub host: String,
|
||||
|
||||
/// MariaDB port (default: 3306)
|
||||
pub port: u16,
|
||||
|
||||
/// Authentication username
|
||||
pub user: String,
|
||||
|
||||
/// Authentication password
|
||||
pub pass: String,
|
||||
|
||||
/// Default database name
|
||||
pub database: String,
|
||||
}
|
||||
|
||||
@@ -1,26 +1,78 @@
|
||||
//! # logging.rs — BEDS Structured Logging Initialiser
|
||||
//!
|
||||
//! Initialises the `tracing` subscriber at IPL step 2. Supports two output
|
||||
//! targets: journald (syslog) and console (stdout). Either or both may be
|
||||
//! active depending on the config flags passed in.
|
||||
//!
|
||||
//! The subscriber must be initialised before any `tracing::info!` /
|
||||
//! `tracing::warn!` / `tracing::error!` calls — the macros are no-ops until
|
||||
//! a subscriber is registered.
|
||||
//!
|
||||
//! ## Calling Agents
|
||||
//! - `ipl()` in main.rs — calls `init_from_config()` as the second IPL step
|
||||
//!
|
||||
//! ## Inputs
|
||||
//! - `syslog: bool` — from `BedsConfig.syslog`
|
||||
//! - `mirror_console: bool` — from `BedsConfig.syslog_mirror_console`
|
||||
//!
|
||||
//! ## Output Behaviour
|
||||
//! | syslog | mirror_console | journald | console |
|
||||
//! |--------|----------------|----------|---------|
|
||||
//! | false | false | — | yes |
|
||||
//! | false | true | — | yes |
|
||||
//! | true | false | yes | — |
|
||||
//! | true | true | yes | yes |
|
||||
//!
|
||||
//! **Author:** mks
|
||||
//! **Version:** 1.0
|
||||
//!
|
||||
//! ## History
|
||||
//! * `2026-04-02` - mks - original coding
|
||||
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
||||
|
||||
/// Initialises the `tracing` subscriber from BEDS config flags.
|
||||
///
|
||||
/// Registers a global subscriber with up to two output layers — journald
|
||||
/// and/or console — based on the `syslog` and `mirror_console` flags. The
|
||||
/// log level is read from the `RUST_LOG` environment variable; defaults to
|
||||
/// `info` if not set.
|
||||
///
|
||||
/// Must be called exactly once, before any tracing macros are used.
|
||||
/// Calling it a second time will panic (tracing enforces a single global
|
||||
/// subscriber).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `syslog` — enable journald output
|
||||
/// * `mirror_console` — also write to console when journald is active
|
||||
///
|
||||
/// # History
|
||||
///
|
||||
/// * `2026-04-02` - mks - original coding
|
||||
pub fn init_from_config(syslog: bool, mirror_console: bool) {
|
||||
let registry = tracing_subscriber::registry()
|
||||
.with(EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| EnvFilter::new("info")));
|
||||
|
||||
// journald layer — active when syslog is enabled in config
|
||||
let journald_layer = if syslog {
|
||||
tracing_journald::layer().ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
|
||||
// console layer — active when syslog is off, or when mirroring is on
|
||||
let console_layer = if !syslog || mirror_console {
|
||||
Some(tracing_subscriber::fmt::layer()
|
||||
.with_target(false)
|
||||
.compact())
|
||||
}else {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
|
||||
registry
|
||||
.with(journald_layer)
|
||||
.with(console_layer)
|
||||
.init();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user