From 9d12e3ecf1269b5530d3e1d9897db481181bc920 Mon Sep 17 00:00:00 2001 From: Tyler Koenig Date: Sun, 24 May 2026 20:20:35 -0400 Subject: [PATCH] chore: complete rename from go-upkeep to uptop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Module path: gitea.lerkolabs.com/lerko/uptop - Binary: cmd/uptop/ - All imports updated to full module path - Env vars: UPKEEP_* → UPTOP_* - Prometheus metrics: upkeep_* → uptop_* - Default DB: uptop.db - Docker image: lerko/uptop - All docs, compose files, CI updated Only remaining "go-upkeep" reference is the fork attribution in README. --- .github/workflows/docker.yml | 2 +- .gitignore | 7 +--- CONTRIBUTING.md | 2 +- Dockerfile | 14 +++---- README.md | 52 +++++++++++------------ cmd/{goupkeep => uptop}/main.go | 64 ++++++++++++++--------------- docker-compose.cluster.yml | 42 +++++++++---------- docker-compose.dev.yml | 16 ++++---- docker-compose.probe.yml | 32 +++++++-------- docker-compose.yml | 12 +++--- docs/config-as-code.md | 26 ++++++------ go.mod | 2 +- internal/alert/alert.go | 6 +-- internal/alert/alert_test.go | 2 +- internal/cluster/cluster.go | 2 +- internal/cluster/cluster_test.go | 4 +- internal/cluster/probe.go | 4 +- internal/config/apply.go | 4 +- internal/config/apply_test.go | 4 +- internal/config/export.go | 4 +- internal/config/export_test.go | 2 +- internal/importer/kuma.go | 2 +- internal/metrics/prometheus.go | 44 ++++++++++---------- internal/metrics/prometheus_test.go | 18 ++++---- internal/monitor/checker.go | 2 +- internal/monitor/checker_test.go | 2 +- internal/monitor/monitor.go | 6 +-- internal/monitor/monitor_test.go | 2 +- internal/server/server.go | 16 ++++---- internal/server/server_test.go | 4 +- internal/store/sqlstore.go | 2 +- internal/store/sqlstore_test.go | 2 +- internal/store/store.go | 2 +- internal/tui/tab_maint.go | 2 +- internal/tui/tab_sites.go | 5 ++- internal/tui/tui.go | 6 +-- 36 files changed, 208 insertions(+), 210 deletions(-) rename cmd/{goupkeep => uptop}/main.go (85%) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a8b1591..446e3da 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -29,7 +29,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ secrets.DOCKERHUB_USERNAME }}/go-upkeep + images: ${{ secrets.DOCKERHUB_USERNAME }}/uptop tags: | # This turns git tag "v1.0.0" into docker tag "1.0.0" type=semver,pattern={{version}} diff --git a/.gitignore b/.gitignore index 1fd01d6..a958ed7 100644 --- a/.gitignore +++ b/.gitignore @@ -26,8 +26,8 @@ go.work # End of https://www.toptal.com/developers/gitignore/api/go -/goupkeep -upkeep.db +/uptop +uptop.db .ssh @@ -35,8 +35,5 @@ authorized_keys tmp -# Old repo -/go-upkeep/ - *.local.json *.local.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35c6a4e..69f457d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Development ```sh -go run cmd/goupkeep/main.go -demo # starts with sample data +go run cmd/uptop/main.go -demo # starts with sample data ssh -p 23234 localhost # connect to TUI ``` diff --git a/Dockerfile b/Dockerfile index 1c0e9c8..e4e804c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ENV CGO_ENABLED=1 ARG VERSION=dev ARG COMMIT=none ARG BUILD_DATE=unknown -RUN go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${BUILD_DATE}" -o go-upkeep ./cmd/goupkeep/main.go +RUN go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${BUILD_DATE}" -o uptop ./cmd/uptop/main.go # --- Stage 2: Runner --- FROM alpine:latest @@ -17,15 +17,15 @@ WORKDIR /app RUN apk add --no-cache ca-certificates openssh-client RUN mkdir /data -COPY --from=builder /app/go-upkeep . +COPY --from=builder /app/uptop . # Set Default Configuration via ENV # Docker users can override these in docker-compose.yml ENV LIPGLOSS_RENDERER_HAS_DARK_BACKGROUND=true -ENV UPKEEP_DB_TYPE=sqlite -ENV UPKEEP_DB_DSN=/data/upkeep.db -ENV UPKEEP_KEYS=/data/authorized_keys -ENV UPKEEP_PORT=23234 +ENV UPTOP_DB_TYPE=sqlite +ENV UPTOP_DB_DSN=/data/uptop.db +ENV UPTOP_KEYS=/data/authorized_keys +ENV UPTOP_PORT=23234 EXPOSE 23234 -CMD ["./go-upkeep"] \ No newline at end of file +CMD ["./uptop"] \ No newline at end of file diff --git a/README.md b/README.md index 7517786..6553aac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Go-Upkeep +# uptop Self-hosted uptime monitor with a TUI you can access over SSH. No browser, no install on the client — just `ssh -p 23234 your-server`. @@ -18,14 +18,14 @@ Built on the foundation of [RDGames/go-upkeep](https://github.com/RDGames/go-upk ## Quick start ```bash -go run cmd/goupkeep/main.go +go run cmd/uptop/main.go ssh -p 23234 localhost ``` Seed some demo data to see it in action: ```bash -go run cmd/goupkeep/main.go -demo +go run cmd/uptop/main.go -demo ``` ## Install @@ -33,34 +33,34 @@ go run cmd/goupkeep/main.go -demo ### From source ```bash -go install gitea.lerkolabs.com/lerko/uptime/cmd/goupkeep@latest +go install gitea.lerkolabs.com/lerko/uptop/cmd/uptop@latest ``` ### Docker ```bash -docker pull lerko/go-upkeep:latest -docker run -p 23234:23234 -p 8080:8080 -v ./data:/data lerko/go-upkeep +docker pull lerko/uptop:latest +docker run -p 23234:23234 -p 8080:8080 -v ./data:/data lerko/uptop ``` ### Binary -Download from [Releases](https://gitea.lerkolabs.com/lerko/uptime/releases). +Download from [Releases](https://gitea.lerkolabs.com/lerko/uptop/releases). ## Config as code Export your current monitors: ```bash -goupkeep export -o monitors.yaml +uptop export -o monitors.yaml ``` Apply a config file: ```bash -goupkeep apply -f monitors.yaml -goupkeep apply -f monitors.yaml --dry-run # see what would change -goupkeep apply -f monitors.yaml --prune # delete anything not in the YAML +uptop apply -f monitors.yaml +uptop apply -f monitors.yaml --dry-run # see what would change +uptop apply -f monitors.yaml --prune # delete anything not in the YAML ``` See [docs/config-as-code.md](docs/config-as-code.md) for the full reference. @@ -81,28 +81,28 @@ services: - ./data:/data - ./ssh_keys:/app/.ssh environment: - - UPKEEP_DB_TYPE=sqlite - - UPKEEP_DB_DSN=/data/upkeep.db - - UPKEEP_STATUS_ENABLED=true - - UPKEEP_CLUSTER_SECRET=change-me + - UPTOP_DB_TYPE=sqlite + - UPTOP_DB_DSN=/data/uptop.db + - UPTOP_STATUS_ENABLED=true + - UPTOP_CLUSTER_SECRET=change-me ``` -First run: attach to the container (`docker attach go-upkeep`), go to the Users tab, add your SSH public key. Then detach with `Ctrl+P, Ctrl+Q` and connect normally over SSH. +First run: attach to the container (`docker attach uptop`), go to the Users tab, add your SSH public key. Then detach with `Ctrl+P, Ctrl+Q` and connect normally over SSH. ## Environment variables | Variable | Default | What it does | |---|---|---| -| `UPKEEP_PORT` | `23234` | SSH server port | -| `UPKEEP_HTTP_PORT` | `8080` | HTTP server port (status page, push, metrics) | -| `UPKEEP_DB_TYPE` | `sqlite` | `sqlite` or `postgres` | -| `UPKEEP_DB_DSN` | `upkeep.db` | Database path or connection string | -| `UPKEEP_STATUS_ENABLED` | `false` | Enable public status page | -| `UPKEEP_STATUS_TITLE` | `System Status` | Status page title | -| `UPKEEP_CLUSTER_MODE` | `leader` | `leader` or `follower` | -| `UPKEEP_PEER_URL` | | Leader URL for follower nodes | -| `UPKEEP_CLUSTER_SECRET` | | Shared key for cluster + API auth | -| `UPKEEP_INSECURE_SKIP_VERIFY` | `false` | Skip TLS verification for checks | +| `UPTOP_PORT` | `23234` | SSH server port | +| `UPTOP_HTTP_PORT` | `8080` | HTTP server port (status page, push, metrics) | +| `UPTOP_DB_TYPE` | `sqlite` | `sqlite` or `postgres` | +| `UPTOP_DB_DSN` | `uptop.db` | Database path or connection string | +| `UPTOP_STATUS_ENABLED` | `false` | Enable public status page | +| `UPTOP_STATUS_TITLE` | `System Status` | Status page title | +| `UPTOP_CLUSTER_MODE` | `leader` | `leader` or `follower` | +| `UPTOP_PEER_URL` | | Leader URL for follower nodes | +| `UPTOP_CLUSTER_SECRET` | | Shared key for cluster + API auth | +| `UPTOP_INSECURE_SKIP_VERIFY` | `false` | Skip TLS verification for checks | ## Migrating from Uptime Kuma diff --git a/cmd/goupkeep/main.go b/cmd/uptop/main.go similarity index 85% rename from cmd/goupkeep/main.go rename to cmd/uptop/main.go index 00e389b..79968fd 100644 --- a/cmd/goupkeep/main.go +++ b/cmd/uptop/main.go @@ -5,14 +5,14 @@ import ( "errors" "flag" "fmt" - "go-upkeep/internal/cluster" - "go-upkeep/internal/config" - "go-upkeep/internal/importer" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" - "go-upkeep/internal/server" - "go-upkeep/internal/store" - "go-upkeep/internal/tui" + "gitea.lerkolabs.com/lerko/uptop/internal/cluster" + "gitea.lerkolabs.com/lerko/uptop/internal/config" + "gitea.lerkolabs.com/lerko/uptop/internal/importer" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/server" + "gitea.lerkolabs.com/lerko/uptop/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/tui" "log" "os" "os/signal" @@ -54,9 +54,9 @@ func main() { func printVersion() { if version == "dev" { - fmt.Println("go-upkeep dev") + fmt.Println("uptop dev") } else { - fmt.Printf("go-upkeep %s (%s, %s)\n", version, commit, date) + fmt.Printf("uptop %s (%s, %s)\n", version, commit, date) } } @@ -91,8 +91,8 @@ func runApply(args []string) { filePath := fs.String("f", "", "Path to YAML config file (required)") dryRun := fs.Bool("dry-run", false, "Show planned changes without applying") prune := fs.Bool("prune", false, "Delete monitors/alerts not in YAML") - dbType := fs.String("db-type", envOrDefault("UPKEEP_DB_TYPE", "sqlite"), "Database type") - dsn := fs.String("dsn", envOrDefault("UPKEEP_DB_DSN", "upkeep.db"), "Database DSN") + dbType := fs.String("db-type", envOrDefault("UPTOP_DB_TYPE", "sqlite"), "Database type") + dsn := fs.String("dsn", envOrDefault("UPTOP_DB_DSN", "uptop.db"), "Database DSN") _ = fs.Parse(args) // ExitOnError: parse errors exit before returning if *filePath == "" { @@ -124,8 +124,8 @@ func runApply(args []string) { func runExport(args []string) { fs := flag.NewFlagSet("export", flag.ExitOnError) outPath := fs.String("o", "-", "Output file path (- for stdout)") - dbType := fs.String("db-type", envOrDefault("UPKEEP_DB_TYPE", "sqlite"), "Database type") - dsn := fs.String("dsn", envOrDefault("UPKEEP_DB_DSN", "upkeep.db"), "Database DSN") + dbType := fs.String("db-type", envOrDefault("UPTOP_DB_TYPE", "sqlite"), "Database type") + dsn := fs.String("dsn", envOrDefault("UPTOP_DB_DSN", "uptop.db"), "Database DSN") _ = fs.Parse(args) // ExitOnError: parse errors exit before returning s := openStore(*dbType, *dsn) @@ -145,7 +145,7 @@ func runExport(args []string) { func runServe(args []string) { portVal := 23234 dbType := "sqlite" - dbDSN := "upkeep.db" + dbDSN := "uptop.db" httpPort := 8080 enableStatus := false statusTitle := "System Status" @@ -153,50 +153,50 @@ func runServe(args []string) { clusterPeer := "" clusterKey := "" - if v := os.Getenv("UPKEEP_PORT"); v != "" { + if v := os.Getenv("UPTOP_PORT"); v != "" { if p, err := strconv.Atoi(v); err == nil { portVal = p } } - if v := os.Getenv("UPKEEP_DB_TYPE"); v != "" { + if v := os.Getenv("UPTOP_DB_TYPE"); v != "" { dbType = v } - if v := os.Getenv("UPKEEP_DB_DSN"); v != "" { + if v := os.Getenv("UPTOP_DB_DSN"); v != "" { dbDSN = v } - if v := os.Getenv("UPKEEP_HTTP_PORT"); v != "" { + if v := os.Getenv("UPTOP_HTTP_PORT"); v != "" { if p, err := strconv.Atoi(v); err == nil { httpPort = p } } - if v := os.Getenv("UPKEEP_STATUS_ENABLED"); v == "true" { + if v := os.Getenv("UPTOP_STATUS_ENABLED"); v == "true" { enableStatus = true } - if v := os.Getenv("UPKEEP_STATUS_TITLE"); v != "" { + if v := os.Getenv("UPTOP_STATUS_TITLE"); v != "" { statusTitle = v } - if v := os.Getenv("UPKEEP_CLUSTER_MODE"); v != "" { + if v := os.Getenv("UPTOP_CLUSTER_MODE"); v != "" { clusterMode = v } - if v := os.Getenv("UPKEEP_PEER_URL"); v != "" { + if v := os.Getenv("UPTOP_PEER_URL"); v != "" { clusterPeer = v } - if v := os.Getenv("UPKEEP_CLUSTER_SECRET"); v != "" { + if v := os.Getenv("UPTOP_CLUSTER_SECRET"); v != "" { clusterKey = v } - nodeID := os.Getenv("UPKEEP_NODE_ID") - nodeName := os.Getenv("UPKEEP_NODE_NAME") - nodeRegion := os.Getenv("UPKEEP_NODE_REGION") - aggStrategy := os.Getenv("UPKEEP_AGG_STRATEGY") + nodeID := os.Getenv("UPTOP_NODE_ID") + nodeName := os.Getenv("UPTOP_NODE_NAME") + nodeRegion := os.Getenv("UPTOP_NODE_REGION") + aggStrategy := os.Getenv("UPTOP_AGG_STRATEGY") if clusterMode == "probe" { if nodeID == "" { - fmt.Fprintln(os.Stderr, "UPKEEP_NODE_ID is required for probe mode") + fmt.Fprintln(os.Stderr, "UPTOP_NODE_ID is required for probe mode") os.Exit(1) } if clusterPeer == "" { - fmt.Fprintln(os.Stderr, "UPKEEP_PEER_URL is required for probe mode") + fmt.Fprintln(os.Stderr, "UPTOP_PEER_URL is required for probe mode") os.Exit(1) } @@ -270,7 +270,7 @@ func runServe(args []string) { } eng := monitor.NewEngine(s) - if os.Getenv("UPKEEP_INSECURE_SKIP_VERIFY") == "true" { + if os.Getenv("UPTOP_INSECURE_SKIP_VERIFY") == "true" { eng.SetInsecureSkipVerify(true) } if aggStrategy != "" { @@ -305,7 +305,7 @@ func runServe(args []string) { fmt.Printf("Error: %v\n", err) } } else { - fmt.Println("Go-Upkeep running in HEADLESS mode") + fmt.Println("uptop running in HEADLESS mode") done := make(chan os.Signal, 1) signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) <-done diff --git a/docker-compose.cluster.yml b/docker-compose.cluster.yml index b6c6c7a..344e08a 100644 --- a/docker-compose.cluster.yml +++ b/docker-compose.cluster.yml @@ -4,21 +4,21 @@ services: # ------------------------- leader: build: . - container_name: upkeep-leader + container_name: uptop-leader ports: - "23234:23234" # SSH - "8080:8080" # HTTP environment: - - UPKEEP_DB_TYPE=postgres + - UPTOP_DB_TYPE=postgres # Note: Port 5432 is correct here because we are talking INSIDE the network - - UPKEEP_DB_DSN=postgres://devuser:devpass@leader-db:5432/upkeep_dev?sslmode=disable - - UPKEEP_HTTP_PORT=8080 - - UPKEEP_STATUS_ENABLED=true - - UPKEEP_STATUS_TITLE=Leader Node + - UPTOP_DB_DSN=postgres://devuser:devpass@leader-db:5432/uptop_dev?sslmode=disable + - UPTOP_HTTP_PORT=8080 + - UPTOP_STATUS_ENABLED=true + - UPTOP_STATUS_TITLE=Leader Node # Cluster Config - - UPKEEP_CLUSTER_MODE=leader - - UPKEEP_CLUSTER_SECRET=mysecret + - UPTOP_CLUSTER_MODE=leader + - UPTOP_CLUSTER_SECRET=mysecret depends_on: - leader-db stdin_open: true @@ -26,11 +26,11 @@ services: leader-db: image: postgres:15-alpine - container_name: upkeep-leader-db + container_name: uptop-leader-db environment: POSTGRES_USER: devuser POSTGRES_PASSWORD: devpass - POSTGRES_DB: upkeep_dev + POSTGRES_DB: uptop_dev volumes: - ./tmp/leader-data:/var/lib/postgresql/data @@ -39,23 +39,23 @@ services: # ------------------------- follower: build: . - container_name: upkeep-follower + container_name: uptop-follower ports: - "23233:23234" # SSH (Mapped to different host port) - "8081:8080" # HTTP (Mapped to different host port) environment: - - UPKEEP_DB_TYPE=postgres + - UPTOP_DB_TYPE=postgres # Connects to its OWN database - - UPKEEP_DB_DSN=postgres://devuser:devpass@follower-db:5432/upkeep_dev?sslmode=disable - - UPKEEP_HTTP_PORT=8080 - - UPKEEP_STATUS_ENABLED=true - - UPKEEP_STATUS_TITLE=Follower Node + - UPTOP_DB_DSN=postgres://devuser:devpass@follower-db:5432/uptop_dev?sslmode=disable + - UPTOP_HTTP_PORT=8080 + - UPTOP_STATUS_ENABLED=true + - UPTOP_STATUS_TITLE=Follower Node # Cluster Config - - UPKEEP_CLUSTER_MODE=follower - - UPKEEP_CLUSTER_SECRET=mysecret + - UPTOP_CLUSTER_MODE=follower + - UPTOP_CLUSTER_SECRET=mysecret # IMPORTANT: Uses the Service Name "leader" to connect internally - - UPKEEP_PEER_URL=http://leader:8080 + - UPTOP_PEER_URL=http://leader:8080 depends_on: - follower-db stdin_open: true @@ -63,10 +63,10 @@ services: follower-db: image: postgres:15-alpine - container_name: upkeep-follower-db + container_name: uptop-follower-db environment: POSTGRES_USER: devuser POSTGRES_PASSWORD: devpass - POSTGRES_DB: upkeep_dev + POSTGRES_DB: uptop_dev volumes: - ./tmp/follower-data:/var/lib/postgresql/data \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index dc08057..b7b7194 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -4,19 +4,19 @@ services: build: context: . dockerfile: Dockerfile - container_name: upkeep-dev + container_name: uptop-dev ports: - "23234:23234" # SSH Access - "8080:8080" # HTTP (Push Monitors + Status Page) environment: # --- Database Configuration (Postgres) --- - - UPKEEP_DB_TYPE=postgres - - UPKEEP_DB_DSN=postgres://devuser:devpass@postgres:5432/upkeep_dev?sslmode=disable + - UPTOP_DB_TYPE=postgres + - UPTOP_DB_DSN=postgres://devuser:devpass@postgres:5432/uptop_dev?sslmode=disable # --- Web Server Configuration (Phase 4) --- - - UPKEEP_HTTP_PORT=8080 - - UPKEEP_STATUS_ENABLED=true - - UPKEEP_STATUS_TITLE=Dev Infrastructure Status + - UPTOP_HTTP_PORT=8080 + - UPTOP_STATUS_ENABLED=true + - UPTOP_STATUS_TITLE=Dev Infrastructure Status depends_on: - postgres stdin_open: true # Required for 'docker attach' (Local Admin Console) @@ -25,11 +25,11 @@ services: # The Database postgres: image: postgres:15-alpine - container_name: upkeep-postgres + container_name: uptop-postgres environment: POSTGRES_USER: devuser POSTGRES_PASSWORD: devpass - POSTGRES_DB: upkeep_dev + POSTGRES_DB: uptop_dev ports: - "5432:5432" # Expose for external DB tools (DBeaver, etc.) volumes: diff --git a/docker-compose.probe.yml b/docker-compose.probe.yml index 791811f..b741c6d 100644 --- a/docker-compose.probe.yml +++ b/docker-compose.probe.yml @@ -2,10 +2,10 @@ services: leader: build: . environment: - - UPKEEP_CLUSTER_MODE=leader - - UPKEEP_CLUSTER_SECRET=changeme - - UPKEEP_AGG_STRATEGY=any-down - - UPKEEP_STATUS_ENABLED=true + - UPTOP_CLUSTER_MODE=leader + - UPTOP_CLUSTER_SECRET=changeme + - UPTOP_AGG_STRATEGY=any-down + - UPTOP_STATUS_ENABLED=true ports: - "8080:8080" - "23234:23234" @@ -13,23 +13,23 @@ services: probe-us-east: build: . environment: - - UPKEEP_CLUSTER_MODE=probe - - UPKEEP_NODE_ID=us-east-1 - - UPKEEP_NODE_NAME=US East Probe - - UPKEEP_NODE_REGION=us-east - - UPKEEP_PEER_URL=http://leader:8080 - - UPKEEP_CLUSTER_SECRET=changeme + - UPTOP_CLUSTER_MODE=probe + - UPTOP_NODE_ID=us-east-1 + - UPTOP_NODE_NAME=US East Probe + - UPTOP_NODE_REGION=us-east + - UPTOP_PEER_URL=http://leader:8080 + - UPTOP_CLUSTER_SECRET=changeme depends_on: - leader probe-eu-west: build: . environment: - - UPKEEP_CLUSTER_MODE=probe - - UPKEEP_NODE_ID=eu-west-1 - - UPKEEP_NODE_NAME=EU West Probe - - UPKEEP_NODE_REGION=eu-west - - UPKEEP_PEER_URL=http://leader:8080 - - UPKEEP_CLUSTER_SECRET=changeme + - UPTOP_CLUSTER_MODE=probe + - UPTOP_NODE_ID=eu-west-1 + - UPTOP_NODE_NAME=EU West Probe + - UPTOP_NODE_REGION=eu-west + - UPTOP_PEER_URL=http://leader:8080 + - UPTOP_CLUSTER_SECRET=changeme depends_on: - leader diff --git a/docker-compose.yml b/docker-compose.yml index 24c5b71..9c71634 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,16 +3,16 @@ services: build: context: . dockerfile: Dockerfile - container_name: upkeep + container_name: uptop restart: unless-stopped ports: - "23234:23234" - "8080:8080" environment: - - UPKEEP_DB_TYPE=sqlite - - UPKEEP_DB_DSN=/data/upkeep.db - - UPKEEP_HTTP_PORT=8080 - - UPKEEP_STATUS_ENABLED=true - - UPKEEP_STATUS_TITLE=System Status + - UPTOP_DB_TYPE=sqlite + - UPTOP_DB_DSN=/data/uptop.db + - UPTOP_HTTP_PORT=8080 + - UPTOP_STATUS_ENABLED=true + - UPTOP_STATUS_TITLE=System Status volumes: - ./data:/data diff --git a/docs/config-as-code.md b/docs/config-as-code.md index 1c9e8a1..1ce5411 100644 --- a/docs/config-as-code.md +++ b/docs/config-as-code.md @@ -7,13 +7,13 @@ Define your monitors and alerts in a YAML file. Version control them, copy them Export what you already have: ```bash -goupkeep export -o monitors.yaml +uptop export -o monitors.yaml ``` That gives you a working file you can edit and re-apply: ```bash -goupkeep apply -f monitors.yaml +uptop apply -f monitors.yaml ``` That's it. Apply only creates or updates — it won't delete anything unless you tell it to. @@ -184,34 +184,34 @@ All 9 providers work in the YAML. The `settings` map is different per type. **Export current state:** ```bash -goupkeep export -o monitors.yaml # to a file -goupkeep export # to stdout +uptop export -o monitors.yaml # to a file +uptop export # to stdout ``` **Apply a config:** ```bash -goupkeep apply -f monitors.yaml +uptop apply -f monitors.yaml ``` **See what would change first:** ```bash -goupkeep apply -f monitors.yaml --dry-run +uptop apply -f monitors.yaml --dry-run ``` **Delete monitors not in the YAML:** ```bash -goupkeep apply -f monitors.yaml --prune +uptop apply -f monitors.yaml --prune ``` Without `--prune`, apply never deletes anything. It only creates and updates. **Pointing at a different database:** ```bash -goupkeep export -db-type postgres -dsn "host=localhost dbname=upkeep sslmode=disable" -goupkeep apply -f monitors.yaml -db-type postgres -dsn "..." +uptop export -db-type postgres -dsn "host=localhost dbname=uptop sslmode=disable" +uptop apply -f monitors.yaml -db-type postgres -dsn "..." ``` -Both commands respect the `UPKEEP_DB_TYPE` and `UPKEEP_DB_DSN` environment variables too. +Both commands respect the `UPTOP_DB_TYPE` and `UPTOP_DB_DSN` environment variables too. ## How apply works @@ -230,15 +230,15 @@ If something fails mid-apply, just fix the issue and run it again. It picks up w ```bash # set up your monitors in the TUI first, then export -goupkeep export -o monitors.yaml +uptop export -o monitors.yaml # commit it git add monitors.yaml && git commit -m "add monitor config" # deploy to another instance scp monitors.yaml prod-server: -ssh prod-server goupkeep apply -f monitors.yaml +ssh prod-server uptop apply -f monitors.yaml # or just keep it as a backup you can restore from -goupkeep apply -f monitors.yaml +uptop apply -f monitors.yaml ``` diff --git a/go.mod b/go.mod index 38cc730..06b6111 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module go-upkeep +module gitea.lerkolabs.com/lerko/uptop go 1.24.4 diff --git a/internal/alert/alert.go b/internal/alert/alert.go index 12a2f41..e80a2e7 100644 --- a/internal/alert/alert.go +++ b/internal/alert/alert.go @@ -5,7 +5,7 @@ import ( "context" "encoding/json" "fmt" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "net/http" "net/smtp" "strconv" @@ -76,7 +76,7 @@ func pagerdutyPayload(routingKey, severity string) PayloadFunc { "event_action": "trigger", "payload": map[string]string{ "summary": fmt.Sprintf("%s: %s", title, message), - "source": "go-upkeep", + "source": "uptop", "severity": severity, }, }) @@ -184,7 +184,7 @@ func (e *EmailProvider) Send(ctx context.Context, title, message string) error { } auth := smtp.PlainAuth("", e.User, e.Pass, e.Host) msg := []byte("To: " + e.To + "\r\n" + - "Subject: Go-Upkeep: " + title + "\r\n" + + "Subject: uptop: " + title + "\r\n" + "\r\n" + message + "\r\n") return smtp.SendMail(e.Host+":"+e.Port, auth, e.From, []string{e.To}, msg) diff --git a/internal/alert/alert_test.go b/internal/alert/alert_test.go index 3314d17..3668cd0 100644 --- a/internal/alert/alert_test.go +++ b/internal/alert/alert_test.go @@ -3,7 +3,7 @@ package alert import ( "context" "encoding/json" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "net/http" "net/http/httptest" "testing" diff --git a/internal/cluster/cluster.go b/internal/cluster/cluster.go index 53cf847..b10580c 100644 --- a/internal/cluster/cluster.go +++ b/internal/cluster/cluster.go @@ -3,7 +3,7 @@ package cluster import ( "context" "fmt" - "go-upkeep/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" "net/http" "strings" "time" diff --git a/internal/cluster/cluster_test.go b/internal/cluster/cluster_test.go index 63eec88..504ed35 100644 --- a/internal/cluster/cluster_test.go +++ b/internal/cluster/cluster_test.go @@ -3,8 +3,8 @@ package cluster import ( "context" "encoding/json" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" "net/http" "net/http/httptest" "sync" diff --git a/internal/cluster/probe.go b/internal/cluster/probe.go index 4a04687..70197a4 100644 --- a/internal/cluster/probe.go +++ b/internal/cluster/probe.go @@ -6,8 +6,8 @@ import ( "crypto/tls" "encoding/json" "fmt" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" "log" "net/http" "sync" diff --git a/internal/config/apply.go b/internal/config/apply.go index ca37e36..c2cf2ef 100644 --- a/internal/config/apply.go +++ b/internal/config/apply.go @@ -2,8 +2,8 @@ package config import ( "fmt" - "go-upkeep/internal/models" - "go-upkeep/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/store" "reflect" "strings" ) diff --git a/internal/config/apply_test.go b/internal/config/apply_test.go index 824fd61..275180b 100644 --- a/internal/config/apply_test.go +++ b/internal/config/apply_test.go @@ -1,8 +1,8 @@ package config import ( - "go-upkeep/internal/models" - "go-upkeep/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/store" "strings" "testing" ) diff --git a/internal/config/export.go b/internal/config/export.go index dd9bdc6..57708fb 100644 --- a/internal/config/export.go +++ b/internal/config/export.go @@ -2,8 +2,8 @@ package config import ( "fmt" - "go-upkeep/internal/models" - "go-upkeep/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/store" "os" "sort" diff --git a/internal/config/export_test.go b/internal/config/export_test.go index 16b5534..f27c811 100644 --- a/internal/config/export_test.go +++ b/internal/config/export_test.go @@ -1,7 +1,7 @@ package config import ( - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "testing" ) diff --git a/internal/importer/kuma.go b/internal/importer/kuma.go index 953e5d1..e779d93 100644 --- a/internal/importer/kuma.go +++ b/internal/importer/kuma.go @@ -3,7 +3,7 @@ package importer import ( "encoding/json" "fmt" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "os" "strings" ) diff --git a/internal/metrics/prometheus.go b/internal/metrics/prometheus.go index 6e6e39e..37ec52a 100644 --- a/internal/metrics/prometheus.go +++ b/internal/metrics/prometheus.go @@ -2,8 +2,8 @@ package metrics import ( "fmt" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" "net/http" "sort" "strings" @@ -16,74 +16,74 @@ func Handler(eng *monitor.Engine) http.HandlerFunc { var b strings.Builder - writeHelp(&b, "upkeep_monitor_up", "gauge", "Whether the monitor is up (1) or down (0).") + writeHelp(&b, "uptop_monitor_up", "gauge", "Whether the monitor is up (1) or down (0).") for _, s := range sites { val := 0 if s.Status == "UP" { val = 1 } - writeGauge(&b, "upkeep_monitor_up", labels(s), float64(val)) + writeGauge(&b, "uptop_monitor_up", labels(s), float64(val)) } - writeHelp(&b, "upkeep_monitor_latency_seconds", "gauge", "Last check latency in seconds.") + writeHelp(&b, "uptop_monitor_latency_seconds", "gauge", "Last check latency in seconds.") for _, s := range sites { - writeGauge(&b, "upkeep_monitor_latency_seconds", labels(s), s.Latency.Seconds()) + writeGauge(&b, "uptop_monitor_latency_seconds", labels(s), s.Latency.Seconds()) } - writeHelp(&b, "upkeep_monitor_status_code", "gauge", "HTTP response status code of the last check.") + writeHelp(&b, "uptop_monitor_status_code", "gauge", "HTTP response status code of the last check.") for _, s := range sites { if s.Type != "http" { continue } - writeGauge(&b, "upkeep_monitor_status_code", labels(s), float64(s.StatusCode)) + writeGauge(&b, "uptop_monitor_status_code", labels(s), float64(s.StatusCode)) } - writeHelp(&b, "upkeep_monitor_check_timestamp_seconds", "gauge", "Unix timestamp of the last check.") + writeHelp(&b, "uptop_monitor_check_timestamp_seconds", "gauge", "Unix timestamp of the last check.") for _, s := range sites { if s.LastCheck.IsZero() { continue } - writeGauge(&b, "upkeep_monitor_check_timestamp_seconds", labels(s), float64(s.LastCheck.Unix())) + writeGauge(&b, "uptop_monitor_check_timestamp_seconds", labels(s), float64(s.LastCheck.Unix())) } - writeHelp(&b, "upkeep_monitor_paused", "gauge", "Whether the monitor is paused (1) or active (0).") + writeHelp(&b, "uptop_monitor_paused", "gauge", "Whether the monitor is paused (1) or active (0).") for _, s := range sites { val := 0 if s.Paused { val = 1 } - writeGauge(&b, "upkeep_monitor_paused", labels(s), float64(val)) + writeGauge(&b, "uptop_monitor_paused", labels(s), float64(val)) } - writeHelp(&b, "upkeep_monitor_maintenance", "gauge", "Whether the monitor is in a maintenance window (1) or not (0).") + writeHelp(&b, "uptop_monitor_maintenance", "gauge", "Whether the monitor is in a maintenance window (1) or not (0).") for _, s := range sites { val := 0 if eng.GetDisplayStatus(s) == "MAINT" { val = 1 } - writeGauge(&b, "upkeep_monitor_maintenance", labels(s), float64(val)) + writeGauge(&b, "uptop_monitor_maintenance", labels(s), float64(val)) } - writeHelp(&b, "upkeep_monitor_cert_expiry_timestamp_seconds", "gauge", "Unix timestamp when the SSL certificate expires.") + writeHelp(&b, "uptop_monitor_cert_expiry_timestamp_seconds", "gauge", "Unix timestamp when the SSL certificate expires.") for _, s := range sites { if !s.HasSSL || s.CertExpiry.IsZero() { continue } - writeGauge(&b, "upkeep_monitor_cert_expiry_timestamp_seconds", labels(s), float64(s.CertExpiry.Unix())) + writeGauge(&b, "uptop_monitor_cert_expiry_timestamp_seconds", labels(s), float64(s.CertExpiry.Unix())) } - writeHelp(&b, "upkeep_monitor_checks_total", "counter", "Total number of checks performed.") - writeHelp(&b, "upkeep_monitor_checks_up_total", "counter", "Total number of successful checks.") + writeHelp(&b, "uptop_monitor_checks_total", "counter", "Total number of checks performed.") + writeHelp(&b, "uptop_monitor_checks_up_total", "counter", "Total number of successful checks.") for _, s := range sites { h, ok := eng.GetHistory(s.ID) if !ok { continue } - writeGauge(&b, "upkeep_monitor_checks_total", labels(s), float64(h.TotalChecks)) - writeGauge(&b, "upkeep_monitor_checks_up_total", labels(s), float64(h.UpChecks)) + writeGauge(&b, "uptop_monitor_checks_total", labels(s), float64(h.TotalChecks)) + writeGauge(&b, "uptop_monitor_checks_up_total", labels(s), float64(h.UpChecks)) } - writeHelp(&b, "upkeep_probe_up", "gauge", "Whether a probe node is online (1) or offline (0) based on last-seen time.") + writeHelp(&b, "uptop_probe_up", "gauge", "Whether a probe node is online (1) or offline (0) based on last-seen time.") for _, site := range sites { probeResults := eng.GetProbeResults(site.ID) for nodeID, result := range probeResults { @@ -92,7 +92,7 @@ func Handler(eng *monitor.Engine) http.HandlerFunc { val = 1 } nodeLabels := fmt.Sprintf(`id="%d",name="%s",node="%s"`, site.ID, escapeLabelValue(site.Name), escapeLabelValue(nodeID)) - writeGauge(&b, "upkeep_probe_up", nodeLabels, float64(val)) + writeGauge(&b, "uptop_probe_up", nodeLabels, float64(val)) } } diff --git a/internal/metrics/prometheus_test.go b/internal/metrics/prometheus_test.go index 847d7cf..2fbccf7 100644 --- a/internal/metrics/prometheus_test.go +++ b/internal/metrics/prometheus_test.go @@ -2,8 +2,8 @@ package metrics import ( "context" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" "net/http" "net/http/httptest" "strings" @@ -94,13 +94,13 @@ func TestMetricsHandler(t *testing.T) { } expected := []string{ - "# HELP upkeep_monitor_up", - "# TYPE upkeep_monitor_up gauge", - `upkeep_monitor_up{id="1",name="Example",type="http"}`, - `upkeep_monitor_up{id="2",name="DNS Check",type="dns"}`, - "# HELP upkeep_monitor_latency_seconds", - "# HELP upkeep_monitor_paused", - "# HELP upkeep_monitor_checks_total", + "# HELP uptop_monitor_up", + "# TYPE uptop_monitor_up gauge", + `uptop_monitor_up{id="1",name="Example",type="http"}`, + `uptop_monitor_up{id="2",name="DNS Check",type="dns"}`, + "# HELP uptop_monitor_latency_seconds", + "# HELP uptop_monitor_paused", + "# HELP uptop_monitor_checks_total", } for _, s := range expected { if !strings.Contains(body, s) { diff --git a/internal/monitor/checker.go b/internal/monitor/checker.go index 0fadd5f..c3cb9da 100644 --- a/internal/monitor/checker.go +++ b/internal/monitor/checker.go @@ -2,7 +2,7 @@ package monitor import ( "context" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "net" "net/http" "strconv" diff --git a/internal/monitor/checker_test.go b/internal/monitor/checker_test.go index 39698b4..3db1324 100644 --- a/internal/monitor/checker_test.go +++ b/internal/monitor/checker_test.go @@ -2,7 +2,7 @@ package monitor import ( "crypto/tls" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "net" "net/http" "net/http/httptest" diff --git a/internal/monitor/monitor.go b/internal/monitor/monitor.go index c2b334e..a7a096b 100644 --- a/internal/monitor/monitor.go +++ b/internal/monitor/monitor.go @@ -4,9 +4,9 @@ import ( "context" "crypto/tls" "fmt" - "go-upkeep/internal/alert" - "go-upkeep/internal/models" - "go-upkeep/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/alert" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/store" "math/rand/v2" "net/http" "sync" diff --git a/internal/monitor/monitor_test.go b/internal/monitor/monitor_test.go index dd392de..f4c778b 100644 --- a/internal/monitor/monitor_test.go +++ b/internal/monitor/monitor_test.go @@ -2,7 +2,7 @@ package monitor import ( "fmt" - "go-upkeep/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/models" "sync" "testing" "time" diff --git a/internal/server/server.go b/internal/server/server.go index 2e94214..7908fae 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -4,11 +4,11 @@ import ( "crypto/subtle" "encoding/json" "fmt" - "go-upkeep/internal/importer" - "go-upkeep/internal/metrics" - "go-upkeep/internal/models" - "go-upkeep/internal/monitor" - "go-upkeep/internal/store" + "gitea.lerkolabs.com/lerko/uptop/internal/importer" + "gitea.lerkolabs.com/lerko/uptop/internal/metrics" + "gitea.lerkolabs.com/lerko/uptop/internal/models" + "gitea.lerkolabs.com/lerko/uptop/internal/monitor" + "gitea.lerkolabs.com/lerko/uptop/internal/store" "html/template" "log" "net/http" @@ -59,7 +59,7 @@ var statusTpl = template.Must(template.New("status").Parse(`
-
Powered by Go-Upkeep
+
Powered by uptop