Home

Awesome

Prometheus Proxy

JitPack Build Status codebeat badge Codacy Badge codecov Coverage Status Kotlin ktlint

Prometheus is an excellent systems monitoring and alerting toolkit, which uses a pull model for collecting metrics. The pull model is problematic when a firewall separates a Prometheus server and its metrics endpoints. Prometheus Proxy enables Prometheus to reach metrics endpoints running behind a firewall and preserves the pull model.

The prometheus-proxy runtime comprises 2 services:

Here's a simplified network diagram of how the deployed proxy and agent work:

network diagram

Endpoints running behind a firewall require a prometheus-agent (the agent) to be run inside the firewall. An agent can run as a stand-alone server, embedded in another java server, or as a java agent. Agents connect to a prometheus-proxy (the proxy) and register the paths for which they will provide data. One proxy can work one or many agents.

Requirements

Requires Java 11 or newer.

CLI Usage

Download the proxy and agent uber-jars from here.

Start a proxy with:

java -jar prometheus-proxy.jar

Start an agent with:

java -jar prometheus-agent.jar -Dagent.proxy.hostname=mymachine.local --config https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/myapps.conf

If the prometheus-proxy were running on a machine named mymachine.local and the agent.pathConfigs value in the myapps.conf config file had the contents:

agent {
  pathConfigs: [
    {
      name: "App1 metrics"
      path: app1_metrics
      labels: "{\"key1\": \"value1\", \"key2\": 2}"
      url: "http://app1.local:9100/metrics"
    },
    {
      name: "App2 metrics"
      path: app2_metrics
      labels: "{\"key3\": \"value3\", \"key4\": 4}"
      url: "http://app2.local:9100/metrics"
    },
    {
      name: "App3 metrics"
      path: app3_metrics
      labels: "{\"key5\": \"value5\", \"key6\": 6}"
      url: "http://app3.local:9100/metrics"
    }
  ]
}

then the prometheus.yml scrape_config would target the three apps with:

If the endpoints were restricted with basic auth/bearer authentication, you could either include the basic-auth credentials in the URL with: http://user:pass@hostname/metrics or they could be configured with basic_auth/bearer_token in the scrape-config.

The prometheus.yml file would include:

scrape_configs:
  - job_name: 'app1 metrics'
    metrics_path: '/app1_metrics'
    bearer_token: 'eyJ....hH9rloA'
    static_configs:
      - targets: [ 'mymachine.local:8080' ]
  - job_name: 'app2 metrics'
    metrics_path: '/app2_metrics'
    basic_auth:
        username: 'user'
        password: 's3cr3t'
    static_configs:
      - targets: [ 'mymachine.local:8080' ]
  - job_name: 'app3 metrics'
    metrics_path: '/app3_metrics'
    static_configs:
      - targets: [ 'mymachine.local:8080' ]

Docker Usage

The docker images are available via:

docker pull pambrose/prometheus-proxy:1.23.1
docker pull pambrose/prometheus-agent:1.23.1

Start a proxy container with:

docker run --rm -p 8082:8082 -p 8092:8092 -p 50051:50051 -p 8080:8080 \
        --env ADMIN_ENABLED=true \
        --env METRICS_ENABLED=true \
        pambrose/prometheus-proxy:1.23.1

Start an agent container with:

docker run --rm -p 8083:8083 -p 8093:8093 \
        --env AGENT_CONFIG='https://raw.githubusercontent.com/pambrose/prometheus-proxy/master/examples/simple.conf' \
        pambrose/prometheus-agent:1.23.1

Using the config file simple.conf, the proxy and the agent metrics would be available from the proxy on localhost at:

If you want to use a local config file with a docker container (instead of the above HTTP-served config file), use the docker mount option. Assuming the config file prom-agent.conf is in your current directory, run an agent container with:

docker run --rm -p 8083:8083 -p 8093:8093 \
    --mount type=bind,source="$(pwd)"/prom-agent.conf,target=/app/prom-agent.conf \
    --env AGENT_CONFIG=prom-agent.conf \
    pambrose/prometheus-agent:1.23.1

Note: The WORKDIR of the proxy and agent images is /app, so make sure to use /app as the base directory in the target for --mount options.

Embedded Agent Usage

If you are running a JVM-based program, you can run with the agent embedded directly in your app and not use an external agent:

EmbeddedAgentInfo agentInfo = startAsyncAgent("configFile.conf", true);

Configuration

The proxy and agent use the Typesafe Config library for configuration. Highlights include:

