first commit
This commit is contained in:
commit
5817a382fd
7 changed files with 320 additions and 0 deletions
97
README.md
Normal file
97
README.md
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
# pocket-id-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.
|
||||||
|
|
||||||
|
## Funktionen
|
||||||
|
|
||||||
|
- Exportiert die Gesamtzahl der Anmeldungen als Metrik `pocket_id_login_count`
|
||||||
|
- Exportiert die Gesamtzahl der Benutzer als Metrik `pocket_id_user_count`
|
||||||
|
- Stellt Metriken im Prometheus-Format unter dem `/metrics`-Endpunkt bereit
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
- Docker Compose
|
||||||
|
|
||||||
|
## Verwendung mit Docker Compose
|
||||||
|
|
||||||
|
1. Erstellen Sie eine `docker-compose.yml`-Datei im Projektverzeichnis mit folgendem Inhalt:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
pocket-id-exporter:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- ./data:/app/data
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Erstellen Sie eine `Dockerfile` im Projektverzeichnis:
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
FROM golang:1.17-alpine
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
4. Bauen und starten Sie den Container mit Docker Compose:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Exporter ist nun unter `http://localhost:3000/metrics` erreichbar.
|
||||||
|
|
||||||
|
## Konfiguration von Prometheus
|
||||||
|
|
||||||
|
Fügen Sie folgende Job-Konfiguration zu Ihrer `prometheus.yml` hinzu, um die Metriken zu scrapen:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'pocket-id'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['localhost:3000']
|
||||||
|
```
|
||||||
|
|
||||||
|
## Entwicklung
|
||||||
|
|
||||||
|
Um den Exporter lokal zu entwickeln und zu testen:
|
||||||
|
|
||||||
|
1. Installieren Sie Go (Version 1.17 oder höher)
|
||||||
|
2. Klonen Sie das Repository
|
||||||
|
3. Installieren Sie die Abhängigkeiten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go mod download
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Bauen und starten Sie den Exporter:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go build
|
||||||
|
./pocket-id-exporter
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lizenz
|
||||||
|
|
||||||
|
[MIT License](LICENSE)
|
||||||
|
|
||||||
|
https://github.com/stonith404/pocket-id
|
||||||
|
|
||||||
|
https://goneuland.de/pocket-id-mit-docker-und-traefik-installieren/
|
||||||
|
|
||||||
|
https://github.com/stonith404/pocket-id/issues/56
|
54
docker-compose.yml
Normal file
54
docker-compose.yml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
services:
|
||||||
|
pocketid:
|
||||||
|
image: stonith404/pocket-id:latest
|
||||||
|
container_name: pocket-id
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
|
volumes:
|
||||||
|
- "./data:/app/backend/data"
|
||||||
|
|
||||||
|
environment:
|
||||||
|
- TRUST_PROXY=true # Set to true if a reverse proxy is in front of the container
|
||||||
|
- VIRTUAL_HOST=pocket-id.brothertec.eu
|
||||||
|
- VIRTUAL_PORT=80
|
||||||
|
- LETSENCRYPT_HOST=pocket-id.brothertec.eu
|
||||||
|
- LETSENCRYPT_EMAIL=admin@brothertec.eu
|
||||||
|
|
||||||
|
labels:
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- proxy
|
||||||
|
- edge-tier
|
||||||
|
|
||||||
|
pocket-id-exporter:
|
||||||
|
container_name: pocket-id-exporter
|
||||||
|
build:
|
||||||
|
context: go/.
|
||||||
|
args:
|
||||||
|
- GO111MODULE=off
|
||||||
|
volumes:
|
||||||
|
- "./data:/data"
|
||||||
|
#ports:
|
||||||
|
# - "3000:3000"
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
dns:
|
||||||
|
ipv4_address: 172.28.0.93
|
||||||
|
|
||||||
|
networks:
|
||||||
|
dns:
|
||||||
|
name: dns
|
||||||
|
external: true
|
||||||
|
proxy:
|
||||||
|
name: nginx-proxy
|
||||||
|
external: true
|
||||||
|
edge-tier:
|
||||||
|
name: edge
|
||||||
|
external: true
|
28
go/Dockerfile
Executable file
28
go/Dockerfile
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# Build the application from source
|
||||||
|
FROM golang:1.20 AS build-stage
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY * ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=1 GOOS=linux go build -o /main
|
||||||
|
|
||||||
|
# Run the tests in the container
|
||||||
|
FROM build-stage AS run-test-stage
|
||||||
|
RUN go test -v ./...
|
||||||
|
|
||||||
|
# Deploy the application binary into a lean image
|
||||||
|
FROM gcr.io/distroless/base-debian12 AS build-release-stage
|
||||||
|
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
|
COPY --from=build-stage /main /main
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
USER nonroot:nonroot
|
||||||
|
|
||||||
|
ENTRYPOINT ["/main"]
|
22
go/Dockerfile.old
Executable file
22
go/Dockerfile.old
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
# Use an official Golang runtime as a parent image
|
||||||
|
FROM golang:1.21.4
|
||||||
|
|
||||||
|
# Set the working directory in the container
|
||||||
|
WORKDIR /go/src/app
|
||||||
|
|
||||||
|
# Copy the local package files to the container's workspace
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Download and install any required third-party dependencies into the container.
|
||||||
|
#RUN go get -u github.com/gorilla/mux
|
||||||
|
RUN go get -u github.com/go-sql-driver/mysql
|
||||||
|
RUN go get -u github.com/sirupsen/logrus
|
||||||
|
|
||||||
|
# Build the Go application
|
||||||
|
RUN go build -o main .
|
||||||
|
|
||||||
|
# Expose port 8080 to the outside world
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Command to run the application with environment variables
|
||||||
|
CMD ["./main"]
|
20
go/go.mod
Normal file
20
go/go.mod
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module pocket-id-exporter
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.24
|
||||||
|
github.com/prometheus/client_golang v1.20.5
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
|
)
|
24
go/go.sum
Normal file
24
go/go.sum
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
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/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
|
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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||||
|
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
75
go/mailu.go
Normal file
75
go/mailu.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dbPath = "./data/pocket-id.db"
|
||||||
|
port = ":3000"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
db *sql.DB
|
||||||
|
|
||||||
|
loginCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Name: "pocket_id_login_count",
|
||||||
|
Help: "Total number of sign-ins",
|
||||||
|
})
|
||||||
|
|
||||||
|
userCount = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||||
|
Name: "pocket_id_user_count",
|
||||||
|
Help: "Total number of users",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
prometheus.MustRegister(loginCount)
|
||||||
|
prometheus.MustRegister(userCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var err error
|
||||||
|
db, err = sql.Open("sqlite3", dbPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error opening database: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
log.Println("Connected to the Pocket ID SQLite database.")
|
||||||
|
|
||||||
|
http.HandleFunc("/metrics", metricsHandler)
|
||||||
|
http.Handle("/", promhttp.Handler())
|
||||||
|
|
||||||
|
log.Printf("Server running on http://localhost%s", port)
|
||||||
|
log.Fatal(http.ListenAndServe(port, nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func metricsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
updateMetrics()
|
||||||
|
promhttp.Handler().ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateMetrics() {
|
||||||
|
var count int
|
||||||
|
|
||||||
|
err := db.QueryRow("SELECT COUNT(*) FROM Audit_Logs WHERE event = 'SIGN_IN'").Scan(&count)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error querying login count: %v", err)
|
||||||
|
} else {
|
||||||
|
loginCount.Set(float64(count))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.QueryRow("SELECT COUNT(*) FROM Users").Scan(&count)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error querying user count: %v", err)
|
||||||
|
} else {
|
||||||
|
userCount.Set(float64(count))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue