Init repo

This commit is contained in:
clerie 2024-07-14 19:29:03 +02:00
commit 31a54b7389
6 changed files with 1567 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
result*

1421
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

11
Cargo.toml Normal file
View 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
View 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
View 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
View 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);
}