Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/content/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,13 @@ Exporter OpenTelemetry Properties
(3) Format: `key1=value1,key2=value2`

Many of these attributes can alternatively be configured via OpenTelemetry environment variables, like `OTEL_EXPORTER_OTLP_ENDPOINT`. The Prometheus metrics library has support for OpenTelemetry environment variables. See Javadoc for details.

Exporter PushGateway Properties
-------------------------------

| Name | Javadoc | Note |
|--------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|------|
| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#address(java.lang.String)) | |
| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#scheme(java.lang.String)) | |
| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#job(java.lang.String)) | |

103 changes: 103 additions & 0 deletions docs/content/exporters/pushgateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: Pushgateway
weight: 5
---

The [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) exists to allow ephemeral and batch jobs to expose their metrics to Prometheus.
Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics to a Pushgateway.
The Pushgateway then exposes these metrics to Prometheus.

The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) Java class allows you to push metrics to a Prometheus Pushgateway.

Example
-------

{{< tabs "uniqueid" >}}
{{< tab "Gradle" >}}
```
implementation 'io.prometheus:prometheus-metrics-core:1.3.0'
implementation 'io.prometheus:prometheus-metrics-exporter-pushgateway:1.3.0'
```
{{< /tab >}}
{{< tab "Maven" >}}
```xml
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-core</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-exporter-pushgateway</artifactId>
<version>1.3.0</version>
</dependency>
```
{{< /tab >}}
{{< /tabs >}}

```java
public class ExampleBatchJob {

private static PushGateway pushGateway = PushGateway.builder()
.address("localhost:9091") // not needed as localhost:9091 is the default
.job("example")
.build();

private static Gauge dataProcessedInBytes = Gauge.builder()
.name("data_processed")
.help("data processed in the last batch job run")
.unit(Unit.BYTES)
.register();

public static void main(String[] args) throws Exception {
try {
long bytesProcessed = processData();
dataProcessedInBytes.set(bytesProcessed);
} finally {
pushGateway.push();
}
}

public static long processData() {
// Imagine a batch job here that processes data
// and returns the number of Bytes processed.
return 42;
}
}
```

Basic Auth
----------

The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports basic authentication.

```java
PushGateway pushGateway = PushGateway.builder()
.job("example")
.basicAuth("my_user", "my_password")
.build();
```

The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this.

SSL
---

The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports SSL.

```java
PushGateway pushGateway = PushGateway.builder()
.job("example")
.scheme(Scheme.HTTPS)
.build();
```

However, this requires that the JVM can validate the server certificate.

If you want to skip certificate verification, you need to provide your own [HttpConnectionFactory](/client_java/api/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.html).
The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this.

Configuration Properties
------------------------

The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports a couple of properties that can be configured at runtime. See [config](../../config/config).
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static Volume create(String prefix) throws IOException, URISyntaxExceptio

/**
* Copy a file or directory to this volume.
* @param src is reltive to {@code ./target/}
* @param src is relative to {@code ./target/}
*/
public Volume copy(String src) throws IOException {
Path srcPath = tmpDir.getParent().resolve(src);
Expand Down
98 changes: 98 additions & 0 deletions integration-tests/it-pushgateway/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.prometheus</groupId>
<artifactId>integration-tests</artifactId>
<version>1.3.0-SNAPSHOT</version>
</parent>

<artifactId>it-pushgateway</artifactId>

<name>Integration Test - Pushgateway</name>
<url>http://github.com/prometheus/client_java</url>
<description>
Integration tests for the Pushgateway Exporter
</description>

<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<developers>
<developer>
<id>fstab</id>
<name>Fabian Stäber</name>
<email>[email protected]</email>
</developer>
</developers>

<dependencies>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>prometheus-metrics-exporter-pushgateway</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>it-common</artifactId>
<type>test-jar</type>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<finalName>pushgateway-test-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>io.prometheus.metrics.it.pushgateway.PushGatewayTestApp</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package io.prometheus.metrics.it.pushgateway;

import io.prometheus.metrics.core.metrics.Gauge;
import io.prometheus.metrics.core.metrics.Histogram;
import io.prometheus.metrics.exporter.pushgateway.Format;
import io.prometheus.metrics.exporter.pushgateway.HttpConnectionFactory;
import io.prometheus.metrics.exporter.pushgateway.PushGateway;
import io.prometheus.metrics.model.snapshots.Unit;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS;

/**
* Example application using the {@link PushGateway}.
*/
public class PushGatewayTestApp {

public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java -jar pushgateway-test-app.jar <test>");
System.exit(-1);
}
switch (args[0]) {
case "simple":
runSimpleTest();
break;
case "textFormat":
runTextFormatTest();
break;
case "basicauth":
runBasicAuthTest();
break;
case "ssl":
runSslTest();
break;
default:
System.err.println(args[0] + ": Not implemented.");
System.exit(-1);
}
}

private static void runSimpleTest() throws IOException {
makeMetrics();
PushGateway pg = PushGateway.builder().build();
System.out.println("Pushing metrics...");
pg.push();
System.out.println("Push successful.");
}

private static void runTextFormatTest() throws IOException {
makeMetrics();
PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build();
System.out.println("Pushing metrics...");
pg.push();
System.out.println("Push successful.");
}

private static void runBasicAuthTest() throws IOException {
makeMetrics();
PushGateway pg = PushGateway.builder()
.basicAuth("my_user", "secret_password")
.build();
System.out.println("Pushing metrics...");
pg.push();
System.out.println("Push successful.");
}

private static void runSslTest() throws IOException {
makeMetrics();
PushGateway pg = PushGateway.builder()
.scheme(HTTPS)
.connectionFactory(insecureConnectionFactory)
.build();
System.out.println("Pushing metrics...");
pg.push();
System.out.println("Push successful.");
}

static TrustManager insecureTrustManager = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
};

static HttpConnectionFactory insecureConnectionFactory = url -> {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{insecureTrustManager}, null);
SSLContext.setDefault(sslContext);

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setHostnameVerifier((hostname, session) -> true);
return connection;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
throw new RuntimeException(e);
}
};

private static void makeMetrics() {
Histogram sizes = Histogram.builder()
.name("file_sizes_bytes")
.classicUpperBounds(256, 512, 1024, 2048)
.unit(Unit.BYTES)
.register();
sizes.observe(513);
sizes.observe(814);
sizes.observe(1553);
Gauge duration = Gauge.builder()
.name("my_batch_job_duration_seconds")
.help("Duration of my batch job in seconds.")
.unit(Unit.SECONDS)
.register();
duration.set(0.5);
}
}
Loading