Init repo
This commit is contained in:
commit
31a54b7389
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target
|
||||
result*
|
1421
Cargo.lock
generated
Normal file
1421
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "berlinerbaeder-exporter"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
axum = "0.7.5"
|
||||
reqwest = { version = "0.12.5", features = ["json"] }
|
||||
serde = { version = "1.0.204", features = ["derive"] }
|
||||
serde_json = "1.0.120"
|
||||
tokio = { version = "1.38.0", features = ["rt-multi-thread"] }
|
27
flake.lock
Normal file
27
flake.lock
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1720768451,
|
||||
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
37
flake.nix
Normal file
37
flake.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
outputs = { self, nixpkgs, ... }: {
|
||||
packages.x86_64-linux = let
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
};
|
||||
in {
|
||||
berlinerbaeder-exporter = pkgs.rustPlatform.buildRustPackage rec {
|
||||
pname = "berlinerbaeder-exporter";
|
||||
version = "0.1.0";
|
||||
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.pkg-config
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
pkgs.openssl
|
||||
];
|
||||
|
||||
cargoLock.lockFile = ./Cargo.lock;
|
||||
|
||||
};
|
||||
default = self.packages.x86_64-linux.berlinerbaeder-exporter;
|
||||
};
|
||||
|
||||
hydraJobs = {
|
||||
inherit (self)
|
||||
packages;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
69
src/main.rs
Normal file
69
src/main.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use axum::{
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
|
||||
use serde::{
|
||||
Deserialize,
|
||||
Serialize,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct TrafficDataThresholds {
|
||||
level: i64,
|
||||
threshold: i64,
|
||||
color: String,
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct TrafficDataItem {
|
||||
id: String,
|
||||
level: i64,
|
||||
color: Option<String>,
|
||||
description: Option<String>,
|
||||
counter: Option<i64>,
|
||||
automatic: bool,
|
||||
thresholds: Vec<TrafficDataThresholds>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let app = Router::new()
|
||||
.route("/", get(route_index))
|
||||
.route("/metrics", get(route_metrics));
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("[::]:3000").await.unwrap();
|
||||
println!("Server listening on: http://{}", listener.local_addr().unwrap());
|
||||
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn route_index() -> String {
|
||||
return String::from("Prometheus exporter for Berlinerbaeder occupancy");
|
||||
}
|
||||
|
||||
async fn route_metrics() -> Result<String, String> {
|
||||
let client = reqwest::Client::new();
|
||||
let trafficdata_req = client.get(String::from("https://www.berlinerbaeder.de/traffic/trafficdata.json"))
|
||||
.send().await
|
||||
.map_err(|_err| String::from("trafficdata API cannot be fetched"))?;
|
||||
|
||||
if trafficdata_req.status() != reqwest::StatusCode::OK {
|
||||
return Err(String::from("Unexpected response from trafficdata API"));
|
||||
}
|
||||
|
||||
let trafficdata_body = trafficdata_req.text().await
|
||||
.map_err(|_err| "Cannot read body of trafficdata API")?;
|
||||
|
||||
let trafficdata: Vec<TrafficDataItem> = serde_json::from_str(trafficdata_body.as_str())
|
||||
.map_err(|err| format!("{}", err))?;
|
||||
|
||||
let mut out = String::new();
|
||||
|
||||
for bad in trafficdata {
|
||||
out.push_str(&format!("berlinerbaeder_occupation{{bad=\"{}\"}} {}\n", bad.id, bad.counter.unwrap_or(-1)));
|
||||
}
|
||||
|
||||
return Ok(out);
|
||||
}
|
Loading…
Reference in New Issue
Block a user