add postgresql support

This commit is contained in:
Simon Rieger 2024-12-13 01:01:27 +01:00
parent e9cdfae68d
commit c2f47992b8
8 changed files with 135 additions and 74 deletions

3
.env
View file

@ -1,3 +0,0 @@
# Bitte die Domain wie oben anpassen
PUBLIC_APP_URL=https://pocket-id.brothertec.eu

8
.env.example Normal file
View file

@ -0,0 +1,8 @@
# Bitte die Domain wie oben anpassen
PUBLIC_APP_URL=https://pocket-id.brothertec.eu
POSTGRES_CONNECTION_STRING_ENV=postgresql://pocket-id:password@db:5432/pocket-id
POSTGRES_USER_ENV=pocket-id
POSTGRES_PASSWORD_ENV=password
POSTGRES_DB_ENV=pocket-id
DB_CONNECTION_ENV="host=db port=5432 user=pocket-id dbname=pocket-id password=password sslmode=disable"

3
.gitignore vendored
View file

@ -1 +1,4 @@
data/ data/
postgres_data/
dump.sql
.env

127
README.md
View file

@ -1,97 +1,94 @@
# pocket-id-exporter # Pocket ID Metrics Exporter
Der pocket-id-exporter ist ein Prometheus-Exporter für die Pocket ID-Datenbank. Er stellt Metriken über die Anzahl der Anmeldungen und Benutzer bereit. Dieser Pocket ID Metrics Exporter ist ein Go-Programm, das Metriken aus einer Datenbank (SQLite oder PostgreSQL) ausliest und diese für Prometheus bereitstellt.
## Funktionen ## Funktionen
- Exportiert die Gesamtzahl der Anmeldungen als Metrik `pocket_id_login_count` - Unterstützung für SQLite und PostgreSQL Datenbanken
- Exportiert die Gesamtzahl der Benutzer als Metrik `pocket_id_user_count` - Erfassung der Gesamtanzahl der Anmeldungen
- Stellt Metriken im Prometheus-Format unter dem `/metrics`-Endpunkt bereit - Erfassung der Gesamtanzahl der Benutzer
- Bereitstellung der Metriken über einen HTTP-Endpunkt für Prometheus
## Voraussetzungen ## Voraussetzungen
- Docker - Go 1.15 oder höher
- Docker Compose - SQLite oder PostgreSQL Datenbank
- Zugriff auf die Tabellen `Audit_Logs` und `Users` in der Datenbank
## Verwendung mit Docker Compose ## Installation
1. Erstellen Sie eine `docker-compose.yml`-Datei im Projektverzeichnis mit folgendem Inhalt: 1. Klonen Sie das Repository:
```
git clone https://github.com/yourusername/pocket-id-metrics-exporter.git
cd pocket-id-metrics-exporter
```
```yaml 2. Installieren Sie die erforderlichen Abhängigkeiten:
version: '3' ```
services: go get github.com/prometheus/client_golang/prometheus
pocket-id-exporter: go get github.com/prometheus/client_golang/prometheus/promhttp
build: . go get github.com/lib/pq
ports: go get github.com/mattn/go-sqlite3
- "3000:3000" ```
volumes:
- ./data:/app/data ## Konfiguration
Das Programm verwendet Umgebungsvariablen für die Konfiguration:
- `DB_TYPE`: Der Typ der Datenbank ("sqlite3" oder "postgres")
- `DB_CONNECTION`: Die Verbindungszeichenfolge für die Datenbank
### Beispiele:
Für SQLite:
```
export DB_TYPE=sqlite3
export DB_CONNECTION=./data/pocket-id.db
``` ```
2. Erstellen Sie eine `Dockerfile` im Projektverzeichnis: Für PostgreSQL:
```
```Dockerfile export DB_TYPE=postgres
FROM golang:1.17-alpine export DB_CONNECTION="host=localhost port=5432 user=yourusername dbname=yourdbname password=yourpassword sslmode=disable"
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o pocket-id-exporter
EXPOSE 3000
CMD ["./pocket-id-exporter"]
``` ```
3. Stellen Sie sicher, dass Ihre SQLite-Datenbank im Verzeichnis `./data` mit dem Namen `pocket-id.db` liegt. ## Verwendung
4. Bauen und starten Sie den Container mit Docker Compose: 1. Setzen Sie die Umgebungsvariablen wie oben beschrieben.
```bash 2. Starten Sie das Programm:
docker-compose up --build ```
``` go run main.go
```
Der Exporter ist nun unter `http://localhost:3000/metrics` erreichbar. 3. Das Programm läuft nun auf `http://localhost:3000`. Die Metriken sind unter dem `/metrics` Endpunkt verfügbar.
## Konfiguration von Prometheus ## Metriken
Fügen Sie folgende Job-Konfiguration zu Ihrer `prometheus.yml` hinzu, um die Metriken zu scrapen: - `pocket_id_login_count`: Gesamtanzahl der Anmeldungen
- `pocket_id_user_count`: Gesamtanzahl der Benutzer
## Prometheus Konfiguration
Fügen Sie folgende Job-Konfiguration zu Ihrer `prometheus.yml` hinzu:
```yaml ```yaml
scrape_configs: scrape_configs:
- job_name: 'pocket-id' - job_name: 'pocket_id_metrics'
static_configs: static_configs:
- targets: ['localhost:3000'] - targets: ['localhost:3000']
``` ```
## Entwicklung ## Fehlerbehebung
Um den Exporter lokal zu entwickeln und zu testen: - Stellen Sie sicher, dass die Datenbank erreichbar ist und die erforderlichen Tabellen existieren.
- Überprüfen Sie die Konsolenausgabe auf Fehlermeldungen.
- Vergewissern Sie sich, dass die Umgebungsvariablen korrekt gesetzt sind.
1. Installieren Sie Go (Version 1.17 oder höher) ## Beitragen
2. Klonen Sie das Repository
3. Installieren Sie die Abhängigkeiten:
```bash Beiträge sind willkommen! Bitte erstellen Sie einen Pull Request oder öffnen Sie ein Issue für Vorschläge und Fehlermeldungen.
go mod download
```
4. Bauen und starten Sie den Exporter:
```bash
go build
./pocket-id-exporter
```
## Lizenz ## Lizenz
[MIT License](LICENSE) Dieses Projekt steht unter der MIT-Lizenz. Siehe die [LICENSE](LICENSE) Datei für Details.
https://github.com/stonith404/pocket-id
https://goneuland.de/pocket-id-mit-docker-und-traefik-installieren/
https://github.com/stonith404/pocket-id/issues/56