All the proxy and agent properties are described here. The only required argument is an agent config value, which should have an agent.pathConfigs value.

Proxy CLI Options

OptionsENV VAR<br>PropertyDefaultDescription
--config, -cPROXY_CONFIGAgent config file or url
--port, -pPROXY_PORT <br> proxy.http.port8080Proxy listen port
--agent_port, -aAGENT_PORT <br> proxy.agent.port50051gRPC listen port for agents
--admin, -rADMIN_ENABLED <br> proxy.admin.enabledfalseEnable admin servlets
--admin_port, -iADMIN_PORT <br> proxy.admin.port8092Admin servlets port
--debug, -bDEBUG_ENABLED <br> proxy.admin.debugEnabledfalseEnable proxy debug servlet<br>on admin port
--metrics, -eMETRICS_ENABLED <br> proxy.metrics.enabledfalseEnable proxy metrics
--metrics_port, -mMETRICS_PORT <br> proxy.metrics.port8082Proxy metrics listen port
--sd_enabledSD_ENABLED <br> proxy.service.discovery.enabledfalseService discovery endpoint enabled
--sd_pathSD_PATH <br> proxy.service.discovery.path"discovery"Service discovery endpoint path
--sd_target_prefixSD_TARGET_PREFIX <br> proxy.service.discovery.targetPrefix"http://localhost:8080/"Service discovery target prefix
--tf-disabledTRANSPORT_FILTER_DISABLED <br> proxy.transportFilterDisabledfalseTransport filter disabled
--ref-disabledREFLECTION_DISABLED <br> proxy.reflectionDisabledfalsegRPC Reflection disabled
--cert, -tCERT_CHAIN_FILE_PATH <br> proxy.tls.certChainFilePathCertificate chain file path
--key, -kPRIVATE_KEY_FILE_PATH <br> proxy.tls.privateKeyFilePathPrivate key file path
--trust, -sTRUST_CERT_COLLECTION_FILE_PATH <br> proxy.tls.trustCertCollectionFilePathTrust certificate collection file path
--version, -vPrint version info and exit
--usage, -uPrint usage message and exit
-DDynamic property assignment

Agent CLI Options

OptionsENV VAR<br>PropertyDefaultDescription
--config, -cAGENT_CONFIGAgent config file or url (required)
--proxy, -pPROXY_HOSTNAME <br> agent.proxy.hostnameProxy hostname (can include :port)
--name, -nAGENT_NAME <br> agent.nameAgent name
--admin, -rADMIN_ENABLED <br> agent.admin.enabledfalseEnable admin servlets
--admin_port, -iADMIN_PORT <br> agent.admin.port8093Admin servlets port
--debug, -bDEBUG_ENABLED <br> agent.admin.debugEnabledfalseEnable agent debug servlet<br>on admin port
--metrics, -eMETRICS_ENABLED <br> agent.metrics.enabledfalseEnable agent metrics
--metrics_port, -mMETRICS_PORT <br> agent.metrics.port8083Agent metrics listen port
--consolidated, -oCONSOLIDATED <br> agent.consolidatedfalseEnable multiple agents per registered path
--timeoutSCRAPE_TIMEOUT_SECS <br> agent.scrapeTimeoutSecs15Scrape timeout time (seconds)
--max_retriesSCRAPE_MAX_RETRIES <br> agent.scrapeMaxRetries0Scrape maximum retries (0 disables scrape retries)
--chunkCHUNK_CONTENT_SIZE_KBS <br> agent.chunkContentSizeKbs32Threshold for chunking data to Proxy and buffer size (KBs)
--gzipMIN_GZIP_SIZE_BYTES <br> agent.minGzipSizeBytes1024Minimum size for content to be gzipped (bytes)
--tf-disabledTRANSPORT_FILTER_DISABLED <br> agent.transportFilterDisabledfalseTransport filter disabled
--trust_all_x509TRUST_ALL_X509_CERTIFICATES <br> agent.http.enableTrustAllX509CertificatesfalseDisable SSL verification for agent https endpoints
--cert, -tCERT_CHAIN_FILE_PATH <br> agent.tls.certChainFilePathCertificate chain file path
--key, -kPRIVATE_KEY_FILE_PATH <br> agent.tls.privateKeyFilePathPrivate key file path
--trust, -sTRUST_CERT_COLLECTION_FILE_PATH <br> agent.tls.trustCertCollectionFilePathTrust certificate collection file path
--overrideOVERRIDE_AUTHORITY <br> agent.tls.overrideAuthorityOverride authority (for testing)
--version, -vPrint version info and exit
--usage, -uPrint usage message and exit
-DDynamic property assignment

