Skip to content

Commit

Permalink
Merge pull request #3 from warmans/feature/add-labels
Browse files Browse the repository at this point in the history
Add Label Feature
  • Loading branch information
warmans authored Apr 27, 2017
2 parents c567924 + c55f598 commit 2c046dd
Show file tree
Hide file tree
Showing 19 changed files with 165 additions and 220 deletions.
6 changes: 2 additions & 4 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@ server:
bind: ":8080"
timeout: 1000 #ms
targets:
- "http://localhost:9100/metrics"
- "http://localhost:9100/metrics"
- "http://localhost:9100/metrics"
- "http://localhost:9100/metrics"
- "http://localhost/prom.txt"
- "http://localhost/prom2.txt"
10 changes: 10 additions & 0 deletions fixture/histogram.golden.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# HELP http_request_duration_seconds A histogram of the request duration.
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{ae_source="foo",le="0.05"} 24054
http_request_duration_seconds_bucket{ae_source="foo",le="0.1"} 33444
http_request_duration_seconds_bucket{ae_source="foo",le="0.2"} 100392
http_request_duration_seconds_bucket{ae_source="foo",le="0.5"} 129389
http_request_duration_seconds_bucket{ae_source="foo",le="1"} 133988
http_request_duration_seconds_bucket{ae_source="foo",le="+Inf"} 144320
http_request_duration_seconds_sum{ae_source="foo"} 53423
http_request_duration_seconds_count{ae_source="foo"} 144320
9 changes: 9 additions & 0 deletions fixture/histogram.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"} 3 1395066363000

# HELP http_requests_total The total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{method="post",code="200"} 1027 1395066363000
http_requests_total{method="post",code="400"} 3 1395066363000
26 changes: 21 additions & 5 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package: github.com/warmans/prometheus-aggregate-exporter
import:
- package: gopkg.in/yaml.v2
- package: github.com/prometheus/common
66 changes: 50 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ import (
"net/http"
"strconv"
"time"

"github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
)

var (
Version = "unknown"
Version = "unknown"
)

var (
configPathFlag = flag.String("config", "config.yml", "Path to config YAML file.")
verboseFlag = flag.Bool("verbose", false, "Log more information")
versionFlag = flag.Bool("version", false, "Show version and exit")
verboseFlag = flag.Bool("verbose", false, "Log more information")
versionFlag = flag.Bool("version", false, "Show version and exit")
appendLabel = flag.Bool("label", false, "Add a label to metrics to show their origin target")
labelName = flag.String("label.name", "ae_source", "Label name to use if a target name label is appended to metrics")
)

type Config struct {
Expand Down Expand Up @@ -85,7 +90,7 @@ func main() {
type Result struct {
URL string
SecondsTaken float64
Payload io.ReadCloser
MetricFamily map[string]*io_prometheus_client.MetricFamily
Error error
}

Expand All @@ -102,10 +107,14 @@ func (f *Aggregator) Aggregate(targets []string, output io.Writer) {
}

func(numTargets int, resultChan chan *Result) {

numResuts := 0

allFamilies := make(map[string]*io_prometheus_client.MetricFamily)

for {
if numTargets == numResuts {
return
break
}
select {
case result := <-resultChan:
Expand All @@ -116,34 +125,59 @@ func (f *Aggregator) Aggregate(targets []string, output io.Writer) {
continue
}

_, err := io.Copy(output, result.Payload)
if err != nil {
log.Printf("Copy error: %s", err.Error())
for mfName, mf := range result.MetricFamily {
if *appendLabel {
for _, m := range mf.Metric {
m.Label = append(m.Label, &io_prometheus_client.LabelPair{Name: labelName, Value: &result.URL})
}
}
if existingMf, ok := allFamilies[mfName]; ok {
for _, m := range mf.Metric {
existingMf.Metric = append(existingMf.Metric, m)
}
} else {
allFamilies[*mf.Name] = mf
}
}

err = result.Payload.Close()
if err != nil {
log.Printf("Result body close error: %s", err.Error())
}

if *verboseFlag {
log.Printf("OK: %s was refreshed in %.3f seconds", result.URL, result.SecondsTaken)
}
}
}

encoder := expfmt.NewEncoder(output, expfmt.FmtText)
for _, f := range allFamilies {
encoder.Encode(f)
}

}(len(targets), resultChan)
}

func (f *Aggregator) fetch(target string, resultChan chan *Result) {

startTime := time.Now()
res, err := f.HTTP.Get(target)

result := &Result{URL: target, SecondsTaken: time.Since(startTime).Seconds(), Error: nil}
if res != nil {
result.Payload = res.Body
result.MetricFamily, err = getMetricFamilies(res.Body)
if err != nil {
result.Error = fmt.Errorf("failed to add labels to target %s metrics: %s", target, err.Error())
resultChan <- result
return
}
}
if err != nil {
result.Error = fmt.Errorf("Failed to fetch URL %s due to error: %s", target, err.Error())
result.Error = fmt.Errorf("failed to fetch URL %s due to error: %s", target, err.Error())
}
resultChan <- result
}

func getMetricFamilies(sourceData io.Reader) (map[string]*io_prometheus_client.MetricFamily, error) {
parser := expfmt.TextParser{}
metricFamiles, err := parser.TextToMetricFamilies(sourceData)
if err != nil {
return nil, err
}
return metricFamiles, nil
}
36 changes: 36 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"testing"
)

var updateGoldenFile = flag.Bool("update.golden", false, "update golden files")

func TestMain(m *testing.M) {

flag.Parse()
os.Exit(m.Run())
}

func mustOpenFile(name string, flag int) *os.File {
file, err := os.OpenFile(fmt.Sprintf("fixture/%s", name), flag, 0666)
if err != nil {
panic(err)
}
return file
}

func mustReadAll(r io.Reader) string {
b, err := ioutil.ReadAll(r)
if err != nil {
panic("failed to readall reader: " + err.Error())
}
return string(b[:])
}

//todo: re-implement tests
1 change: 1 addition & 0 deletions vendor/github.com/golang/protobuf
Submodule protobuf added at 2bba06
1 change: 1 addition & 0 deletions vendor/github.com/matttproud/golang_protobuf_extensions
Submodule golang_protobuf_extensions added at c12348
1 change: 1 addition & 0 deletions vendor/github.com/prometheus/client_model
Submodule client_model added at 6f3806
1 change: 1 addition & 0 deletions vendor/github.com/prometheus/common
Submodule common added at 13ba4d
Loading

0 comments on commit 2c046dd

Please sign in to comment.