Initial commit.
This commit is contained in:
commit
61274350d5
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
.kotlin
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
.idea/*.xml
|
||||
.idea/*
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM amazoncorretto:17.0.14-alpine3.21
|
||||
LABEL authors="fey"
|
||||
WORKDIR /app
|
||||
COPY . /app/
|
||||
RUN apk add maven
|
||||
RUN mvn dependency:resolve-plugins dependency:go-offline -B
|
||||
RUN mvn compile package
|
||||
EXPOSE 9400
|
||||
ENTRYPOINT mvn -o exec:java
|
||||
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Octonet Exporter
|
||||
|
||||
This is a Java application that exports metrics from a Digital Devices OctopusNET to Prometheus.
|
||||
|
||||
## How to run?
|
||||
|
||||
* Option 1: Set the OCTONET_IP environment variable to the IP address of your OctopusNET device and run the application using `mvn exec:java`.
|
||||
* Option 2: There's are pre-built binary supplied in the download archive. You can use this by setting the OCTONET_IP environment variable to the IP address of your OctopusNET device and then run the application using `java -jar octonet-exporter-1.0-SNAPSHOT-jar-with-dependencies.jar`.
|
||||
* Option 3 (recommended): Use the provided Dockerfile to build a container and run this application in Docker or Podman. Don't forget to supply an `-e OCTONET_IP=<your_octonet_ip>` to the container.
|
||||
|
||||
## How to compile a binary?
|
||||
|
||||
To compile a binary, run `mvn clean compile assembly:single` in the project directory. This will create a JAR file in the `target` directory that you can run using `java -jar octonet-exporter-1.0-SNAPSHOT-jar-with-dependencies.jar`.
|
||||
75
pom.xml
Normal file
75
pom.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<?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>
|
||||
|
||||
<groupId>moe.yo3explorer</groupId>
|
||||
<artifactId>octonet-exporter</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.25.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>5.0.0-alpha.12</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.prometheus</groupId>
|
||||
<artifactId>prometheus-metrics-core</artifactId>
|
||||
<version>1.3.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.prometheus</groupId>
|
||||
<artifactId>prometheus-metrics-exporter-httpserver</artifactId>
|
||||
<version>1.3.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.17.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>moe.yo3explorer.octonet_exporter.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<mainClass>moe.yo3explorer.octonet_exporter.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
121
src/main/java/moe/yo3explorer/octonet_exporter/Main.java
Normal file
121
src/main/java/moe/yo3explorer/octonet_exporter/Main.java
Normal file
@ -0,0 +1,121 @@
|
||||
package moe.yo3explorer.octonet_exporter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.prometheus.metrics.core.metrics.Gauge;
|
||||
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
|
||||
import moe.yo3explorer.octonet_exporter.entities.FanspeedResponse;
|
||||
import moe.yo3explorer.octonet_exporter.entities.Tuner;
|
||||
import moe.yo3explorer.octonet_exporter.entities.TunerResponse;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
private static final Logger log = LogManager.getLogger(Main.class);
|
||||
|
||||
private static boolean safeSleep()
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
return true;
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Logger logger = LogManager.getLogger(Main.class);
|
||||
logger.info("Hello! This is octonet_exporter!");
|
||||
Map<String, String> getenv = System.getenv();
|
||||
if (!getenv.containsKey("OCTONET_IP"))
|
||||
{
|
||||
logger.error("OCTONET_IP environment variable is not set");
|
||||
System.exit(1);
|
||||
}
|
||||
String octonetIp = getenv.get("OCTONET_IP");
|
||||
logger.info("Octonet IP: " + octonetIp);
|
||||
|
||||
HTTPServer server = HTTPServer.builder()
|
||||
.hostname("0.0.0.0")
|
||||
.port(9401)
|
||||
.buildAndStart();
|
||||
logger.info("Server started on port 9401");
|
||||
|
||||
String fanspeedUrl = "http:/%s/system/fanspeed?_=%d";
|
||||
String temperaturUrl = "http://%s/log/Temperatur.log?_=%d";
|
||||
String tunerstatusUrl = "http://%s/octoserve/tunerstatus.json";
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Gauge fanspeed = Gauge.builder().name("octonetExporter_fanspeed").help("Fan speed").register();
|
||||
Gauge temperature = Gauge.builder().name("octonetExporter_temperature").help("Temperature").register();
|
||||
Gauge locked = Gauge.builder().name("octonetExporter_locked").help("Is the tuner locked?").labelNames("input").register();
|
||||
Gauge strength = Gauge.builder().name("octonetExporter_strength").help("Signal strength").labelNames("input").register();
|
||||
Gauge snr = Gauge.builder().name("octonetExporter_snr").help("Signal to noise ratio").labelNames("input").register();
|
||||
Gauge quality = Gauge.builder().name("octonetExporter_quality").help("Signal quality").labelNames("input").register();
|
||||
Gauge level = Gauge.builder().name("octonetExporter_level").help("Signal level").labelNames("input").register();
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder().build();
|
||||
int state = 1;
|
||||
while (state != Integer.MAX_VALUE)
|
||||
{
|
||||
if (state == 1)
|
||||
{
|
||||
logger.info("Starting scraping loop...");
|
||||
state++;
|
||||
}
|
||||
Request request = new Request.Builder().url(String.format(fanspeedUrl,octonetIp,System.currentTimeMillis())).build();
|
||||
Call call = client.newCall(request);
|
||||
Response execute = call.execute();
|
||||
String string = execute.body().string();
|
||||
FanspeedResponse fanspeedResponse = objectMapper.readValue(string, FanspeedResponse.class);
|
||||
fanspeed.set(fanspeedResponse.speed);
|
||||
if (!safeSleep())
|
||||
break;
|
||||
|
||||
request = new Request.Builder().url(String.format(temperaturUrl,octonetIp,System.currentTimeMillis())).build();
|
||||
call = client.newCall(request);
|
||||
execute = call.execute();
|
||||
string = execute.body().string();
|
||||
StringReader stringReader = new StringReader(string);
|
||||
BufferedReader bufferedReader = new BufferedReader(stringReader);
|
||||
String headLine = bufferedReader.readLine();
|
||||
String temperatureString = bufferedReader.readLine();
|
||||
bufferedReader.close();
|
||||
stringReader.close();
|
||||
temperature.set(Double.parseDouble(temperatureString));
|
||||
if (!safeSleep())
|
||||
break;
|
||||
|
||||
request = new Request.Builder().url(String.format(tunerstatusUrl,octonetIp)).build();
|
||||
call = client.newCall(request);
|
||||
execute = call.execute();
|
||||
string = execute.body().string();
|
||||
TunerResponse tunerResponse = objectMapper.readValue(string, TunerResponse.class);
|
||||
for (Tuner tuner : tunerResponse.getTunerList())
|
||||
{
|
||||
locked.labelValues(tuner.getInput()).set(tuner.isLock() ? 1 : 0);
|
||||
strength.labelValues(tuner.getInput()).set(tuner.isLock() ? ((double)(tuner.getStrength() + 108750) / 1000.0) : 0.0);
|
||||
snr.labelValues(tuner.getInput()).set((double)tuner.getSnr() / 1000.0);
|
||||
quality.labelValues(tuner.getInput()).set(tuner.getQuality());
|
||||
level.labelValues(tuner.getInput()).set(tuner.getLevel());
|
||||
}
|
||||
if (!safeSleep())
|
||||
break;
|
||||
if (state == 2)
|
||||
{
|
||||
logger.info("Scraping loop successfully started.");
|
||||
state++;
|
||||
}
|
||||
}
|
||||
|
||||
logger.warn("Scraping loop stopped.");
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package moe.yo3explorer.octonet_exporter.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class FanspeedResponse
|
||||
{
|
||||
@JsonProperty("speed")
|
||||
public int speed;
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package moe.yo3explorer.octonet_exporter.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class Tuner {
|
||||
@JsonProperty("Input")
|
||||
private String input;
|
||||
|
||||
@JsonProperty("Status")
|
||||
private String status;
|
||||
|
||||
@JsonProperty("Lock")
|
||||
private boolean lock;
|
||||
|
||||
@JsonProperty("Strength")
|
||||
private long strength;
|
||||
|
||||
@JsonProperty("SNR")
|
||||
private int snr;
|
||||
|
||||
@JsonProperty("Quality")
|
||||
private int quality;
|
||||
|
||||
@JsonProperty("Level")
|
||||
private int level;
|
||||
|
||||
// Getters and Setters
|
||||
public String getInput() { return input; }
|
||||
public String getStatus() { return status; }
|
||||
public boolean isLock() { return lock; }
|
||||
public long getStrength() { return strength; }
|
||||
public int getSnr() { return snr; }
|
||||
public int getQuality() { return quality; }
|
||||
public int getLevel() { return level; }
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package moe.yo3explorer.octonet_exporter.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
|
||||
public class TunerResponse {
|
||||
@JsonProperty("TunerList")
|
||||
private List<Tuner> tunerList;
|
||||
|
||||
public List<Tuner> getTunerList() {
|
||||
return tunerList;
|
||||
}
|
||||
|
||||
public void setTunerList(List<Tuner> tunerList) {
|
||||
this.tunerList = tunerList;
|
||||
}
|
||||
}
|
||||
17
src/main/resources/log4j2.xml
Normal file
17
src/main/resources/log4j2.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration xmlns="https://logging.apache.org/xml/ns"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
https://logging.apache.org/xml/ns
|
||||
https://logging.apache.org/xml/ns/log4j-config-2.xsd">
|
||||
<Appenders>
|
||||
<Console name="CONSOLE">
|
||||
<PatternLayout pattern="%p - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="CONSOLE" level="DEBUG"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
Loading…
x
Reference in New Issue
Block a user