Use metrics
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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
143
network/metrics.go
Normal 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
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user