feat: add loki health command (backport release-3.6.x) (#20590)

Co-authored-by: Jackson Coelho <fcjack@gmail.com>
This commit is contained in:
loki-gh-app[bot]
2026-01-28 09:35:46 +00:00
committed by GitHub
parent 40077783ce
commit dfdbe2a351
3 changed files with 100 additions and 4 deletions

72
cmd/loki/health.go Normal file
View File

@@ -0,0 +1,72 @@
package main
import (
"fmt"
"net/http"
"os"
"regexp"
"time"
)
const (
healthFlag = "health"
defaultHealthURL = "http://localhost:3100/ready"
healthTimeout = 5 * time.Second
)
// CheckHealth checks if args contain the -health flag
func CheckHealth(args []string) bool {
pattern := regexp.MustCompile(`^-+` + healthFlag + `$`)
for _, a := range args {
if pattern.MatchString(a) {
return true
}
}
return false
}
// RunHealthCheck performs a health check against the /ready endpoint
// Returns exit code 0 if healthy, 1 if unhealthy
func RunHealthCheck(args []string) int {
url := getHealthURL(args)
client := &http.Client{
Timeout: healthTimeout,
}
resp, err := client.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "Health check failed: %v\n", err)
return 1
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
fmt.Println("Loki is healthy")
return 0
}
fmt.Fprintf(os.Stderr, "Loki is unhealthy: status code %d\n", resp.StatusCode)
return 1
}
// getHealthURL extracts the URL from args or returns default
// Looks for -health.url=<url> or -health.url <url>
func getHealthURL(args []string) string {
urlPattern := regexp.MustCompile(`^-+health\.url[=:]?(.*)$`)
healthArgPattern := regexp.MustCompile(`^-`)
for i, a := range args {
if matches := urlPattern.FindStringSubmatch(a); matches != nil {
if matches[1] != "" {
return matches[1]
}
// Check next argument for the URL value
if i+1 < len(args) && !healthArgPattern.MatchString(args[i+1]) {
return args[i+1]
}
}
}
return defaultHealthURL
}

View File

@@ -33,6 +33,12 @@ func main() {
var config loki.ConfigWrapper
// Health check command - runs before any config parsing
// Usage: loki -health [-health.url=http://localhost:3100/ready]
if CheckHealth(os.Args[1:]) {
os.Exit(RunHealthCheck(os.Args[1:]))
}
if loki.PrintVersion(os.Args[1:]) {
fmt.Println(version.Print("loki"))
os.Exit(0)

View File

@@ -14,10 +14,6 @@ services:
init:
image: &lokiImage grafana/loki:latest
user: root
entrypoint:
- "chown"
- "10001:10001"
- "/loki"
volumes:
- ./loki:/loki
networks:
@@ -57,6 +53,7 @@ services:
# for testing purposes only, disable in production
log-generator:
image: mingrammer/flog
platform: linux/amd64
command:
- --loop
- --format=json
@@ -132,6 +129,13 @@ services:
deploy:
mode: replicated
replicas: 3
# Native healthcheck using loki -health command (no shell required)
healthcheck:
test: ["CMD", "/usr/bin/loki", "-health"]
start_period: 30s
interval: 30s
timeout: 10s
retries: 3
loki-write:
image: *lokiImage
@@ -154,6 +158,13 @@ services:
deploy:
mode: replicated
replicas: 3
# Native healthcheck using loki -health command (no shell required)
healthcheck:
test: ["CMD", "/usr/bin/loki", "-health"]
start_period: 30s
interval: 30s
timeout: 10s
retries: 3
loki-backend:
image: *lokiImage
@@ -177,6 +188,13 @@ services:
deploy:
mode: replicated
replicas: 3
# # Native healthcheck using loki -health command (no shell required)
healthcheck:
test: ["CMD", "/usr/bin/loki", "-health"]
start_period: 30s
interval: 30s
timeout: 10s
retries: 3
# alertmanager to enable receiving alerts
alertmanager: