From 6cc9d44264291d9149db12db9a61cd5458306787 Mon Sep 17 00:00:00 2001 From: anushree-n Date: Tue, 14 Jul 2015 11:06:55 -0700 Subject: [PATCH] Implement Collect method of Collector interface --- collector/generic_collector.go | 71 ++++++++++++++++++++++++++++- collector/generic_collector_test.go | 31 +++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/collector/generic_collector.go b/collector/generic_collector.go index 763e6ff1..d3d30467 100644 --- a/collector/generic_collector.go +++ b/collector/generic_collector.go @@ -18,7 +18,10 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/http" "regexp" + "strconv" + "strings" "time" "github.com/google/cadvisor/info/v1" @@ -92,6 +95,70 @@ func (collector *GenericCollector) Name() string { //Returns collected metrics and the next collection time of the collector func (collector *GenericCollector) Collect() (time.Time, []v1.Metric, error) { - //TO BE IMPLEMENTED - return time.Now(), nil, nil + minNextColTime := collector.configFile.MetricsConfig[0].PollingFrequency + for _, metricConfig := range collector.configFile.MetricsConfig { + if metricConfig.PollingFrequency < minNextColTime { + minNextColTime = metricConfig.PollingFrequency + } + } + currentTime := time.Now() + nextCollectionTime := currentTime.Add(time.Duration(minNextColTime * time.Second)) + + uri := collector.configFile.Endpoint + response, err := http.Get(uri) + if err != nil { + return nextCollectionTime, nil, err + } + + defer response.Body.Close() + + pageContent, err := ioutil.ReadAll(response.Body) + if err != nil { + return nextCollectionTime, nil, err + } + + metrics := make([]v1.Metric, len(collector.configFile.MetricsConfig)) + var errorSlice []error + + for ind, metricConfig := range collector.configFile.MetricsConfig { + regex, err := regexp.Compile(metricConfig.Regex) + if err != nil { + return nextCollectionTime, nil, err + } + + matchString := regex.FindStringSubmatch(string(pageContent)) + if matchString != nil { + if metricConfig.Units == "float" { + regVal, err := strconv.ParseFloat(strings.TrimSpace(matchString[1]), 64) + if err != nil { + errorSlice = append(errorSlice, err) + } + metrics[ind].FloatPoints = []v1.FloatPoint{ + {Value: regVal, Timestamp: currentTime}, + } + } else if metricConfig.Units == "integer" || metricConfig.Units == "int" { + regVal, err := strconv.ParseInt(strings.TrimSpace(matchString[1]), 10, 64) + if err != nil { + errorSlice = append(errorSlice, err) + } + metrics[ind].IntPoints = []v1.IntPoint{ + {Value: regVal, Timestamp: currentTime}, + } + + } else { + errorSlice = append(errorSlice, fmt.Errorf("Unexpected value of 'units' for metric '%v' in config ", metricConfig.Name)) + } + } else { + errorSlice = append(errorSlice, fmt.Errorf("No match found for regexp: %v for metric '%v' in config", metricConfig.Regex, metricConfig.Name)) + } + + metrics[ind].Name = metricConfig.Name + if metricConfig.MetricType == "gauge" { + metrics[ind].Type = v1.MetricGauge + } else if metricConfig.MetricType == "counter" { + metrics[ind].Type = v1.MetricCumulative + } + } + + return nextCollectionTime, metrics, compileErrors(errorSlice) } diff --git a/collector/generic_collector_test.go b/collector/generic_collector_test.go index ca875d60..fd38f287 100644 --- a/collector/generic_collector_test.go +++ b/collector/generic_collector_test.go @@ -15,10 +15,14 @@ package collector import ( + "fmt" "io/ioutil" + "net/http" + "net/http/httptest" "os" "testing" + "github.com/google/cadvisor/info/v1" "github.com/stretchr/testify/assert" ) @@ -115,3 +119,30 @@ func TestConfig(t *testing.T) { assert.Equal(collector.configFile.Endpoint, "http://localhost:8000/nginx_status") assert.Equal(collector.configFile.MetricsConfig[0].Name, "activeConnections") } + +func TestMetricCollection(t *testing.T) { + assert := assert.New(t) + + //Collect nginx metrics from a fake nginx endpoint + fakeCollector, err := NewCollector("nginx", "config/sample_config.json") + assert.NoError(err) + + tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Active connections: 3\nserver accepts handled requests") + fmt.Fprintln(w, "5 5 32\nReading: 0 Writing: 1 Waiting: 2") + })) + defer tempServer.Close() + fakeCollector.configFile.Endpoint = tempServer.URL + + _, metrics, errMetric := fakeCollector.Collect() + assert.NoError(errMetric) + assert.Equal(metrics[0].Name, "activeConnections") + assert.Equal(metrics[0].Type, v1.MetricGauge) + assert.Nil(metrics[0].FloatPoints) + assert.Equal(metrics[1].Name, "reading") + assert.Equal(metrics[2].Name, "writing") + assert.Equal(metrics[3].Name, "waiting") + + //Assert: Number of active connections = Number of connections reading + Number of connections writing + Number of connections waiting + assert.Equal(metrics[0].IntPoints[0].Value, (metrics[1].IntPoints[0].Value)+(metrics[2].IntPoints[0].Value)+(metrics[3].IntPoints[0].Value)) +}