View file

@ -13,6 +13,11 @@ services:
- VIRTUAL_PORT=80 - VIRTUAL_PORT=80
- LETSENCRYPT_HOST=pocket-id.brothertec.eu - LETSENCRYPT_HOST=pocket-id.brothertec.eu
- LETSENCRYPT_EMAIL=admin@brothertec.eu - LETSENCRYPT_EMAIL=admin@brothertec.eu
- DB_PROVIDER=postgres
- POSTGRES_CONNECTION_STRING=$POSTGRES_CONNECTION_STRING_ENV
depends_on:
- db
labels: labels:
- "com.centurylinklabs.watchtower.enable=true" - "com.centurylinklabs.watchtower.enable=true"
@ -22,6 +27,24 @@ services:
- proxy - proxy
- edge-tier - edge-tier
db:
image: postgres:17
environment:
POSTGRES_USER: $POSTGRES_USER_ENV
POSTGRES_PASSWORD: $POSTGRES_PASSWORD_ENV
POSTGRES_DB: $POSTGRES_DB_ENV
volumes:
- ./postgres_data:/var/lib/postgresql/data
restart: always
networks:
default:
dns:
ipv4_address: 172.28.0.123
ports:
- "5432:5432"
labels:
- "com.centurylinklabs.watchtower.enable=true"
pocket-id-exporter: pocket-id-exporter:
container_name: pocket-id-exporter container_name: pocket-id-exporter
build: build:
@ -34,6 +57,13 @@ services:
# - "3000:3000" # - "3000:3000"
environment: environment:
- TZ=Europe/Berlin - TZ=Europe/Berlin
- DB_TYPE=postgres
- DB_CONNECTION=$DB_CONNECTION_ENV
#- DB_TYPE=sqlite3
#- DB_CONNECTION=./data/pocket-id.db
depends_on:
- db
restart: always restart: always

View file

@ -3,6 +3,7 @@ module pocket-id-exporter
go 1.20 go 1.20
require ( require (
github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.24 github.com/mattn/go-sqlite3 v1.14.24
github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_golang v1.20.5
) )

View file

@ -6,6 +6,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=

View file

@ -4,15 +4,16 @@ import (
"database/sql" "database/sql"
"log" "log"
"net/http" "net/http"
"os"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
const ( const (
dbPath = "./data/pocket-id.db" port = ":3000"
port = ":3000"
) )
var ( var (
@ -35,14 +36,26 @@ func init() {
} }
func main() { func main() {
dbType := os.Getenv("DB_TYPE")
dbConnection := os.Getenv("DB_CONNECTION")
if dbType == "" || dbConnection == "" {
log.Fatal("DB_TYPE and DB_CONNECTION environment variables must be set")
}
var err error var err error
db, err = sql.Open("sqlite3", dbPath) db, err = sql.Open(dbType, dbConnection)
if err != nil { if err != nil {
log.Fatalf("Error opening database: %v", err) log.Fatalf("Error opening database: %v", err)
} }
defer db.Close() defer db.Close()
log.Println("Connected to the Pocket ID SQLite database.") err = db.Ping()
if err != nil {
log.Fatalf("Error connecting to the database: %v", err)
}
log.Printf("Connected to the %s database.", dbType)
http.HandleFunc("/metrics", metricsHandler) http.HandleFunc("/metrics", metricsHandler)
http.Handle("/", promhttp.Handler()) http.Handle("/", promhttp.Handler())
@ -59,14 +72,24 @@ func metricsHandler(w http.ResponseWriter, r *http.Request) {
func updateMetrics() { func updateMetrics() {
var count int var count int
err := db.QueryRow("SELECT COUNT(*) FROM Audit_Logs WHERE event = 'SIGN_IN'").Scan(&count) query := "SELECT COUNT(*) FROM Audit_Logs WHERE event = 'SIGN_IN'"
if os.Getenv("DB_TYPE") == "postgres" {
query = "SELECT COUNT(*) FROM audit_logs WHERE event = 'SIGN_IN'"
}
err := db.QueryRow(query).Scan(&count)
if err != nil { if err != nil {
log.Printf("Error querying login count: %v", err) log.Printf("Error querying login count: %v", err)
} else { } else {
loginCount.Set(float64(count)) loginCount.Set(float64(count))
} }
err = db.QueryRow("SELECT COUNT(*) FROM Users").Scan(&count) query = "SELECT COUNT(*) FROM Users"
if os.Getenv("DB_TYPE") == "postgres" {
query = "SELECT COUNT(*) FROM users"
}
err = db.QueryRow(query).Scan(&count)
if err != nil { if err != nil {
log.Printf("Error querying user count: %v", err) log.Printf("Error querying user count: %v", err)
} else { } else {