bestool_alertd/
lib.rs

1#![deny(rust_2018_idioms)]
2
3use std::fmt;
4
5mod alert;
6pub mod commands;
7mod daemon;
8mod events;
9mod glob_resolver;
10pub mod http_server;
11mod loader;
12mod metrics;
13
14pub mod scheduler;
15mod targets;
16pub mod templates;
17
18#[cfg(windows)]
19pub mod windows_service;
20
21pub use alert::{AlertDefinition, InternalContext, TicketSource};
22pub use daemon::{run, run_with_shutdown};
23pub use events::EventType;
24pub use targets::{AlertTargets, ExternalTarget, ResolvedTarget, SendTarget};
25
26/// The version of the alertd library
27pub const VERSION: &str = env!("CARGO_PKG_VERSION");
28
29/// Email server configuration
30#[derive(Debug, Clone)]
31pub struct EmailConfig {
32	pub from: String,
33	pub mailgun_api_key: String,
34	pub mailgun_domain: String,
35}
36
37/// Configuration for the alertd daemon
38#[derive(Debug, Clone)]
39pub struct DaemonConfig {
40	/// Glob patterns for directories/files containing alert definitions
41	///
42	/// Patterns are resolved to directories and files, and watched for changes.
43	/// On occasion, patterns are re-evaluated to pick up newly created paths.
44	pub alert_globs: Vec<String>,
45
46	/// Database connection URL
47	pub database_url: String,
48
49	/// Email server configuration
50	pub email: Option<EmailConfig>,
51
52	/// Whether to perform a dry run (execute all alerts once and quit)
53	pub dry_run: bool,
54
55	/// Whether to disable the HTTP server
56	pub no_server: bool,
57
58	/// HTTP server bind addresses
59	pub server_addrs: Vec<std::net::SocketAddr>,
60}
61
62impl DaemonConfig {
63	pub fn new(alert_globs: Vec<String>, database_url: String) -> Self {
64		Self {
65			alert_globs,
66			database_url,
67			email: None,
68			dry_run: false,
69			no_server: false,
70			server_addrs: Vec::new(),
71		}
72	}
73
74	pub fn with_email(mut self, email: EmailConfig) -> Self {
75		self.email = Some(email);
76		self
77	}
78
79	pub fn with_dry_run(mut self, dry_run: bool) -> Self {
80		self.dry_run = dry_run;
81		self
82	}
83
84	pub fn with_no_server(mut self, no_server: bool) -> Self {
85		self.no_server = no_server;
86		self
87	}
88
89	pub fn with_server_addrs(mut self, server_addrs: Vec<std::net::SocketAddr>) -> Self {
90		self.server_addrs = server_addrs;
91		self
92	}
93}
94
95/// Helper to format miette errors for logging without ANSI codes
96pub(crate) struct LogError<'a>(pub &'a miette::Report);
97
98impl fmt::Display for LogError<'_> {
99	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100		use miette::ReportHandler;
101
102		let handler = miette::NarratableReportHandler::new();
103
104		if let Err(e) = handler.debug(self.0.as_ref(), f) {
105			write!(f, "{}: {}", self.0, e)
106		} else {
107			Ok(())
108		}
109	}
110}