Use metrics

This commit is contained in:
Daniel
2021-01-28 17:45:52 +01:00
parent ee9ee3dc68
commit c9b89ef2ea
13 changed files with 289 additions and 6 deletions

View File

@@ -147,6 +147,9 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
// profile and required for correct re-evaluation of a connections
// verdict.
ProfileRevisionCounter uint64
// addedToMetrics signifies if the connection has already been counted in
// the metrics.
addedToMetrics bool
}
// Reason holds information justifying a verdict, as well as additional
@@ -449,6 +452,7 @@ func (conn *Connection) SaveWhenFinished() {
// Callers must make sure to lock the connection itself before calling
// Save().
func (conn *Connection) Save() {
conn.addToMetrics()
conn.UpdateMeta()
if !conn.KeyIsSet() {

View File

@@ -55,3 +55,24 @@ func (cs *connectionStore) clone() map[string]*Connection {
}
return m
}
func (cs *connectionStore) len() int {
cs.rw.RLock()
defer cs.rw.RUnlock()
return len(cs.items)
}
func (cs *connectionStore) active() int {
// Clone and count all active connections.
var cnt int
for _, conn := range cs.clone() {
conn.Lock()
if conn.Ended != 0 {
cnt++
}
conn.Unlock()
}
return cnt
}

143
network/metrics.go Normal file
View File

@@ -0,0 +1,143 @@
package network
import (
"github.com/safing/portbase/api"
"github.com/safing/portbase/config"
"github.com/safing/portbase/metrics"
)
var (
blockedOutConnCounter *metrics.Counter
encryptedAndTunneledOutConnCounter *metrics.Counter
encryptedOutConnCounter *metrics.Counter
tunneledOutConnCounter *metrics.Counter
outConnCounter *metrics.Counter
)
func registerMetrics() error {
_, err := metrics.NewGauge(
"network/connections/active/total",
nil,
func() float64 {
return float64(conns.active())
},
&metrics.Options{
Permission: api.PermitUser,
ExpertiseLevel: config.ExpertiseLevelUser,
})
if err != nil {
return err
}
connCounterID := "network/connections/total"
connCounterOpts := &metrics.Options{
Name: "Connections",
Permission: api.PermitUser,
ExpertiseLevel: config.ExpertiseLevelUser,
Persist: true,
}
blockedOutConnCounter, err = metrics.NewCounter(
connCounterID,
map[string]string{
"direction": "out",
"blocked": "true",
},
connCounterOpts,
)
if err != nil {
return err
}
encryptedAndTunneledOutConnCounter, err = metrics.NewCounter(
connCounterID,
map[string]string{
"direction": "out",
"encrypted": "true",
"tunneled": "true",
},
connCounterOpts,
)
if err != nil {
return err
}
encryptedOutConnCounter, err = metrics.NewCounter(
connCounterID,
map[string]string{
"direction": "out",
"encrypted": "true",
},
connCounterOpts,
)
if err != nil {
return err
}
tunneledOutConnCounter, err = metrics.NewCounter(
connCounterID,
map[string]string{
"direction": "out",
"tunneled": "true",
},
connCounterOpts,
)
if err != nil {
return err
}
outConnCounter, err = metrics.NewCounter(
connCounterID,
map[string]string{
"direction": "out",
},
connCounterOpts,
)
if err != nil {
return err
}
return nil
}
func (conn *Connection) addToMetrics() {
if conn.addedToMetrics {
return
}
// Only count outgoing connections for now.
if conn.Inbound {
return
}
// Check the verdict.
switch conn.Verdict {
case VerdictBlock, VerdictDrop:
blockedOutConnCounter.Inc()
conn.addedToMetrics = true
return
case VerdictAccept:
// Continue to next section.
default:
// Connection is not counted.
return
}
// Only count successful connections, not DNS requests.
if conn.ID == "" {
return
}
// Select counter based on attributes.
switch {
case conn.Encrypted && conn.Tunneled:
encryptedAndTunneledOutConnCounter.Inc()
case conn.Encrypted:
encryptedOutConnCounter.Inc()
case conn.Tunneled:
tunneledOutConnCounter.Inc()
default:
outConnCounter.Inc()
}
conn.addedToMetrics = true
}

View File

@@ -11,7 +11,7 @@ var (
)
func init() {
module = modules.Register("network", nil, start, nil, "base", "processes")
module = modules.Register("network", prep, start, nil, "base", "processes")
}
// SetDefaultFirewallHandler sets the default firewall handler.
@@ -21,6 +21,10 @@ func SetDefaultFirewallHandler(handler FirewallHandler) {
}
}
func prep() error {
return registerMetrics()
}
func start() error {
err := registerAsDatabase()
if err != nil {