mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-11 02:58:49 +00:00
feat(lib/policy/expressions): add system load average to bot expression inputs (#766)
* feat(lib/policy/expressions): add system load average to bot expression inputs This lets Anubis dynamically react to system load in order to increase and decrease the required level of scrutiny. High load? More scrutiny required. Low load? Less scrutiny required. * docs: spell system correctly Signed-off-by: Xe Iaso <me@xeiaso.net> * Update metadata check-spelling run (pull_request) for Xe/load-average Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com> on-behalf-of: @check-spelling <check-spelling-bot@check-spelling.dev> * fix(default-config): don't enable low load average feature by default Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com> Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
This commit is contained in:
@@ -73,6 +73,12 @@ func (cr *CELRequest) ResolveName(name string) (any, bool) {
|
||||
return expressions.URLValues{Values: cr.URL.Query()}, true
|
||||
case "headers":
|
||||
return expressions.HTTPHeaders{Header: cr.Header}, true
|
||||
case "load_1m":
|
||||
return expressions.Load1(), true
|
||||
case "load_5m":
|
||||
return expressions.Load5(), true
|
||||
case "load_15m":
|
||||
return expressions.Load15(), true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ func BotEnvironment() (*cel.Env, error) {
|
||||
cel.Variable("path", cel.StringType),
|
||||
cel.Variable("query", cel.MapType(cel.StringType, cel.StringType)),
|
||||
cel.Variable("headers", cel.MapType(cel.StringType, cel.StringType)),
|
||||
cel.Variable("load_1m", cel.DoubleType),
|
||||
cel.Variable("load_5m", cel.DoubleType),
|
||||
cel.Variable("load_15m", cel.DoubleType),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
69
lib/policy/expressions/loadavg.go
Normal file
69
lib/policy/expressions/loadavg.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package expressions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/load"
|
||||
)
|
||||
|
||||
type loadAvg struct {
|
||||
lock sync.RWMutex
|
||||
data *load.AvgStat
|
||||
}
|
||||
|
||||
func (l *loadAvg) updateThread(ctx context.Context) {
|
||||
ticker := time.NewTicker(15 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
l.update()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
l.update()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *loadAvg) update() {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
var err error
|
||||
l.data, err = load.Avg()
|
||||
if err != nil {
|
||||
slog.Debug("can't get load average", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
globalLoadAvg *loadAvg
|
||||
)
|
||||
|
||||
func init() {
|
||||
globalLoadAvg = &loadAvg{}
|
||||
go globalLoadAvg.updateThread(context.Background())
|
||||
}
|
||||
|
||||
func Load1() float64 {
|
||||
globalLoadAvg.lock.RLock()
|
||||
defer globalLoadAvg.lock.RUnlock()
|
||||
return globalLoadAvg.data.Load1
|
||||
}
|
||||
|
||||
func Load5() float64 {
|
||||
globalLoadAvg.lock.RLock()
|
||||
defer globalLoadAvg.lock.RUnlock()
|
||||
return globalLoadAvg.data.Load5
|
||||
}
|
||||
|
||||
func Load15() float64 {
|
||||
globalLoadAvg.lock.RLock()
|
||||
defer globalLoadAvg.lock.RUnlock()
|
||||
return globalLoadAvg.data.Load15
|
||||
}
|
||||
Reference in New Issue
Block a user