Hinzufügen von der aktuellen Statisken der einzelnen Benutzern

This commit is contained in:
Simon Rieger 2025-03-09 23:39:38 +01:00
parent 1136ac0b01
commit 158db4da66
2 changed files with 179 additions and 36 deletions

100
README.md Normal file
View file

@ -0,0 +1,100 @@
# Träwelling Prometheus Exporter
## Beschreibung
Dieser Prometheus Exporter sammelt Daten von der Träwelling API und stellt sie als Prometheus-Metriken zur Verfügung. Er bietet detaillierte Informationen über Fahrten, einschließlich Gesamtfahrzeit, Gesamtpunkte und Gesamtentfernung für jeden Benutzer.
## Funktionen
- Abfrage der Träwelling API für aktuelle Fahrtdaten
- Bereitstellung von Prometheus-Metriken für:
- Gesamtfahrzeit pro Benutzer
- Gesamtpunkte pro Benutzer
- Gesamtentfernung pro Benutzer
- Konsolenausgabe detaillierter Fahrtinformationen
- Regelmäßige Aktualisierung der Daten (alle 5 Minuten)
## Voraussetzungen
- Go 1.15 oder höher
- Docker und Docker Compose (für containerisierte Ausführung)
- Gültiger Träwelling API-Token
## Installation
1. Klone das Repository:
```
git clone https://github.com/yourusername/traewelling-prometheus-exporter.git
cd traewelling-prometheus-exporter
```
2. Installiere die erforderlichen Go-Pakete:
```
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promauto
go get github.com/prometheus/client_golang/prometheus/promhttp
```
3. Erstelle eine `.env` Datei im Projektverzeichnis und füge deinen Träwelling API-Token hinzu:
```
TRAEWELLING_TOKEN=your_token_here
```
## Ausführung
### Lokale Ausführung
1. Baue die Anwendung:
```
go build -o traewelling-exporter
```
2. Führe die Anwendung aus:
```
./traewelling-exporter
```
### Mit Docker
1. Baue das Docker-Image:
```
docker-compose build
```
2. Starte den Container:
```
docker-compose up -d
```
## Verwendung
Nach dem Start ist der Exporter unter `http://localhost:8080/metrics` erreichbar. Prometheus kann so konfiguriert werden, dass es diese Endpunkt abfragt.
## Prometheus Konfiguration
Füge folgende Job-Konfiguration zu deiner `prometheus.yml` hinzu:
```
scrape_configs:
- job_name: 'traewelling'
static_configs:
- targets: ['localhost:8080']
```
## Metriken
- `traewelling_total_trip_duration_minutes`: Gesamtfahrzeit eines Benutzers in Minuten
- `traewelling_total_trip_points`: Gesamtpunkte eines Benutzers
- `traewelling_total_trip_distance_km`: Gesamtentfernung eines Benutzers in Kilometern
## Beitragen
Beiträge sind willkommen! Bitte erstelle ein Issue oder einen Pull Request für Verbesserungsvorschläge oder Fehlerbehebungen.
## Lizenz
[MIT License](LICENSE)
## Kontakt
Bei Fragen oder Problemen erstelle bitte ein GitHub Issue oder kontaktiere [dein-kontakt@example.com](mailto:dein-kontakt@example.com).

View file

