Skip to content

Commit

Permalink
πŸ‘±πŸ»β€β™€οΈ Monika: Experimental OpenTelemetry support
Browse files Browse the repository at this point in the history
This commit tells Monika to expose the `free_space` metric for each monitored path using the *OpenTelemetry SDK for Java*.
  • Loading branch information
mkarg committed Jun 22, 2024
1 parent 9a1a836 commit cd6d1dd
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 11 deletions.
2 changes: 1 addition & 1 deletion build
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ cp src/main/docker/Dockerfile target
pushd ./target
docker build -t monika .
popd
docker run -it --rm -P monika
docker run -it --rm -P -e OTEL_JAVA_GLOBAL_AUTOCONFIGURE_ENABLED=True -e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf -e OTEL_EXPORTER_OTLP_ENDPOINT=https://grafana.ijug.eu:8080/otlp -e OTEL_SERVICE_NAME=Monika -e OTEL_METRIC_EXPORT_INTERVAL=15000 -e OTEL_METRICS_EXPORTER=otlp -e OTEL_LOGS_EXPORTER=none -e OTEL_TRACES_EXPORTER=none monika

35 changes: 35 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<maven.compiler.release>17</maven.compiler.release>
<jaxrs.version>3.1.0</jaxrs.version>
<jersey.version>3.1.7</jersey.version>
<otelsdk.version>1.39.0</otelsdk.version>
</properties>

<dependencyManagement>
Expand All @@ -23,6 +24,14 @@
<type>pom</type>
<scope>import</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>${otelsdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -50,6 +59,26 @@
<artifactId>jersey-netty-connector</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-logging</artifactId>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -117,6 +146,12 @@
<exclude>**/*.so</exclude>
</excludes>
</filter>
<filter>
<artifact>io.opentelemetry:*</artifact>
<includes>
<include>**/*</include>
</includes>
</filter>
</filters>
<transformers>
<transformer
Expand Down
45 changes: 35 additions & 10 deletions src/main/java/MonikaBootstrap.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import static jakarta.ws.rs.core.Response.Status.Family.REDIRECTION;
import static jakarta.ws.rs.core.Response.Status.Family.SUCCESSFUL;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
Expand All @@ -16,6 +23,32 @@
import jakarta.ws.rs.core.UriBuilder;

public class MonikaBootstrap {

private static final Collection<Path> mp;
static {
final var meter = GlobalOpenTelemetry.getMeter("eu.ijug.free_disk_space");
final var monitoredPaths = System.getenv("MONITORED_PATHS");
mp = monitoredPaths == null || monitoredPaths.isBlank() ? Set.of(Path.of("/"))
: Arrays.asList(monitoredPaths.split(File.pathSeparator)).stream().map(Path::of).toList();
assert mp != null && !mp.isEmpty() : "Monitored paths cannot be null nor empty";
mp.forEach(monitoredPath -> System.out.printf("Monitoring: %s%n", monitoredPath));
meter.gaugeBuilder("system.filesystem.free")
.setDescription("Free disk space (measured in percent)")
.setUnit("Percent")
.buildWithCallback(measurement -> {
mp.forEach(monitoredPath -> {
try {
final var fileStore = Files.getFileStore(monitoredPath);
final var percentFree = Math.toIntExact(100 * fileStore.getUsableSpace() / fileStore.getTotalSpace());
System.out.printf("%s is %d %% free%n", monitoredPath, percentFree);
measurement.record(percentFree, Attributes.of(AttributeKey.stringKey("system.filesystem.mountpoint"), monitoredPath.toString()));
} catch (final IOException e) {
e.printStackTrace();
}
});
});
}

public static void main(final String[] args) throws InterruptedException, ExecutionException {
final var port = Integer.parseInt(System.getenv().getOrDefault("IP_PORT", "8080"));

Expand Down Expand Up @@ -57,15 +90,7 @@ public Set<Class<?>> getClasses() {
return Set.of(MonikaResource.class);
}

private static final Map<String, Object> PROPERTIES;
static {
final var monitoredPaths = System.getenv("MONITORED_PATHS");

final var mp = monitoredPaths == null || monitoredPaths.isBlank() ? Set.of(Path.of("/"))
: Arrays.asList(monitoredPaths.split(File.pathSeparator)).stream().map(Path::of).toList();
mp.forEach(monitoredPath -> System.out.printf("Monitoring: %s%n", monitoredPath));
PROPERTIES = Map.of("MONITORED_PATHS", mp);
}
private static final Map<String, Object> PROPERTIES = Map.of("MONITORED_PATHS", mp);

@Override
public Map<String, Object> getProperties() {
Expand All @@ -81,7 +106,7 @@ private static HEALTH checkHealth(final int port, final boolean ignoreErrors) {
System.out.println("HEALTHCHECK " + uri);
if (!EnumSet.of(SUCCESSFUL, REDIRECTION).contains(ClientBuilder.newClient().target(uri).request().get().getStatusInfo().getFamily()))
throw new WebApplicationException();

System.out.println("HEALTHY");
return HEALTH.SUCCESS;
} catch (final Throwable t) {
Expand Down

0 comments on commit cd6d1dd

Please sign in to comment.