bestool_alertd/
lib.rs

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