Skip to content

Commit 8c5cc3e

Browse files
aaurenmrueg
authored andcommitted
feat(route_sync): add metrics
1 parent da6ef9b commit 8c5cc3e

File tree

4 files changed

+57
-4
lines changed

4 files changed

+57
-4
lines changed

pkg/controllers/routing/network_routes_controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
12891289
nrc.bgpServerStarted = false
12901290
nrc.disableSrcDstCheck = kubeRouterConfig.DisableSrcDstCheck
12911291
nrc.initSrcDstCheckDone = false
1292-
nrc.routeSyncer = routes.NewRouteSyncer(kubeRouterConfig.InjectedRoutesSyncPeriod)
1292+
nrc.routeSyncer = routes.NewRouteSyncer(kubeRouterConfig.InjectedRoutesSyncPeriod, kubeRouterConfig.MetricsEnabled)
12931293

12941294
nrc.bgpHoldtime = kubeRouterConfig.BGPHoldTime.Seconds()
12951295
if nrc.bgpHoldtime > 65536 || nrc.bgpHoldtime < 3 {

pkg/metrics/metrics_controller.go

+24
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,30 @@ var (
209209
Name: "controller_policy_ipsets",
210210
Help: "Active policy ipsets",
211211
})
212+
// ControllerHostRoutesSyncTime Time it took for the host routes controller to sync to the system
213+
ControllerHostRoutesSyncTime = prometheus.NewHistogram(prometheus.HistogramOpts{
214+
Namespace: namespace,
215+
Name: "host_routes_sync_time",
216+
Help: "Time it took for the host routes controller to sync to the system",
217+
})
218+
// ControllerHostRoutesSynced Number of host routes currently synced to the system
219+
ControllerHostRoutesSynced = prometheus.NewGauge(prometheus.GaugeOpts{
220+
Namespace: namespace,
221+
Name: "host_routes_synced",
222+
Help: "Count of host routes currently synced to the system",
223+
})
224+
// ControllerHostRoutesSynced Number of host routes added to the system
225+
ControllerHostRoutesAdded = prometheus.NewCounter(prometheus.CounterOpts{
226+
Namespace: namespace,
227+
Name: "host_routes_added",
228+
Help: "Total count of host routes added to the system",
229+
})
230+
// ControllerHostRoutesSynced Number of host routes removed to the system
231+
ControllerHostRoutesRemoved = prometheus.NewCounter(prometheus.CounterOpts{
232+
Namespace: namespace,
233+
Name: "host_routes_removed",
234+
Help: "Total count of host routes removed to the system",
235+
})
212236
)
213237

214238
// Controller Holds settings for the metrics controller

pkg/routes/route_sync.go

+30-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"time"
88

99
"github.com./cloudnativelabs/kube-router/v2/pkg/healthcheck"
10+
"github.com./cloudnativelabs/kube-router/v2/pkg/metrics"
11+
"github.com./prometheus/client_golang/prometheus"
1012
"github.com./vishvananda/netlink"
1113
"k8s.io/klog/v2"
1214
)
@@ -26,6 +28,7 @@ type RouteSync struct {
2628
injectedRoutesSyncPeriod time.Duration
2729
mutex sync.Mutex
2830
routeReplacer func(route *netlink.Route) error
31+
metricsEnabled bool
2932
}
3033

3134
// addInjectedRoute adds a route to the route map that is regularly synced to the kernel's routing table
@@ -34,6 +37,10 @@ func (rs *RouteSync) AddInjectedRoute(dst *net.IPNet, route *netlink.Route) {
3437
defer rs.mutex.Unlock()
3538
klog.V(3).Infof("Adding route for destination: %s", dst)
3639
rs.routeTableStateMap[dst.String()] = route
40+
if rs.metricsEnabled {
41+
metrics.ControllerHostRoutesAdded.Inc()
42+
metrics.ControllerHostRoutesSynced.Set(float64(len(rs.routeTableStateMap)))
43+
}
3744
}
3845

