diff --git a/collectors/nodestats/nodestats_collector_test.go b/collectors/nodestats/nodestats_collector_test.go index 0118430..779a18a 100644 --- a/collectors/nodestats/nodestats_collector_test.go +++ b/collectors/nodestats/nodestats_collector_test.go @@ -153,6 +153,64 @@ func TestCollectError(t *testing.T) { } } +func TestIsPipelineHealthy(t *testing.T) { + collector := NewPipelineSubcollector() + tests := []struct { + name string + stats responses.PipelineReloadResponse + expected float64 + }{ + { + name: "Both timestamps nil", + stats: responses.PipelineReloadResponse{ + LastFailureTimestamp: nil, + LastSuccessTimestamp: nil, + }, + expected: 1, + }, + { + name: "Failure timestamp set", + stats: responses.PipelineReloadResponse{ + LastFailureTimestamp: &time.Time{}, + LastSuccessTimestamp: nil, + }, + expected: 0, + }, + { + name: "Success timestamp earlier than failure timestamp", + stats: responses.PipelineReloadResponse{ + LastFailureTimestamp: &time.Time{}, + LastSuccessTimestamp: func() *time.Time { t := time.Time{}.Add(-1 * time.Hour); return &t }(), + }, + expected: 0, + }, + { + name: "Success timestamp later than failure timestamp", + stats: responses.PipelineReloadResponse{ + LastFailureTimestamp: &time.Time{}, + LastSuccessTimestamp: func() *time.Time { t := time.Time{}.Add(1 * time.Hour); return &t }(), + }, + expected: 1, + }, + { + name: "Missing fields, assume healthy", + stats: responses.PipelineReloadResponse{}, + expected: 1, + }, + } + + // Run test cases + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := collector.isPipelineHealthy(tt.stats) + if result != tt.expected { + t.Errorf("Expected %v, but got %v", tt.expected, result) + return + } + }) + } +} + func TestTruncatePluginId(t *testing.T) { testCases := []struct { input string @@ -170,4 +228,4 @@ func TestTruncatePluginId(t *testing.T) { t.Errorf("TruncatePluginId(%v) = %v; want %v", tc.input, got, tc.output) } } -} \ No newline at end of file +} diff --git a/collectors/nodestats/pipeline_subcollector.go b/collectors/nodestats/pipeline_subcollector.go index 255b854..66d0603 100644 --- a/collectors/nodestats/pipeline_subcollector.go +++ b/collectors/nodestats/pipeline_subcollector.go @@ -88,6 +88,13 @@ func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipeli ch <- prometheus.NewMetricWithTimestamp(*pipeStats.Reloads.LastFailureTimestamp, prometheus.MustNewConstMetric(collector.ReloadsLastFailureTimestamp, prometheus.GaugeValue, 1, pipelineID)) } + if pipeStats.Reloads.LastSuccessTimestamp != nil { + ch <- prometheus.NewMetricWithTimestamp(*pipeStats.Reloads.LastSuccessTimestamp, prometheus.MustNewConstMetric(collector.ReloadsLastSuccessTimestamp, prometheus.GaugeValue, 1, pipelineID)) + } + if pipeStats.Reloads.LastFailureTimestamp != nil { + ch <- prometheus.NewMetricWithTimestamp(*pipeStats.Reloads.LastFailureTimestamp, prometheus.MustNewConstMetric(collector.ReloadsLastFailureTimestamp, prometheus.GaugeValue, 1, pipelineID)) + } + ch <- prometheus.MustNewConstMetric(collector.QueueEventsCount, prometheus.CounterValue, float64(pipeStats.Queue.EventsCount), pipelineID) ch <- prometheus.MustNewConstMetric(collector.QueueEventsQueueSize, prometheus.CounterValue, float64(pipeStats.Queue.QueueSizeInBytes), pipelineID) ch <- prometheus.MustNewConstMetric(collector.QueueMaxQueueSizeInBytes, prometheus.CounterValue, float64(pipeStats.Queue.MaxQueueSizeInBytes), pipelineID) @@ -134,8 +141,8 @@ func (collector *PipelineSubcollector) Collect(pipeStats *responses.SinglePipeli } func (collector *PipelineSubcollector) isPipelineHealthy(pipeReloadStats responses.PipelineReloadResponse) float64 { - // 1. If both timestamps are nil, the pipeline is healthy - if pipeReloadStats.LastSuccessTimestamp == nil && pipeReloadStats.LastFailureTimestamp == nil { + // 1. If last failure timestamp (or both) are nil, the pipeline is healthy + if pipeReloadStats.LastFailureTimestamp == nil { return 1 // 2. If last_failure_timestamp is set and last success timestamp is nil, the pipeline is unhealthy } else if pipeReloadStats.LastFailureTimestamp != nil && pipeReloadStats.LastSuccessTimestamp == nil {