mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
Add notify threshold for app related notification
This commit is contained in:
parent
bff3dc8a27
commit
7d1f7a0d0f
2 changed files with 64 additions and 4 deletions
|
@ -52,6 +52,9 @@ func start() error {
|
|||
MaxDelay(selfcheckTaskRetryAfter).
|
||||
Schedule(time.Now().Add(selfcheckTaskRetryAfter))
|
||||
|
||||
module.NewTask("clean notify thresholds", cleanNotifyThreshold).
|
||||
Repeat(10 * time.Minute)
|
||||
|
||||
return module.RegisterEventHook(
|
||||
netenv.ModuleName,
|
||||
netenv.NetworkChangedEvent,
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/modules"
|
||||
"github.com/safing/portbase/notifications"
|
||||
"github.com/safing/portmaster/process"
|
||||
"github.com/safing/portmaster/profile"
|
||||
|
@ -124,9 +125,6 @@ func (issue *appIssue) notify(proc *process.Process) {
|
|||
proc.Path,
|
||||
)
|
||||
|
||||
// Build message.
|
||||
message := strings.ReplaceAll(issue.message, "[APPNAME]", p.Name)
|
||||
|
||||
// Check if we already have this notification.
|
||||
eventID := fmt.Sprintf(issue.id, p.ID)
|
||||
n := notifications.Get(eventID)
|
||||
|
@ -134,7 +132,15 @@ func (issue *appIssue) notify(proc *process.Process) {
|
|||
return
|
||||
}
|
||||
|
||||
// Otherwise, create a new one.
|
||||
// Check if we reach the threshold to actually send a notification.
|
||||
if !isOverThreshold(eventID) {
|
||||
return
|
||||
}
|
||||
|
||||
// Build message.
|
||||
message := strings.ReplaceAll(issue.message, "[APPNAME]", p.Name)
|
||||
|
||||
// Create a new notification.
|
||||
n = ¬ifications.Notification{
|
||||
EventID: eventID,
|
||||
Type: issue.level,
|
||||
|
@ -171,3 +177,54 @@ func (issue *appIssue) notify(proc *process.Process) {
|
|||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
notifyThresholdMinIncidents = 11
|
||||
notifyThresholdResetAfter = 2 * time.Minute
|
||||
)
|
||||
|
||||
var (
|
||||
notifyThresholds = make(map[string]*notifyThreshold)
|
||||
notifyThresholdsLock sync.Mutex
|
||||
)
|
||||
|
||||
type notifyThreshold struct {
|
||||
FirstSeen time.Time
|
||||
Incidents uint
|
||||
}
|
||||
|
||||
func (nt *notifyThreshold) expired() bool {
|
||||
return time.Now().Add(-notifyThresholdResetAfter).After(nt.FirstSeen)
|
||||
}
|
||||
|
||||
func isOverThreshold(id string) bool {
|
||||
notifyThresholdsLock.Lock()
|
||||
defer notifyThresholdsLock.Unlock()
|
||||
|
||||
// Get notify threshold and check if we reach the minimum incidents.
|
||||
nt, ok := notifyThresholds[id]
|
||||
if ok && !nt.expired() {
|
||||
nt.Incidents++
|
||||
return nt.Incidents >= notifyThresholdMinIncidents
|
||||
}
|
||||
|
||||
// Add new entry.
|
||||
notifyThresholds[id] = ¬ifyThreshold{
|
||||
FirstSeen: time.Now(),
|
||||
Incidents: 1,
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func cleanNotifyThreshold(ctx context.Context, task *modules.Task) error {
|
||||
notifyThresholdsLock.Lock()
|
||||
defer notifyThresholdsLock.Unlock()
|
||||
|
||||
for id, nt := range notifyThresholds {
|
||||
if nt.expired() {
|
||||
delete(notifyThresholds, id)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue