Skip to content

Commit

Permalink
Add a generic config and collector for custom metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
anushree-n committed Jul 7, 2015
1 parent afc2188 commit b4dcc37
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 0 deletions.
53 changes: 53 additions & 0 deletions collector/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package collector

import (
"time"
)

type Config struct {
//the endpoint to hit to scrape metrics
Endpoint string `json:"endpoint"`

//holds information about different metrics that can be collected
MetricsConfig []MetricConfig `json:"metrics_config"`
}

// metricConfig holds information extracted from the config file about a metric
type MetricConfig struct {
//the name of the metric
Name string `json:"name"`

//enum type for the metric type
MetricType MetricType `json:"metric_type"`

//data type of the metric (eg: integer, string)
Units string `json:"units"`

//the frequency at which the metric should be collected
PollingFrequency time.Duration `json:"polling_frequency"`

//the regular expression that can be used to extract the metric
Regex string `json:"regex"`
}

// MetricType is an enum type that lists the possible type of the metric
type MetricType string

const (
Counter MetricType = "counter"
Gauge MetricType = "gauge"
)
30 changes: 30 additions & 0 deletions collector/config/sample_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"endpoint" : "http://localhost:8000/nginx_status",
"metrics_config" : [
{ "name" : "activeConnections",
"metric_type" : "gauge",
"units" : "integer",
"polling_frequency" : 10,
"regex" : "Active connections: ([0-9]+)"
},
{ "name" : "reading",
"metric_type" : "gauge",
"units" : "integer",
"polling_frequency" : 10,
"regex" : "Reading: ([0-9]+) .*"
},
{ "name" : "writing",
"metric_type" : "gauge",
"units" : "integer",
"polling_frequency" : 10,
"regex" : ".*Writing: ([0-9]+).*"
},
{ "name" : "waiting",
"metric_type" : "gauge",
"units" : "integer",
"polling_frequency" : 10,
"regex" : ".*Waiting: ([0-9]+)"
}
]

}
62 changes: 62 additions & 0 deletions collector/generic_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package collector

import (
"encoding/json"
"io/ioutil"
"time"

"github.com/google/cadvisor/info/v2"
)

type GenericCollector struct {
//name of the collector
name string

//holds information extracted from the config file for a collector
configFile Config
}

//Returns a new collector using the information extracted from the configfile
func NewCollector(collectorName string, configfile string) (*GenericCollector, error) {
configFile, err := ioutil.ReadFile(configfile)
if err != nil {
return nil, err
}

var configInJSON Config
err = json.Unmarshal(configFile, &configInJSON)
if err != nil {
return nil, err
}

//TODO : Add checks for validity of config file (eg : Accurate JSON fields)

return &GenericCollector{
name: collectorName, configFile: configInJSON,
}, nil
}

//Returns name of the collector
func (collector *GenericCollector) Name() string {
return collector.name
}

//Returns collected metrics and the next collection time of the collector
func (collector *GenericCollector) Collect() (time.Time, []v2.Metric, error) {
//TO BE IMPLEMENTED
return time.Now(), nil, nil
}
62 changes: 62 additions & 0 deletions collector/generic_collector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package collector

import (
"io/ioutil"
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestConfigWithErrors(t *testing.T) {
assert := assert.New(t)

//Syntax error: Missed '"' after active connections
invalid := `
{
"endpoint" : "host:port/nginx_status",
"metricsConfig" : [
{
"name" : "activeConnections,
"metricType" : "gauge",
"units" : "integer",
"pollingFrequency" : "10s",
"regex" : "Active connections: ([0-9]+)"
}
]
}
`

//Create a temporary config file 'temp.json' with invalid json format
assert.NoError(ioutil.WriteFile("temp.json", []byte(invalid), 0777))

_, err := NewCollector("tempCollector", "temp.json")
assert.Error(err)

assert.NoError(os.Remove("temp.json"))
}

func TestConfig(t *testing.T) {
assert := assert.New(t)

//Create an nginx collector using the config file 'sample_config.json'
collector, err := NewCollector("nginx", "config/sample_config.json")
assert.NoError(err)
assert.Equal(collector.name, "nginx")
assert.Equal(collector.configFile.Endpoint, "http://localhost:8000/nginx_status")
assert.Equal(collector.configFile.MetricsConfig[0].Name, "activeConnections")
}

0 comments on commit b4dcc37

Please sign in to comment.