Add more metrics

This commit is contained in:
Torjus Håkestad 2021-10-29 01:45:47 +02:00
parent e7074257b1
commit 0560e2a76c
3 changed files with 73 additions and 13 deletions

View File

@ -82,7 +82,17 @@ func ActionServe(c *cli.Context) error {
return fmt.Errorf("Invalid store configured")
}
s = store.NewMetricsCollectingStore(s)
// Setup interrupt handling
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, os.Interrupt)
rootCtx, rootCancel := context.WithCancel(c.Context)
defer rootCancel()
serversCtx, serversCancel := context.WithCancel(rootCtx)
defer serversCancel()
// Setup metrics collection
s = store.NewMetricsCollectingStore(rootCtx, s)
// Setup honeypot
hs, err := ssh.NewHoneypotServer(cfg.Honeypot, s)
@ -109,13 +119,6 @@ func ActionServe(c *cli.Context) error {
web.TLSConfig = tlsConfig
}
// Setup interrupt handling
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, os.Interrupt)
rootCtx, rootCancel := context.WithCancel(c.Context)
serversCtx, serversCancel := context.WithCancel(rootCtx)
// Setup portlistener, if configured
if cfg.Ports.Enable {
portsCtx, cancel := context.WithCancel(rootCtx)

View File

@ -1,16 +1,22 @@
package store
import (
"context"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.uio.no/torjus/apiary/models"
)
type MetricsCollectingStore struct {
store LoginAttemptStore
attemptsCounter *prometheus.CounterVec
store LoginAttemptStore
attemptsCounter *prometheus.CounterVec
uniqueUsernamesCount prometheus.Gauge
uniquePasswordsCount prometheus.Gauge
uniqueIPsCount prometheus.Gauge
}
func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore {
func NewMetricsCollectingStore(ctx context.Context, store LoginAttemptStore) *MetricsCollectingStore {
mcs := &MetricsCollectingStore{store: store}
mcs.attemptsCounter = prometheus.NewCounterVec(
@ -21,7 +27,42 @@ func NewMetricsCollectingStore(store LoginAttemptStore) *MetricsCollectingStore
},
[]string{"CountryCode"},
)
mcs.uniqueUsernamesCount = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "apiary_ssh_unique_usernames_count",
Help: "Counter of unique usernames.",
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
})
mcs.uniquePasswordsCount = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "apiary_ssh_unique_passwords_count",
Help: "Counter of unique passwords.",
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
})
mcs.uniqueIPsCount = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "apiary_ssh_unique_ips_count",
Help: "Counter of unique IPs.",
ConstLabels: prometheus.Labels{"service": "honeypot_ssh"},
})
prometheus.MustRegister(mcs.attemptsCounter)
prometheus.MustRegister(mcs.uniqueUsernamesCount)
prometheus.MustRegister(mcs.uniquePasswordsCount)
prometheus.MustRegister(mcs.uniqueIPsCount)
// Kinda jank, we just fetch the stats every 10seconds, but it should be cached most of the time.
go func(ctx context.Context) {
ticker := time.NewTicker(10 * time.Second)
select {
case <-ctx.Done():
return
case <-ticker.C:
mcs.Stats(LoginStatsTotals, 0)
}
}(ctx)
return mcs
}
@ -37,7 +78,23 @@ func (s *MetricsCollectingStore) All() ([]models.LoginAttempt, error) {
}
func (s *MetricsCollectingStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) {
return s.store.Stats(statType, limit)
stats, err := s.store.Stats(statType, limit)
if statType == LoginStatsTotals {
for _, element := range stats {
switch element.Name {
case "UniquePasswords":
s.uniquePasswordsCount.Set(float64(element.Count))
case "UniqueUsernames":
s.uniqueUsernamesCount.Set(float64(element.Count))
case "UniqueIPs":
s.uniqueIPsCount.Set(float64(element.Count))
default:
continue
}
}
}
return stats, err
}
func (s *MetricsCollectingStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {

View File

@ -5,7 +5,7 @@ import (
"runtime"
)
var Version = "v0.1.15"
var Version = "v0.1.16"
var Build string
func FullVersion() string {