3946
// delInjectedRoute delete a route from the route map that is regularly synced to the kernel's routing table
@@ -44,10 +51,21 @@ func (rs *RouteSync) DelInjectedRoute(dst *net.IPNet) {
4451
klog.V(3).Infof("Removing route for destination: %s", dst)
4552
delete(rs.routeTableStateMap, dst.String())
4653
}
54+
if rs.metricsEnabled {
55+
metrics.ControllerHostRoutesRemoved.Inc()
56+
metrics.ControllerHostRoutesSynced.Set(float64(len(rs.routeTableStateMap)))
57+
}
4758
}
4859

4960
// syncLocalRouteTable iterates over the local route state map and syncs all routes to the kernel's routing table
5061
func (rs *RouteSync) SyncLocalRouteTable() error {
62+
if rs.metricsEnabled {
63+
startSyncTime := time.Now()
64+
defer func(startTime time.Time) {
65+
runTime := time.Since(startTime)
66+
metrics.ControllerHostRoutesSyncTime.Observe(runTime.Seconds())
67+
}(startSyncTime)
68+
}
5169
rs.mutex.Lock()
5270
defer rs.mutex.Unlock()
5371
klog.V(2).Infof("Running local route table synchronization")
@@ -61,6 +79,9 @@ func (rs *RouteSync) SyncLocalRouteTable() error {
6179
}
6280
}
6381
}
82+
if rs.metricsEnabled {
83+
metrics.ControllerHostRoutesSynced.Set(float64(len(rs.routeTableStateMap)))
84+
}
6485
return nil
6586
}
6687

@@ -94,12 +115,20 @@ func (rs *RouteSync) Run(healthChan chan<- *healthcheck.ControllerHeartbeat, sto
94115

95116
// NewRouteSyncer creates a new routeSyncer that, when run, will sync routes kept in its local state table every
96117
// syncPeriod
97-
func NewRouteSyncer(syncPeriod time.Duration) *RouteSync {
118+
func NewRouteSyncer(syncPeriod time.Duration, registerMetrics bool) *RouteSync {
98119
rs := RouteSync{}
99120
rs.routeTableStateMap = make(map[string]*netlink.Route)
100121
rs.injectedRoutesSyncPeriod = syncPeriod
101122
rs.mutex = sync.Mutex{}
102123
// We substitute the RouteReplace function here so that we can easily monkey patch it in our unit tests
103124
rs.routeReplacer = netlink.RouteReplace
125+
rs.metricsEnabled = registerMetrics
126+
127+
// Register Metrics
128+
if registerMetrics {
129+
prometheus.MustRegister(metrics.ControllerHostRoutesSynced, metrics.ControllerHostRoutesSyncTime,
130+
metrics.ControllerHostRoutesAdded, metrics.ControllerHostRoutesRemoved)
131+
}
132+
104133
return &rs
105134
}

pkg/routes/route_sync_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func Test_syncLocalRouteTable(t *testing.T) {
6161
myNetlink.pause = time.Millisecond * 200
6262

6363
// Create a route replacer and seed it with some routes to iterate over
64-
syncer := NewRouteSyncer(15 * time.Second)
64+
syncer := NewRouteSyncer(15*time.Second, false)
6565
syncer.routeTableStateMap = generateTestRouteMap(testRoutes)
6666

6767
// Replace the netlink.RouteReplace function with our own mock function that includes a WaitGroup for syncing
@@ -143,7 +143,7 @@ func Test_routeSyncer_run(t *testing.T) {
143143

144144
t.Run("Ensure that run goroutine shuts down correctly on stop", func(t *testing.T) {
145145
// Setup routeSyncer to run 10 times a second
146-
syncer := NewRouteSyncer(100 * time.Millisecond)
146+
syncer := NewRouteSyncer(100*time.Millisecond, false)
147147
myNetLink := mockNetlink{}
148148
syncer.routeReplacer = myNetLink.mockRouteReplace
149149
syncer.routeTableStateMap = generateTestRouteMap(testRoutes)

0 commit comments

Comments
 (0)