• Stars
    star
    341
  • Rank 123,987 (Top 3 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A reverse proxy designed for Prometheus exporters

Exporter Exporter - prometheus exporter proxy

"you mean apache/nginx" - bbrazil

This provides a simple reverse proxy for prometheus exporters. It is intended as a single binary alternative to nginx/apache for use in environments where opening multiple TCP ports to all servers might be difficult (technically or politically)

The advantages are:

  • A single port can be used to query multiple exporters (to ease firewall configuration concerns).
  • Can provide TLS with optional client certificate authentication.
  • Provides verification that the target is serving prometheus metrics.
  • Can be used to execute scripts that produce prometheus metrics.
  • up behaviour is the same as for querying individual collectors.
  • Small code size, minimal external depedencies, easily auditable.

The exporter has three endpoints.

  • /: displays a list of all exporters with links to their metrics.

    • Returns JSON if the header "Accept: application/json" is passed
  • /proxy: which takes the following parameters:

    • module: the name of the module from the configuration to execute. (a default module can be selected using the defaultModule config option)
    • args: (only for exec modules): additional arguments to the backend command.
    • all other query string parameters are passed on to any http backend module. (excluding the first module parameter value).
  • /metrics: this exposes the metrics for the collector itself.

Features that will NOT be included:

  • merging of module outputs into one query (this would break up behaviour)

Installation

You can build directly using a plain go get github.com/QubitProducts/exporter_exporter. The provided Makefile is primarily used for releases.

Pre-built binaries and a debian package are available on the GitHub release page.

An ansible recipe as also available (kindly provided by one of our users).

TODO:

  • Config reload on HUP (or POST, or config file change?)
  • route to a docker/rocket container by name

Windows Service

The binary can be installed as a Windows service by supplying the -winsvc install arg. All other arguments passed along with -winsvc install will be added to the service startup and can only be changed by uninstalling/installing it again (or modifying the Windows registry directly).

Configuration

In expexp.yaml list each exporter listening on localhost with its known port.

defaultModule: node # called if "module" param is not supplied
modules:
  node:
    method: http
    http:
       port: 9100

  mtail:
    method: http
    http:
       port: 3903
       headers:
          foo: bar

  cadvisor:
    method: http
    http:
       verify: false
       port: 4194

  netdata:
    method: http
    http:
       port: 19999
       path: '/api/v1/allmetrics?format=prometheus'

  blackbox:
    method: http
    http:
       port: 9115
       path: '/probe'

  somescript:
    method: exec
    timeout: 1s
    exec:
      command: /tmp/myscript.sh
      args:
        - "myarg1"
        - "myarg2"
      env:
        THING: "1"
        THING2: "2"

  somefile:
    method: file
    file:
      path: /tmp/myfile.prometheus.txt

In your prometheus configuration

scrape_configs:
  - job_name: 'expexp_metrics'
    scrape_interval: 1s
    static_configs:
      - targets: ['host:9999']
  - job_name: 'cadvisor'
    scrape_interval: 5s
    metrics_path: /proxy
    params:
      module:
        - cadvisor
    static_configs:
      - targets: ['host:9999']
  - job_name: 'mtail'
    scrape_interval: 5s
    metrics_path: /proxy
    params:
      module:
        - mtail
    static_configs:
      - targets: ['host:9999']
  - job_name: 'somescript'
    scrape_interval: 5s
    metrics_path: /proxy
    params:
      module:
        - somescript
    static_configs:
      - targets: ['host:9999']
  - job_name: 'blackbox'
    metrics_path: /proxy
    params:
      module:
        - blackbox
        - icmp_example
    static_configs:
      - targets:
        - 8.8.8.8
        - 8.8.4.4
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: host:9999

Blackbox Exporter

The blackbox exporter also uses the "module" query string parameter. To query it via exporter_exporter we rely on the stripping of the initial "module" parameter. For example

curl http://localhost:9999/proxy\?module\=blackbox\&module\=icmp_example\&target\=8.8.8.8

Will query the icmp_example module in your blackbox configuration.

Directory-based configuration

You can also specify -config.dirs to break the configuration into separate files. The module name is taken from the name of the file (minus the yml/yaml extension), and the configuration for that module goes in at the top level.

Note that if you want to use only this configuration method and not the file-based configuration (-config.file option), you must provide an empty string for the file option : ./exporter_exporter -config.file "" -config.dirs "/etc/exporter_exporter/"

==> expexp.yaml <==
modules: {}

==> expexp.d/node.yaml <==
method: http
http:
   port: 9100

==> expexp.d/mtail.yaml <==
method: http
http:
   port: 3903

TLS configuration

You can use exporter_exporter with TLS to encrypt the traffic, and at the same time enforce strong mutual authentication between the nodes and the prometheus server.

Note that -web.tls.verify will accept any certificate signed by the -web.tls.ca, so you need to create a separate CA for this purpose - or use a self-signed certificate, which acts as its own CA.

Here is a simple configuration example, using one key/cert for the prometheus server and one key/cert shared between all the remote nodes. Firstly, create the keys and certs:

openssl req -x509 -newkey rsa:2048 -keyout prom_node_key.pem -out prom_node_cert.pem -days 29220 -nodes -subj /commonName=prom_node/ -addext "subjectAltName=DNS:prom_node"
openssl req -x509 -newkey rsa:2048 -keyout prometheus_key.pem -out prometheus_cert.pem -days 29220 -nodes -subj /commonName=prometheus/ -addext "subjectAltName=DNS:prometheus"

Create an /etc/prometheus/ssl/ directory on the prometheus server and all the remote nodes. Install both cert.pem files everywhere. It is safe for them to be world-readable.

Install prom_node_key.pem only on the nodes, and set file permissions to protect it so that only exporter_exporter can read it. Similarly, install prometheus_key.pem only on the prometheus server, and set permissions so that only the prometheus process can read it.

Configuration for exporter_exporter on the nodes (here it also disables plain HTTP):

EXPEXP_FLAGS='-web.listen-address= -web.tls.listen-address=:9998
 -web.tls.cert=/etc/prometheus/ssl/prom_node_cert.pem
 -web.tls.key=/etc/prometheus/ssl/prom_node_key.pem
 -web.tls.ca=/etc/prometheus/ssl/prometheus_cert.pem
 -web.tls.verify'

To test, use curl to make a scrape, replacing x.x.x.x with the IP address of the target:

curl --cert /etc/prometheus/ssl/prometheus_cert.pem \
     --key /etc/prometheus/ssl/prometheus_key.pem \
     --cacert /etc/prometheus/ssl/prom_node_cert.pem \
     --resolve prom_node:9998:x.x.x.x \
     -v https://prom_node:9998/proxy?module=node

When this is working, configure your prometheus server to use https. Example:

  - job_name: node
    scrape_interval: 1m
    scrape_timeout: 50s
    file_sd_configs:
      - files:
        - /etc/prometheus/targets.d/node_targets.yml
    scheme: https
    tls_config:
      # Verifying remote identity
      ca_file: /etc/prometheus/ssl/prom_node_cert.pem
      server_name: prom_node
      # Asserting our identity
      cert_file: /etc/prometheus/ssl/prometheus_cert.pem
      key_file: /etc/prometheus/ssl/prometheus_key.pem
    metrics_path: /proxy
    params:
      module: [ node ]
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
      - source_labels: [__address__]
        regex: '([^:]+)'
        target_label: __address__
        replacement: '${1}:9998'

Example /etc/prometheus/targets.d/node_targets.yml:

- labels: []
  targets:
  - 192.0.2.1
  - 192.0.2.2

More Repositories

1

bamboo

HAProxy auto configuration and auto service discovery for Mesos Marathon
Go
793
star
2

cherrytree

A flexible nested router.
JavaScript
108
star
3

gcs-browser-upload

Resumable chunked uploads to Google Cloud Storage from the browser
JavaScript
84
star
4

d3-react-sparkline

A simple component to render a sparkline with D3
JavaScript
73
star
5

aws_audit_exporter

Prometheus exporter for aws billing information
Go
24
star
6

queue-that

A queue managed in localStorage for async tasks that may run immediately before page unload
JavaScript
21
star
7

json-bourne

Drop in replacement for JSON that standardizes Array.toJSON and Date.toJSON
JavaScript
15
star
8

dataflow_launcher

A unified way of launching Dataflow jobs
Python
14
star
9

metrics-flow

Metrics collection library for Google Dataflow
Java
13
star
10

kafka_lag_exporter

A kafka lag exporter for prometheus
Go
11
star
11

cookieman

simple cookie lib
JavaScript
11
star
12

shopify-qubit-asset

Template snippets for implementing Qubit events in Shopify
Liquid
11
star
13

jsonlogic

Go
10
star
14

bapistrano

Deploy JS apps to s3 multiverse.
JavaScript
9
star
15

iris

Envoy xDS for Kubernetes service discovery
Go
8
star
16

qubit-cli

Develop experiences from your desktop
JavaScript
8
star
17

secret-door

An RPC implementation on top of window.postMessage for cross context communication in the browser ㊙️ 🚪
JavaScript
7
star
18

sync-p

Tiny battle tested sync promise lib
JavaScript
7
star
19

kube-ci

Go
6
star
20

driftwood

A namespaced stylish logger
JavaScript
6
star
21

utils

Utilities for clientside code injection
JavaScript
5
star
22

gogoproto-java

Java packaging for Gogoproto
5
star
23

akka-cloudpubsub

Akka Streams Source and Sink for Cloud Pub/Sub
Scala
5
star
24

mflowd

A go daemon that collects monitoring metrics from Google Dataflow workers and exposes them to Prometheus
Go
5
star
25

event-kitten

An event emitter inspired by event-kit, written in JavaScript
JavaScript
5
star
26

recommendations

@qubit/recommendations
JavaScript
4
star
27

topNET

Lightweight Java NIO HTTP Server
Java
4
star
28

uv-api

Universal Variable API
JavaScript
3
star
29

express-sourcemap-filter

Simple express middleware to restrict sourcemap access to certain IP addresses
JavaScript
3
star
30

qubit-react

A wrapper component for use with Qubit Experiences
JavaScript
3
star
31

slapdash

A lightweight JavaScript utility belt with native method override protection
JavaScript
3
star
32

matchete

Super simple string value matching
JavaScript
2
star
33

placement-examples

2
star
34

url-canon

Normalizes URL's to prevent duplicates that point to the same server resource
JavaScript
2
star
35

base64int

Pure JS integer to/from base64 converter
JavaScript
2
star
36

dubber

Advanced DNS zone provisioning from orchestration services.
Go
2
star
37

tlsproxy

A simple tls to unix/tcp proxy, in go.
Go
2
star
38

log-requests

A service that simply logs all requests sent to it
JavaScript
2
star
39

looker-source-block

Looker Block for Qubit Live Tap - Retail
LookML
2
star
40

s3-cnpm

S3 storage wrapper for cnpm
JavaScript
1
star
41

really-unique-id

Produces random ID's on browsers using plugins and cookies for more randomness
JavaScript
1
star
42

prom-config-controller

A kubernetes controller that exposes Prometheus Scrapes and Rule Groups as CRDs
Go
1
star
43

battlesauce

battle test your rest apis with saucelabs
JavaScript
1
star