21#include <unordered_map>
93 std::lock_guard<std::mutex> lock(
mutex_);
96 auto now = std::chrono::steady_clock::now();
98 auto it =
groups_.find(group_key);
103 groups_[group_key] = std::move(new_group);
107 bool is_duplicate =
false;
108 for (
auto& existing : it->second.alerts) {
116 it->second.add_alert(a);
128 std::lock_guard<std::mutex> lock(
mutex_);
130 std::vector<alert_group> ready;
131 auto now = std::chrono::steady_clock::now();
133 for (
auto& [key, group] :
groups_) {
152 ready.push_back(group);
163 std::lock_guard<std::mutex> lock(
mutex_);
164 last_sent_[group_key] = std::chrono::steady_clock::now();
171 std::lock_guard<std::mutex> lock(
mutex_);
173 auto now = std::chrono::steady_clock::now();
176 auto& group = it->second;
179 auto alert_it = group.alerts.begin();
180 while (alert_it != group.alerts.end()) {
182 auto resolved_time = alert_it->resolved_at.value_or(now);
184 alert_it = group.alerts.erase(alert_it);
206 std::lock_guard<std::mutex> lock(
mutex_);
214 std::lock_guard<std::mutex> lock(
mutex_);
216 for (
const auto& [key, group] :
groups_) {
217 count += group.size();
240 common.
set(label, val);
249 std::unordered_map<std::string, alert_group>
groups_;
250 std::unordered_map<std::string, std::chrono::steady_clock::time_point>
first_seen_;
251 std::unordered_map<std::string, std::chrono::steady_clock::time_point>
last_sent_;
296 for (
const auto& label :
equal) {
336 std::lock_guard<std::mutex> lock(
mutex_);
344 std::lock_guard<std::mutex> lock(
mutex_);
359 const std::vector<alert>& active_alerts)
const {
360 std::lock_guard<std::mutex> lock(
mutex_);
362 for (
const auto& rule :
rules_) {
363 for (
const auto& source : active_alerts) {
370 if (source.fingerprint() == target.
fingerprint()) {
374 if (rule.should_inhibit(source, target)) {
387 std::lock_guard<std::mutex> lock(
mutex_);
417 std::lock_guard<std::mutex> lock(
mutex_);
424 auto now = std::chrono::steady_clock::now();
426 return (now - it->second) < cooldown;
434 std::lock_guard<std::mutex> lock(
mutex_);
444 std::chrono::milliseconds cooldown) {
445 std::lock_guard<std::mutex> lock(
mutex_);
455 std::lock_guard<std::mutex> lock(
mutex_);
459 return std::chrono::milliseconds::zero();
462 auto now = std::chrono::steady_clock::now();
464 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
467 if (elapsed >= cooldown) {
468 return std::chrono::milliseconds::zero();
470 return cooldown - elapsed;
477 std::lock_guard<std::mutex> lock(
mutex_);
485 std::lock_guard<std::mutex> lock(
mutex_);
526 std::lock_guard<std::mutex> lock(
mutex_);
531 auto it =
seen_.find(fingerprint);
533 if (it ==
seen_.end()) {
534 seen_[fingerprint] = std::chrono::steady_clock::now();
553 std::lock_guard<std::mutex> lock(
mutex_);
555 seen_[fingerprint] = std::chrono::steady_clock::now();
563 std::lock_guard<std::mutex> lock(
mutex_);
570 auto now = std::chrono::steady_clock::now();
571 for (
auto it =
seen_.begin(); it !=
seen_.end(); ) {
574 it =
seen_.erase(it);
583 std::unordered_map<std::string, std::chrono::steady_clock::time_point>
seen_;
605 virtual std::string
name()
const = 0;
621 stages_.push_back(std::move(stage));
630 for (
const auto& stage :
stages_) {
631 if (!stage->process(a)) {
642 std::vector<std::string> names;
644 for (
const auto& stage :
stages_) {
645 names.push_back(stage->name());
651 std::vector<std::shared_ptr<pipeline_stage>>
stages_;
Core alert data structures for the monitoring system.
Groups and deduplicates alerts.
size_t group_count() const
Get current group count.
void cleanup()
Remove resolved alerts and clean up old groups.
std::string add_alert(const alert &a)
Add an alert for aggregation.
void mark_sent(const std::string &group_key)
Mark a group as sent.
alert_labels extract_common_labels(const alert &a) const
std::string compute_group_key(const alert &a) const
std::unordered_map< std::string, std::chrono::steady_clock::time_point > first_seen_
std::unordered_map< std::string, alert_group > groups_
alert_aggregator(const alert_aggregator_config &config)
Construct with configuration.
std::unordered_map< std::string, std::chrono::steady_clock::time_point > last_sent_
std::vector< alert_group > get_ready_groups()
Get groups ready for notification.
alert_aggregator_config config_
size_t total_alert_count() const
Get total alert count across all groups.
Deduplicates alerts based on fingerprint.
std::unordered_map< std::string, alert_state > last_state_
bool is_duplicate(const alert &a)
Check if alert is a duplicate.
void mark_seen(const alert &a)
Mark alert as seen.
std::chrono::milliseconds cache_duration_
alert_deduplicator(std::chrono::milliseconds cache_duration)
Construct with cache duration.
std::unordered_map< std::string, std::chrono::steady_clock::time_point > seen_
void reset()
Clear deduplication cache.
Manages alert inhibition rules.
void remove_rule(const std::string &name)
Remove an inhibition rule by name.
bool is_inhibited(const alert &target, const std::vector< alert > &active_alerts) const
Check if an alert is inhibited by any active alerts.
void add_rule(const inhibition_rule &rule)
Add an inhibition rule.
std::vector< inhibition_rule > get_rules() const
Get all rules.
std::vector< inhibition_rule > rules_
Configurable alert processing pipeline.
void add_stage(std::shared_ptr< pipeline_stage > stage)
Add a processing stage.
bool process(alert &a)
Process an alert through all stages.
std::vector< std::shared_ptr< pipeline_stage > > stages_
std::vector< std::string > stage_names() const
Get stage names.
Tracks cooldown periods for alert notifications.
void record_notification(const std::string &fingerprint)
Record notification time.
bool is_in_cooldown(const std::string &fingerprint) const
Check if alert is in cooldown.
cooldown_tracker(std::chrono::milliseconds default_cooldown)
Set default cooldown period.
std::chrono::milliseconds default_cooldown_
std::unordered_map< std::string, std::chrono::steady_clock::time_point > last_notification_
void reset()
Clear all cooldown state.
std::unordered_map< std::string, std::chrono::milliseconds > custom_cooldowns_
std::chrono::milliseconds get_cooldown_for(const std::string &fingerprint) const
std::chrono::milliseconds remaining_cooldown(const std::string &fingerprint) const
Get time remaining in cooldown.
void clear_cooldown(const std::string &fingerprint)
Clear cooldown state for an alert.
void set_cooldown(const std::string &fingerprint, std::chrono::milliseconds cooldown)
Set custom cooldown for specific alert.
Base class for pipeline processing stages.
virtual bool process(alert &a)=0
Process an alert through this stage.
virtual ~pipeline_stage()=default
virtual std::string name() const =0
Get stage name.
@ firing
Alert is active and notifications sent.
@ resolved
Alert condition cleared.
Result pattern type definitions for monitoring system.
Configuration for alert aggregation.
std::chrono::milliseconds group_interval
Interval between group sends.
std::chrono::milliseconds group_wait
Initial wait before sending.
std::chrono::milliseconds resolve_timeout
Time before removing resolved.
std::vector< std::string > group_by_labels
Labels to group by.
bool validate() const
Validate configuration.
Group of related alerts for batch notification.
alert_labels common_labels
Labels shared by all alerts.
void add_alert(alert a)
Add an alert to the group.
Key-value labels for alert identification and routing.
std::unordered_map< std::string, std::string > labels
void set(const std::string &key, const std::string &value)
Add or update a label.
std::string get(const std::string &key) const
Get a label value.
Core alert data structure.
alert_state state
Current state.
std::string rule_name
Name of triggering rule.
alert_labels labels
Identifying labels.
std::string fingerprint() const
Get alert fingerprint for deduplication.
Rule for inhibiting alerts based on other alerts.
std::vector< std::string > equal
Labels that must be equal on both.
bool should_inhibit(const alert &source, const alert &target) const
Check if target alert should be inhibited by source.
alert_labels target_match
Labels that target alert must have.
bool matches_source(const alert &a) const
Check if source alert matches this rule.
alert_labels source_match
Labels that source alert must have.