@ -12,41 +12,59 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
totalTrips = promauto.NewGauge(prometheus.GaugeOpts{
Name: "traewelling_total_trips",
Help: "Gesamtanzahl der Fahrten",
})
totalDistance = promauto.NewGauge(prometheus.GaugeOpts{
Name: "traewelling_total_distance_km",
Help: "Gesamtdistanz aller Fahrten in Kilometern",
})
averageDuration = promauto.NewGauge(prometheus.GaugeOpts{
Name: "traewelling_average_duration_minutes",
Help: "Durchschnittliche Dauer der Fahrten in Minuten",
})
)
type DashboardResponse struct {
Data []struct {
ID int `json:"id"`
User struct {
DisplayName string `json:"displayName"`
Username string `json:"username"`
} `json:"userDetails"`
Train struct {
Trip int `json:"trip"`
Distance float64 `json:"distance"`
Duration int `json:"duration"`
Category string `json:"category"`
LineName string `json:"lineName"`
JourneyNumber int `json:"journeyNumber"`
Distance float64 `json:"distance"`
Duration int `json:"duration"`
Points int `json:"points"`
Origin struct {
Name string `json:"name"`
Name string `json:"name"`
DeparturePlanned string `json:"departurePlanned"`
DepartureReal string `json:"departureReal"`
} `json:"origin"`
Destination struct {
Name string `json:"name"`
Name string `json:"name"`
ArrivalPlanned string `json:"arrivalPlanned"`
ArrivalReal string `json:"arrivalReal"`
} `json:"destination"`
} `json:"train"`
} `json:"data"`
}
var (
totalTripDuration = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "traewelling_total_trip_duration_minutes",
Help: "Gesamtfahrzeit eines Benutzers in Minuten",
},
[]string{"username"},
)
totalTripPoints = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "traewelling_total_trip_points",
Help: "Gesamtpunkte eines Benutzers",
},
[]string{"username"},
)
totalTripDistance = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "traewelling_total_trip_distance_km",
Help: "Gesamtentfernung eines Benutzers in Kilometern",
},
[]string{"username"},
)
)
func fetchTraewellingData() (*DashboardResponse, error) {
url := "https://traewelling.de/api/v1/dashboard"
client := &http.Client{Timeout: 10 * time.Second}
@ -81,35 +99,60 @@ func fetchTraewellingData() (*DashboardResponse, error) {
return &apiResponse, nil
}
func processAndPrintTripDetails(data *DashboardResponse) {
fmt.Println("Fahrtdetails der Benutzer:")
fmt.Println("==========================")
userStats := make(map[string]struct {
TotalDuration float64
TotalPoints int
TotalDistance float64
})
for _, trip := range data.Data {
fmt.Printf("Benutzer: %s (@%s)\n", trip.User.DisplayName, trip.User.Username)
fmt.Printf("Fahrt-ID: %d\n", trip.Train.Trip)
fmt.Printf("Kategorie: %s\n", trip.Train.Category)
fmt.Printf("Linie: %s (Nummer: %d)\n", trip.Train.LineName, trip.Train.JourneyNumber)
fmt.Printf("Startbahnhof: %s\n", trip.Train.Origin.Name)
fmt.Printf("\tGeplante Abfahrt: %s\n", trip.Train.Origin.DeparturePlanned)
fmt.Printf("\tTatsächliche Abfahrt: %s\n", trip.Train.Origin.DepartureReal)
fmt.Printf("Zielbahnhof: %s\n", trip.Train.Destination.Name)
fmt.Printf("\tGeplante Ankunft: %s\n", trip.Train.Destination.ArrivalPlanned)
fmt.Printf("\tTatsächliche Ankunft: %s\n", trip.Train.Destination.ArrivalReal)
fmt.Printf("Dauer: %d Minuten\n", trip.Train.Duration)
fmt.Printf("Entfernung: %.2f km\n", trip.Train.Distance/1000)
fmt.Printf("Punkte: %d\n", trip.Train.Points)
fmt.Println("--------------------------")
stats := userStats[trip.User.Username]
stats.TotalDuration += float64(trip.Train.Duration)
stats.TotalPoints += trip.Train.Points
stats.TotalDistance += trip.Train.Distance / 1000
userStats[trip.User.Username] = stats
}
for username, stats := range userStats {
totalTripDuration.WithLabelValues(username).Set(stats.TotalDuration)
totalTripPoints.WithLabelValues(username).Set(float64(stats.TotalPoints))
totalTripDistance.WithLabelValues(username).Set(stats.TotalDistance)
}
}
func updateMetrics() {
data, err := fetchTraewellingData()
if err != nil {
fmt.Printf("Fehler beim Abrufen der Daten: %v\n", err)
return
}
var totalTripsCount int
var totalDistanceSum float64
var totalDurationSum int
for _, trip := range data.Data {
totalTripsCount++
totalDistanceSum += trip.Train.Distance / 1000
totalDurationSum += trip.Train.Duration
}
totalTrips.Set(float64(totalTripsCount))
totalDistance.Set(totalDistanceSum)
if totalTripsCount > 0 {
averageDuration.Set(float64(totalDurationSum) / float64(totalTripsCount))
}
processAndPrintTripDetails(data)
}
func main() {
go func() {
for {
updateMetrics()
time.Sleep(30 * time.Second)
time.Sleep(5 * time.Minute)
}
}()