Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions internal/metrics/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type OctopusMetricsCollector struct {
scopesWithTenantsTotalDesc *prometheus.Desc
scopesWithStepsTotalDesc *prometheus.Desc
scopesWithSpacesTotalDesc *prometheus.Desc
discoveredAgentsTotalDesc *prometheus.Desc
targetNamespacesTotalDesc *prometheus.Desc
}

// NewOctopusMetricsCollector creates a new instance of OctopusMetricsCollector
Expand Down Expand Up @@ -118,10 +118,10 @@ func NewOctopusMetricsCollector(cli client.Client, eng rules.Engine) *OctopusMet
nil,
nil,
),
discoveredAgentsTotalDesc: prometheus.NewDesc(
"octopus_discovered_agents_total",
"Number of discovered agents",
[]string{"agent_type"},
targetNamespacesTotalDesc: prometheus.NewDesc(
"octopus_target_namespaces_total",
"Number of target namespaces",
nil,
nil,
),
}
Expand All @@ -143,7 +143,7 @@ func (c *OctopusMetricsCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.scopesWithTenantsTotalDesc
ch <- c.scopesWithStepsTotalDesc
ch <- c.scopesWithSpacesTotalDesc
ch <- c.discoveredAgentsTotalDesc
ch <- c.targetNamespacesTotalDesc
}

// Collect implements the prometheus.Collector interface
Expand Down Expand Up @@ -176,6 +176,8 @@ func (c *OctopusMetricsCollector) Collect(ch chan<- prometheus.Metric) {
if err := c.collectScopeMetricsFromResources(ctx, ch); err != nil {
logger.Error(err, "Failed to collect scope metrics from resources")
}

c.collectTargetNamespaceMetrics(ch)
}

// collectWSAMetrics collects WorkloadServiceAccount metrics
Expand Down Expand Up @@ -418,6 +420,18 @@ func (c *OctopusMetricsCollector) collectScopeMetricsFromResources(ctx context.C
return nil
}

func (c *OctopusMetricsCollector) collectTargetNamespaceMetrics(ch chan<- prometheus.Metric) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: consider adding another metric around whether namespace detection is enabled, or if the namespaces are statically defined

targetNamespaces := c.engine.GetTargetNamespaces()
count := len(targetNamespaces)

metric := prometheus.MustNewConstMetric(
c.targetNamespacesTotalDesc,
prometheus.GaugeValue,
float64(count),
)
ch <- metric
}

func (c *OctopusMetricsCollector) TrackRequest(controllerType string, scopeMatched bool) {
IncRequestsTotal(controllerType, scopeMatched)
}
4 changes: 2 additions & 2 deletions internal/metrics/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ All metrics are prefixed with `octopus_` to allow easy filtering in Prometheus q
- **`octopus_scopes_with_steps_total`**: Number of scopes with Step defined
- **`octopus_scopes_with_spaces_total`**: Number of scopes with Space defined

#### Agent Metrics
- **`octopus_discovered_agents_total{agent_type}`**: Number of discovered agents by type
#### Namespace Metrics
- **`octopus_target_namespaces_total`**: Number of target namespaces

### Request Metrics (Counter)

Expand Down
6 changes: 6 additions & 0 deletions internal/metrics/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ var _ = Describe("Metrics Test", func() {
},
)

// Set up mock expectations for GetTargetNamespaces
mockEngine.On("GetTargetNamespaces").Return([]string{"namespace1", "namespace2"})

// Create collector with mock engine
mockCollector := NewOctopusMetricsCollector(k8sClient, mockEngine)
Expect(mockCollector).NotTo(BeNil())
Expand Down Expand Up @@ -292,6 +295,9 @@ var _ = Describe("Metrics Test", func() {
},
)

// Set up mock expectations for GetTargetNamespaces
mockEngine.On("GetTargetNamespaces").Return([]string{"namespace1", "namespace2"})

// Set up mock expectations for other Get* methods that the collector will call
mockEngine.On("GetWorkloadServiceAccounts", mock.MatchedBy(func(ctx context.Context) bool { return true })).Return(
iter.Seq[*v1beta1.WorkloadServiceAccount](func(yield func(*v1beta1.WorkloadServiceAccount) bool) {}),
Expand Down
4 changes: 4 additions & 0 deletions internal/rules/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,10 @@ func (i *InMemoryEngine) cleanupOrphanedResources(
return nil
}

func (i *InMemoryEngine) GetTargetNamespaces() []string {
return i.targetNamespaces
}

// reconcilePermissionsOnly performs fast path reconciliation when only permissions changed
func (i *InMemoryEngine) reconcilePermissionsOnly(
ctx context.Context, resource WSAResource, scopeMap map[Scope]map[string]WSAResource,
Expand Down
5 changes: 5 additions & 0 deletions internal/rules/namespace_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

type NamespaceDiscovery interface {
DiscoverTargetNamespaces(ctx context.Context, k8sClient client.Client) ([]string, error)
GetTargetNamespaces() []string
}

type NamespaceDiscoveryService struct {
Expand Down Expand Up @@ -56,3 +57,7 @@ func (nds NamespaceDiscoveryService) DiscoverTargetNamespaces(

return namespaces, nil
}

func (nds NamespaceDiscoveryService) GetTargetNamespaces() []string {
return []string{}
}
5 changes: 5 additions & 0 deletions internal/test/mocks/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ func (m *MockEngine) DiscoverTargetNamespaces(ctx context.Context, k8sClient cli
return args.Get(0).([]string), args.Error(1)
}

func (m *MockEngine) GetTargetNamespaces() []string {
args := m.Called()
return args.Get(0).([]string)
}

func (m *MockEngine) GarbageCollectServiceAccounts(
ctx context.Context, expectedServiceAccounts *set.Set[string], targetNamespaces *set.Set[string],
) (ctrl.Result, error) {
Expand Down