Example Configs
The repository ships a set of ready-to-run config files under
examples/. Each is
shown below verbatim. For the full set of options see
Agent Configuration and Proxy Configuration.
Precedence
Config files are the lowest-precedence source: CLI args → env vars → config file → built-in defaults. See the CLI Reference.
Self-monitoring — simple.conf
Enables admin and metrics on both components and points the agent at the proxy's and agent's
own /metrics endpoints, so the proxy and agent monitor themselves. A good first run on a
single host.
proxy {
admin.debugEnabled = false
admin.enabled: true
metrics.enabled: true
http.requestLoggingEnabled: true
}
agent {
proxy.hostname = localhost
admin.enabled: true
metrics.enabled: true
pathConfigs: [
{
name: "Proxy metrics"
path: proxy_metrics
labels: "{\"key1\": \"value1\", \"key2\": 2}"
url: "http://localhost:8082/metrics"
//url: "http://"${?HOSTNAME}":8082/metrics"
}
{
name: "Agent metrics"
path: agent_metrics
labels: "{\"key3\": \"value3\", \"key4\": 4}"
url: "http://localhost:8083/metrics"
//url: "http://"${?HOSTNAME}":8083/metrics"
}
]
}
Run it with:
java -jar prometheus-proxy.jar --config examples/simple.conf
java -jar prometheus-agent.jar --config examples/simple.conf
Debugging a local run — prom-agent.conf
The same self-monitoring setup as simple.conf, turned up for troubleshooting: the proxy's debug
servlet is enabled on the admin port and the labels are dropped so the output stays readable. Two
toggles are left commented out for when you need them — transportFilterDisabled for running behind
an nginx reverse proxy, and scrapeTimeoutSecs for endpoints slower than the 15-second default.
proxy {
admin.debugEnabled = true
admin.enabled: true
metrics.enabled: true
#transportFilterDisabled = true
http.requestLoggingEnabled: true
}
agent {
//scrapeTimeoutSecs = 16
proxy.hostname = localhost
admin.enabled: true
metrics.enabled: true
#transportFilterDisabled = true
pathConfigs: [
{
name: "Proxy metrics"
path: proxy_metrics
url: "http://localhost:8082/metrics"
}
{
name: "Agent metrics"
path: agent_metrics
url: "http://localhost:8083/metrics"
}
]
}
This is the config behind the bundled Agent (no auth) IntelliJ run configuration in .run/.
Multiple application endpoints — myapps.conf
Three application endpoints, each on its own proxy path and tagged with custom labels. This
is the typical shape of a real agent config.
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"
}
]
}
Prometheus then scrapes /app1_metrics, /app2_metrics, and /app3_metrics from the proxy.
See the Quick Start.
Metric filtering — agent-filters.conf
Drops whole metric families at the agent, before the payload is gzipped, chunked, and sent across
the WAN. Filters live in a top-level agent.filters list keyed by path rather than nested inside
pathConfigs, so a filter applies to that path whether it was registered statically or by dynamic
discovery.
agent {
pathConfigs: [
{
name: "app1"
path: "app1_metrics"
url: "http://app1:9090/metrics"
}
]
// Drop Go runtime GC metrics for app1 before they cross the WAN.
// Regexes are fully anchored, matching Prometheus relabel_config semantics:
// "go_" matches nothing; "go_.*" matches go_gc_duration_seconds.
filters: [
{
path: "app1_metrics"
metricNameAllow: []
metricNameDeny: [ "go_gc_.*", "go_memstats_.*" ]
}
]
}
Regexes are fully anchored, matching Prometheus relabel_config semantics: go_ matches nothing,
while go_.* matches go_gc_duration_seconds. See
Metric Filtering.
Dynamic discovery targets — discovery-targets.conf
Unlike every other file on this page, this one is not passed to --config. It is the targets
file an agent watches when
dynamic target discovery is enabled, so it has a
top-level paths list and no agent { } wrapper. The agent re-reads it every
reconcileIntervalSecs and registers, unregisters, or re-registers paths to match — no restart, and
paths that did not change keep scraping.
// Dynamic target discovery file, referenced by agent.discovery.file.path.
//
// This is a standalone targets file, NOT an agent config -- there is no `agent { }` wrapper here.
// Point an agent at it from that agent's own config:
//
// agent {
// discovery {
// enabled = true
// file.path = "examples/discovery-targets.conf"
// reconcileIntervalSecs = 30
// }
// }
//
// The agent re-reads this file every reconcileIntervalSecs and registers, unregisters, or
// re-registers paths so the live set matches it -- no restart, and paths that did not change keep
// scraping. Static agent.pathConfigs entries are a baseline reconciliation never touches; if a path
// here collides with a static one, the static entry wins and the collision is logged.
//
// JSON is equally valid, since HOCON is a JSON superset -- convenient if this file is generated.
paths = [
// Only `path` and `url` are required: `name` defaults to `path`, `labels` defaults to "{}". An entry whose
// `path` or `url` is blank is skipped when this file is read, reported once, and the rest of the file applies.
{ path = "app1_metrics", url = "http://app1.local:9100/metrics" }
// Full form. `labels` is a JSON *string*, not a nested object; HOCON triple quotes avoid the
// backslash escaping used in the pathConfigs examples.
{
name = "App2 metrics"
path = "app2_metrics"
url = "http://app2.local:9100/metrics"
labels = """{"env": "prod", "team": "platform"}"""
}
]
// `path` must be a single segment: the proxy serves each registered path at /<path>, so a
// multi-segment value like "app/metrics" is rejected at registration. Use "app_metrics".
// Substitutions are resolved, so a generated or environment-driven file can avoid repetition.
// The ${?VAR} form is optional: it overrides the preceding value when set and falls back to it
// when unset. Uncomment to try:
//
// host = "app3.local"
// port = 9100
// port = ${?METRICS_PORT}
//
// paths = [
// { path = "app3_metrics", url = "http://"${host}":"${port}"/metrics" }
// ]
// Removing every discovered path is spelled `paths = []` -- an empty-but-valid file is a real
// instruction and is honored. Deleting or corrupting this file is NOT: an unreadable file is
// treated as a failed read, so the agent logs a warning, skips the tick, and keeps its
// last-known-good set rather than tearing every target down on a bad write.
An agent points at it from its own config:
agent {
discovery {
enabled = true
file.path = "examples/discovery-targets.conf"
reconcileIntervalSecs = 30
}
}
Prometheus federation — federate.conf
Pulls metrics from an existing Prometheus server through its /federate endpoint, exposing
them on a proxy path. See Prometheus Federation.
agent {
pathConfigs: [
{
name: "Federate metrics"
path: federate_metrics
url: "http://prometheus:9090/federate?match[]={job=~'.*'}"
},
{
name: "Agent metrics"
path: agent_metrics
url: "http://localhost:8083/metrics"
}
]
}
Server-only TLS — tls-no-mutual-auth.conf
Encrypts the gRPC channel with a server certificate; the agent verifies the proxy but does not
present a client certificate. Note the non-default agent port 50440 and the
overrideAuthority used to match the test fixture's SAN.
// TLS without mutual authentication: the agent verifies the proxy's certificate, but the proxy does not
// verify agents. If the agent port is reachable by untrusted peers, also configure agent tokens.
//
// The certificates and keys under testing/certs are TEST FIXTURES committed to a public repository, so their
// private keys are not secret. Never use them outside local testing; generate your own for any real deployment.
proxy {
agent.port = 50440
tls {
certChainFilePath = "testing/certs/server1.pem" // Server certificate chain file path
privateKeyFilePath = "testing/certs/server1.key" // Server private key file path
trustCertCollectionFilePath = "" // Trust certificate collection file path
}
}
agent {
proxy {
hostname = "localhost" // Proxy hostname
port = 50440 // Proxy port
}
// Only trustCertCollectionFilePath is required on the client with TLS (no mutual authentication)
tls {
overrideAuthority = "foo.test.google.fr" // Override authority (for testing only)
certChainFilePath = "" // Client certificate chain file path
privateKeyFilePath = "" // Client private key file path
trustCertCollectionFilePath = "testing/certs/ca.pem" // Trust certificate collection file path
}
}
Mutual TLS — tls-with-mutual-auth.conf
Both sides present certificates: the proxy trusts the client CA and the agent supplies its own
certChainFilePath / privateKeyFilePath. This is the recommended production posture.
// TLS with mutual authentication: the agent verifies the proxy's certificate, and the proxy requires a client
// certificate from each agent.
//
// The certificates and keys under testing/certs are TEST FIXTURES committed to a public repository, so their
// private keys are not secret. Never use them outside local testing; generate your own for any real deployment.
proxy {
agent.port = 50440
tls {
certChainFilePath = "testing/certs/server1.pem" // Server certificate chain file path
privateKeyFilePath = "testing/certs/server1.key" // Server private key file path
trustCertCollectionFilePath = "testing/certs/ca.pem" // Trust certificate collection file path
}
}
agent {
proxy {
hostname = "localhost" // Proxy hostname
port = 50440 // Proxy port
}
// With mutual authentication the client also presents its own certificate chain and private key
tls {
overrideAuthority = "foo.test.google.fr" // Override authority (for testing only)
certChainFilePath = "testing/certs/client.pem" // Client certificate chain file path
privateKeyFilePath = "testing/certs/client.key" // Client private key file path
trustCertCollectionFilePath = "testing/certs/ca.pem" // Trust certificate collection file path
}
}
See TLS Setup for generating certificates and the full TLS option set.