Skip to content

Commit

Permalink
Merge pull request #6 from zsais/exporter-basic-auth
Browse files Browse the repository at this point in the history
add support for exporter basic auth
  • Loading branch information
portertech authored Jan 9, 2018
2 parents 1210b63 + 04c2757 commit 04c8c1d
Show file tree
Hide file tree
Showing 12 changed files with 788 additions and 16 deletions.
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,21 @@ Help:

```
$ sensu-prometheus-collector -h
Usage of ./sensu-prometheus-collector:
Usage of sensu-prometheus-collector:
-exporter-password string
Prometheus exporter basic auth password
-exporter-url string
Prometheus exporter URL to pull metrics from.
Prometheus exporter URL to pull metrics from.
-exporter-user string
Prometheus exporter basic auth user
-metric-prefix string
Metric name prefix, only supported by line protocol output formats.
Metric name prefix, only supported by line protocol output formats.
-output-format string
The check output format to use for metrics {influx|graphite|json}. (default "influx")
The check output format to use for metrics {influx|graphite|json}. (default "influx")
-prom-query string
Prometheus API query string. (default "up")
Prometheus API query string. (default "up")
-prom-url string
Prometheus API URL. (default "http://localhost:9090")
Prometheus API URL. (default "http://localhost:9090")
```

Application instrumentation:
Expand All @@ -82,12 +86,14 @@ go_memstats_mspan_sys_bytes value=32768 1506991233
```

```
$ sensu-prometheus-collector -exporter-url http://localhost:8080/metrics -output-format graphite -metric-prefix foo.bar.
$ sensu-prometheus-collector -exporter-url http://localhost:8080/metrics -exporter-user admin -exporter-password secretpassword -output-format graphite -metric-prefix foo.bar.
foo.bar.go_memstats_stack_inuse_bytes 294912 1506991405
foo.bar.go_memstats_mallocs_total 6375 1506991405
...
```

Exporter basic auth credentials can also be set via environment vars `EXPORTER_USER` and `EXPORTER_PASSWORD`.

Prometheus query API:

```
Expand Down
61 changes: 53 additions & 8 deletions sensu-prometheus-collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ import (
"strconv"
"time"

"github.com/kelseyhightower/envconfig"
"github.com/prometheus/client_golang/api/prometheus"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/common/model"
)

const (
exporterAuthID = "exporter"
)

type Tag struct {
Name model.LabelName
Value model.LabelValue
Expand All @@ -26,6 +31,12 @@ type Metric struct {
Value float64
}

type ExporterAuth struct {
User string `envconfig:"user" default:""`
Password string `envconfig:"password" default:""`
Header string `envconfig:"header" default:""`
}

func CreateJSONMetrics(samples model.Vector) string {
metrics := []Metric{}

Expand Down Expand Up @@ -138,14 +149,20 @@ func QueryPrometheus(promURL string, queryString string) (model.Vector, error) {
return nil, errors.New("unexpected response type")
}

func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
func QueryExporter(exporterURL string, auth ExporterAuth) (model.Vector, error) {
client := &http.Client{}
req, err := http.NewRequest("GET", exporterURL, nil)

if err != nil {
return nil, err
}
if authorization != "" {
req.Header.Set("Authorization", authorization)

if auth.User != "" && auth.Password != "" {
req.SetBasicAuth(auth.User, auth.Password)
}

if auth.Header != "" {
req.Header.Set("Authorization", auth.Header)
}

expResponse, err := client.Do(req)
Expand All @@ -156,7 +173,7 @@ func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
}

if expResponse.StatusCode != http.StatusOK {
return nil, errors.New("exporter returned non OK HTTP response status")
return nil, errors.New("exporter returned non OK HTTP response status: " + expResponse.Status)
}

var parser expfmt.TextParser
Expand All @@ -181,33 +198,61 @@ func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
return samples, nil
}

func setExporterAuth(user string, password string, header string) (auth ExporterAuth, error error) {
err := envconfig.Process(exporterAuthID, &auth)

if err != nil {
return auth, err
}

if user != "" && password != "" {
auth.User = user
auth.Password = password
}

if auth.Header != "" {
auth.Header = header
}

return auth, nil
}

func main() {
exporterURL := flag.String("exporter-url", "", "Prometheus exporter URL to pull metrics from.")
exporterUser := flag.String("exporter-user", "", "Prometheus exporter basic auth user.")
exporterPassword := flag.String("exporter-password", "", "Prometheus exporter basic auth password.")
exporterAuthorizationHeader := flag.String("exporter-authorization", "", "Prometheus exporter Authorization header.")
promURL := flag.String("prom-url", "http://localhost:9090", "Prometheus API URL.")
queryString := flag.String("prom-query", "up", "Prometheus API query string.")
outputFormat := flag.String("output-format", "influx", "The check output format to use for metrics {influx|graphite|json}.")
metricPrefix := flag.String("metric-prefix", "", "Metric name prefix, only supported by line protocol output formats.")
flag.Parse()

samples := model.Vector{}
var samples model.Vector
var err error

if *exporterURL != "" {
samples, err = QueryExporter(*exporterURL, *exporterAuthorizationHeader)
auth, err := setExporterAuth(*exporterUser, *exporterPassword, *exporterAuthorizationHeader)

if err != nil {
_ = fmt.Errorf("%v", err)
os.Exit(2)
}

samples, err = QueryExporter(*exporterURL, auth)
} else {
samples, err = QueryPrometheus(*promURL, *queryString)
}

if err != nil {
fmt.Errorf("%v", err)
_ = fmt.Errorf("%v", err)
os.Exit(2)
}

err = OutputMetrics(samples, *outputFormat, *metricPrefix)

if err != nil {
fmt.Errorf("%v", err)
_ = fmt.Errorf("%v", err)
os.Exit(2)
}
}
2 changes: 1 addition & 1 deletion sensu-prometheus-collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestQueryExporter(t *testing.T) {

time.Sleep(2 * time.Second)

samples, err := QueryExporter("http://localhost:7777/metrics", "")
samples, err := QueryExporter("http://localhost:7777/metrics", ExporterAuth{User: "", Password: "", Header: ""})

assert.NoError(t, err)
assert.NotNil(t, samples)
Expand Down
19 changes: 19 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/LICENSE

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

2 changes: 2 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/MAINTAINERS

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

188 changes: 188 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/README.md

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

Loading

0 comments on commit 04c8c1d

Please sign in to comment.