Misc notes:

Admin Servlets

These admin servlets are available when the admin servlet is enabled:

The admin servlets can be enabled with the ADMIN_ENABLED environment var, the --admin CLI option, or with the proxy.admin.enabled and agent.admin.enabled properties.

The debug servlet can be enabled with the DEBUG_ENABLED environment var, the --debug CLI option , or with the proxy.admin.debugEnabled and agent.admin.debugEnabled properties. The debug servlet requires that the admin servlets are enabled. The debug servlet is at: /debug on the admin port.

Descriptions of the servlets are here. The path names can be changed in the configuration file. To disable an admin servlet, assign its property path to "".

Adding TLS to Agent-Proxy Connections

Agents connect to a proxy using gRPC. gRPC supports TLS with or without mutual authentication. The necessary certificate and key file paths can be specified via CLI args, environment variables and configuration file settings.

The gRPC docs describe how to set up TLS. The repo includes the certificates and keys necessary to test TLS support.

Running TLS without mutual authentication requires these settings:

Running TLS with mutual authentication requires these settings:

Running with TLS

Run a proxy and an agent with TLS (no mutual auth) using the included testing certs and keys with:

java -jar prometheus-proxy.jar --config examples/tls-no-mutual-auth.conf
java -jar prometheus-agent.jar --config examples/tls-no-mutual-auth.conf

Run a proxy and an agent docker container with TLS (no mutual auth) using the included testing certs and keys with:

docker run --rm -p 8082:8082 -p 8092:8092 -p 50440:50440 -p 8080:8080 \
    --mount type=bind,source="$(pwd)"/testing/certs,target=/app/testing/certs \
    --mount type=bind,source="$(pwd)"/examples/tls-no-mutual-auth.conf,target=/app/tls-no-mutual-auth.conf \
    --env PROXY_CONFIG=tls-no-mutual-auth.conf \
    --env ADMIN_ENABLED=true \
    --env METRICS_ENABLED=true \
    pambrose/prometheus-proxy:1.23.1

docker run --rm -p 8083:8083 -p 8093:8093 \
    --mount type=bind,source="$(pwd)"/testing/certs,target=/app/testing/certs \
    --mount type=bind,source="$(pwd)"/examples/tls-no-mutual-auth.conf,target=/app/tls-no-mutual-auth.conf \
    --env AGENT_CONFIG=tls-no-mutual-auth.conf \
    --env PROXY_HOSTNAME=mymachine.lan:50440 \
    --name docker-agent \
    pambrose/prometheus-agent:1.23.1

Note: The WORKDIR of the proxy and agent images is /app, so make sure to use /app as the base directory in the target for --mount options.

Scraping HTTPS Endpoints

Disable SSL verification for agent https endpoints with the TRUST_ALL_X509_CERTIFICATES environment var, the --trust_all_x509 CLI option, or the agent.http.enableTrustAllX509Certificates property.

Scraping a Prometheus Instance

It's possible to scrape an existing prometheus server using the /federate endpoint. This enables using the existing service discovery features already built into Prometheus.

An example config can be found in federate.conf.

Nginx Support

To use the prometheus_proxy with nginx as a reverse proxy, disable the transport filter with the TRANSPORT_FILTER_DISABLED environment var, the --tf-disabled CLI option, or the agent.transportFilterDisabled/ proxy.transportFilterDisabled properties. Agents and the Proxy must run with the same transporFilterDisabled value.

When using transporFilterDisabled, you will not see agent contexts immediately removed from the proxy when agents are terminated. Instead, agent contexts will be removed from the proxy after they age out from inactivity. The maximum age is controlled by the proxy.internal.maxAgentInactivitySecs value. The default value is 1 minute.

An example nginx conf file is here and an example agent/proxy conf file is here

gRPC Reflection

The gRPC Reflection service is enabled by default.

To disable gRPC Reflection support, set the REFLECTION_DISABLED environment var, the --reflection_disabled CLI option, or the proxy.reflectionDisabled property to true.

To use grpcurl to test the reflection service, run:

grpcurl -plaintext localhost:50051 list

If you use the grpcurl -plaintext option, make sure that you run the proxy in plaintext mode, i.e., do not define any TLS properties.

Grafana

Grafana dashboards for the proxy and agent are here.

Related Links