diff --git a/cmd/apiary.go b/cmd/apiary.go index 8c9abfc..2f8a2d1 100644 --- a/cmd/apiary.go +++ b/cmd/apiary.go @@ -96,7 +96,7 @@ func ActionServe(c *cli.Context) error { defer serversCancel() // Setup metrics collection - s = store.NewMetricsCollectingStore(s) + s = store.NewMetricsCollectingStore(rootCtx, s) // Setup honeypot hs, err := ssh.NewHoneypotServer(cfg.Honeypot, s) diff --git a/honeypot/ssh/store/metrics.go b/honeypot/ssh/store/metrics.go index ee2531b..374898d 100644 --- a/honeypot/ssh/store/metrics.go +++ b/honeypot/ssh/store/metrics.go @@ -1,20 +1,28 @@ package store import ( + "context" + "time" + "github.com/prometheus/client_golang/prometheus" "github.uio.no/torjus/apiary/models" ) +const tickDuration = 5 * time.Second + type MetricsCollectingStore struct { - store LoginAttemptStore + store LoginAttemptStore + attemptsCounter *prometheus.CounterVec uniqueUsernamesCount prometheus.Gauge uniquePasswordsCount prometheus.Gauge uniqueIPsCount prometheus.Gauge totalAttemptsCount prometheus.Gauge + + statsTicker *time.Ticker } -func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore { +func NewMetricsCollectingStore(ctx context.Context, store LoginAttemptStore) *MetricsCollectingStore { mcs := &MetricsCollectingStore{store: store} mcs.attemptsCounter = prometheus.NewCounterVec( @@ -59,6 +67,19 @@ func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore prometheus.MustRegister(mcs.uniqueIPsCount) prometheus.MustRegister(mcs.totalAttemptsCount) + mcs.statsTicker = time.NewTicker(tickDuration) + go func() { + defer mcs.statsTicker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-mcs.statsTicker.C: + mcs.Stats(LoginStatsTotals, 0) + } + } + }() + return mcs } @@ -75,6 +96,8 @@ func (s *MetricsCollectingStore) All() ([]models.LoginAttempt, error) { func (s *MetricsCollectingStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) { stats, err := s.store.Stats(statType, limit) if statType == LoginStatsTotals { + // Reset ticker to avoid updating twice within the duration + s.statsTicker.Reset(tickDuration) for _, element := range stats { switch element.Name { case "UniquePasswords": diff --git a/version.go b/version.go index 67ffc2f..3b862ac 100644 --- a/version.go +++ b/version.go @@ -5,7 +5,7 @@ import ( "runtime" ) -var Version = "v0.1.19" +var Version = "v0.1.20" var Build string func FullVersion() string {