feat: AUTO_UPDATE config option, null next_update_check when disabled

- AUTO_UPDATE=false in config file disables auto-updating
- --no-auto-update flag still works as an override
- next_update_check is omitted from pulses when auto-update is disabled
- status command shows auto-update enabled/disabled state
- config.example documents the new option
This commit is contained in:
Joel Male
2026-02-25 14:54:07 +10:00
parent ac607c2757
commit c9f6f282a6
2 changed files with 32 additions and 13 deletions
+3
View File
@@ -9,5 +9,8 @@ TOKEN=your-token-here
# Optional — defaults to https://pulsewise.app/api/collect # Optional — defaults to https://pulsewise.app/api/collect
# URL=http://localhost:8000/api/collect # URL=http://localhost:8000/api/collect
# Optional — set to false to disable automatic updates (default: true)
# AUTO_UPDATE=false
# Optional — logs full response body from the server # Optional — logs full response body from the server
# DEBUG=true # DEBUG=true
+24 -8
View File
@@ -181,7 +181,9 @@ func main() {
flag.Parse() flag.Parse()
config := loadConfig() config := loadConfig()
config.AutoUpdate = !*noAutoUpdate if *noAutoUpdate {
config.AutoUpdate = false
}
log.Printf("Starting Pulsewise collector (v%s)...", version) log.Printf("Starting Pulsewise collector (v%s)...", version)
log.Printf("Hostname: %s", config.Hostname) log.Printf("Hostname: %s", config.Hostname)
@@ -195,6 +197,8 @@ func main() {
if config.AutoUpdate { if config.AutoUpdate {
go runAutoUpdater(config) go runAutoUpdater(config)
} else {
nextUpdateCheck = nil
} }
ticker := time.NewTicker(config.Interval) ticker := time.NewTicker(config.Interval)
@@ -289,7 +293,7 @@ func runStatusCommand() {
fmt.Printf("\n%spulsewise-collector%s v%s\n\n", bold, nc, version) fmt.Printf("\n%spulsewise-collector%s v%s\n\n", bold, nc, version)
// Config // Config
token, hostname, url, _, err := loadConfigFromFile() token, hostname, url, _, autoUpdate, err := loadConfigFromFile()
if err != nil { if err != nil {
fmt.Printf("%s Not configured — %v\n\n", red, nc) fmt.Printf("%s Not configured — %v\n\n", red, nc)
} else { } else {
@@ -299,11 +303,16 @@ func runStatusCommand() {
} else { } else {
maskedToken = "****" maskedToken = "****"
} }
autoUpdateStr := green + "enabled" + nc
if !autoUpdate {
autoUpdateStr = dim + "disabled" + nc
}
fmt.Printf("%sCollector%s\n", bold, nc) fmt.Printf("%sCollector%s\n", bold, nc)
fmt.Printf("%s %s\n", label("Hostname"), hostname) fmt.Printf("%s %s\n", label("Hostname"), hostname)
fmt.Printf("%s %s\n", label("Token"), maskedToken) fmt.Printf("%s %s\n", label("Token"), maskedToken)
fmt.Printf("%s %s\n", label("API endpoint"), url) fmt.Printf("%s %s\n", label("API endpoint"), url)
fmt.Printf("%s %s\n", label("Interval"), collectionInterval) fmt.Printf("%s %s\n", label("Interval"), collectionInterval)
fmt.Printf("%s %s\n", label("Auto-update"), autoUpdateStr)
fmt.Println() fmt.Println()
} }
@@ -633,7 +642,7 @@ func execSelf() {
// ───────────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────────
func loadConfig() *Config { func loadConfig() *Config {
token, hostname, url, debug, err := loadConfigFromFile() token, hostname, url, debug, autoUpdate, err := loadConfigFromFile()
if err != nil { if err != nil {
log.Fatalf("Failed to load config: %v", err) log.Fatalf("Failed to load config: %v", err)
} }
@@ -644,10 +653,11 @@ func loadConfig() *Config {
URL: url, URL: url,
Interval: collectionInterval, Interval: collectionInterval,
Debug: debug, Debug: debug,
AutoUpdate: autoUpdate,
} }
} }
func loadConfigFromFile() (string, string, string, bool, error) { func loadConfigFromFile() (string, string, string, bool, bool, error) {
configPath := configFilePath configPath := configFilePath
if _, err := os.Stat(configPath); os.IsNotExist(err) { if _, err := os.Stat(configPath); os.IsNotExist(err) {
@@ -662,12 +672,13 @@ func loadConfigFromFile() (string, string, string, bool, error) {
file, err := os.Open(configPath) file, err := os.Open(configPath)
if err != nil { if err != nil {
return "", "", "", false, fmt.Errorf("config file not found at %s: %w", configPath, err) return "", "", "", false, false, fmt.Errorf("config file not found at %s: %w", configPath, err)
} }
defer file.Close() defer file.Close()
var token, hostname, url string var token, hostname, url string
var debug bool var debug bool
autoUpdate := true
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
for scanner.Scan() { for scanner.Scan() {
@@ -692,14 +703,19 @@ func loadConfigFromFile() (string, string, string, bool, error) {
val = strings.Trim(val, `"'`) val = strings.Trim(val, `"'`)
debug = val == "true" || val == "1" debug = val == "true" || val == "1"
} }
if strings.HasPrefix(line, "AUTO_UPDATE=") {
val := strings.TrimPrefix(line, "AUTO_UPDATE=")
val = strings.Trim(val, `"'`)
autoUpdate = val != "false" && val != "0"
}
} }
if err := scanner.Err(); err != nil { if err := scanner.Err(); err != nil {
return "", "", "", false, fmt.Errorf("error reading config file: %w", err) return "", "", "", false, false, fmt.Errorf("error reading config file: %w", err)
} }
if token == "" { if token == "" {
return "", "", "", false, fmt.Errorf("TOKEN not found in config file") return "", "", "", false, false, fmt.Errorf("TOKEN not found in config file")
} }
if hostname == "" { if hostname == "" {
hostname, _ = os.Hostname() hostname, _ = os.Hostname()
@@ -709,7 +725,7 @@ func loadConfigFromFile() (string, string, string, bool, error) {
url = defaultURL url = defaultURL
} }
return token, hostname, url, debug, nil return token, hostname, url, debug, autoUpdate, nil
} }
func collectAndSend(config *Config) { func collectAndSend(config *Config) {