Skip to content

Commit ca4c946

Browse files
feat: Add comprehensive health check endpoints with real-time monitoring (#18)
* feat: Implement health monitoring functionality - Add health check command to CLI for checking the health status of the parity client and its services. - Introduce health handler with endpoints for basic health, detailed health, readiness, and liveness checks. - Update Makefile to include versioning information during build. - Enhance README with comprehensive health monitoring documentation and usage examples. - Refactor router to handle health check endpoints. * refactor: streamline variable declaration in health handler
1 parent 0f2fc7e commit ca4c946

7 files changed

Lines changed: 573 additions & 17 deletions

File tree

Makefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,14 @@ deps:
5050
go mod download
5151

5252
build: ## Build the application
53-
$(GOBUILD) $(BUILD_FLAGS) -o $(BINARY_NAME) ./cmd
53+
$(eval VERSION := $(shell git describe --tags --always --dirty))
54+
$(eval COMMIT := $(shell git rev-parse HEAD))
55+
$(eval BUILD_TIME := $(shell date -u '+%Y-%m-%d_%H:%M:%S'))
56+
$(GOBUILD) $(BUILD_FLAGS) \
57+
-ldflags "-X github.com/theblitlabs/parity-client/internal/version.Version=$(VERSION) \
58+
-X github.com/theblitlabs/parity-client/internal/version.CommitSHA=$(COMMIT) \
59+
-X github.com/theblitlabs/parity-client/internal/version.BuildTime=$(BUILD_TIME)" \
60+
-o $(BINARY_NAME) ./cmd
5461
chmod +x $(BINARY_NAME)
5562

5663
test: setup-coverage ## Run tests with coverage
@@ -73,6 +80,9 @@ balance: ## Check token balances
7380
auth: ## Authenticate with the network
7481
$(GOCMD) run $(MAIN_PATH) auth
7582

83+
health: ## Check health status
84+
$(GOCMD) run $(MAIN_PATH) health
85+
7686
clean: ## Clean build files
7787
rm -f $(BINARY_NAME)
7888
find . -type f -name '*.test' -delete

README.md

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,111 @@ curl -X POST http://localhost:3000/api/tasks \
361361
}'
362362
```
363363

364+
### Health Monitoring
365+
366+
The parity client provides comprehensive health monitoring endpoints for operational visibility:
367+
368+
#### Basic Health Check
369+
370+
```bash
371+
# Command line health check
372+
parity-client health
373+
374+
# HTTP health check
375+
curl http://localhost:3000/health
376+
```
377+
378+
#### Detailed Health Information
379+
380+
```bash
381+
# Get detailed health status
382+
parity-client health --detailed
383+
384+
# HTTP detailed health check
385+
curl http://localhost:3000/health/detailed
386+
```
387+
388+
#### Kubernetes-style Probes
389+
390+
```bash
391+
# Readiness probe (for Kubernetes deployments)
392+
curl http://localhost:3000/health/ready
393+
394+
# Liveness probe (for Kubernetes deployments)
395+
curl http://localhost:3000/health/live
396+
```
397+
398+
#### Health Check Options
399+
400+
```bash
401+
# Check health with custom endpoint
402+
parity-client health --endpoint http://your-server:8080
403+
404+
# Set custom timeout
405+
parity-client health --timeout 30s
406+
407+
# Get detailed information
408+
parity-client health --detailed
409+
```
410+
411+
#### Health Check Response Format
412+
413+
Basic health check response:
414+
```json
415+
{
416+
"status": "healthy",
417+
"timestamp": "2024-01-15T10:30:00Z",
418+
"version": "v1.0.0",
419+
"uptime": "2h30m15s",
420+
"services": {
421+
"blockchain": "configured",
422+
"ipfs": "configured",
423+
"runner": "configured"
424+
}
425+
}
426+
```
427+
428+
Detailed health check response:
429+
```json
430+
{
431+
"status": "healthy",
432+
"timestamp": "2024-01-15T10:30:00Z",
433+
"version": "v1.0.0",
434+
"uptime": "2h30m15s",
435+
"services": {
436+
"blockchain": {
437+
"status": "healthy",
438+
"last_check": "2024-01-15T10:29:55Z",
439+
"latency": "125ms"
440+
},
441+
"ipfs": {
442+
"status": "healthy",
443+
"last_check": "2024-01-15T10:29:58Z",
444+
"latency": "45ms"
445+
},
446+
"runner": {
447+
"status": "healthy",
448+
"last_check": "2024-01-15T10:30:00Z",
449+
"latency": "78ms"
450+
}
451+
},
452+
"config": {
453+
"server_host": "0.0.0.0",
454+
"server_port": 3000,
455+
"blockchain_rpc": "https://your-blockchain-node.com",
456+
"ipfs_endpoint": "http://localhost:5001",
457+
"runner_url": "http://localhost:8080"
458+
}
459+
}
460+
```
461+
462+
**Note**: All health check data is real-time:
463+
- **Uptime**: Actual application uptime since start
464+
- **Version**: Real version from git tags and build info
465+
- **Service Status**: Live connectivity tests to blockchain, IPFS, and runner services
466+
- **Latency**: Actual response times from service health checks
467+
- **Configuration**: Real configuration values from your environment
468+
364469
## Configuration Files
365470

366471
### Model Configuration Examples
@@ -469,10 +574,12 @@ parity-client fl create-session \
469574

470575
### Health & Status Endpoints
471576

472-
| Method | Endpoint | Description |
473-
| ------ | ----------- | ------------- |
474-
| GET | /api/health | Health check |
475-
| GET | /api/status | System status |
577+
| Method | Endpoint | Description |
578+
| ------ | ------------------ | ------------------------------ |
579+
| GET | /health | Basic health check |
580+
| GET | /health/detailed | Detailed health information |
581+
| GET | /health/ready | Readiness probe |
582+
| GET | /health/live | Liveness probe |
476583

477584
## Development
478585

internal/commands/commands.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ func AddCommands(rootCmd *cobra.Command) {
99
rootCmd.AddCommand(llmCmd)
1010
rootCmd.AddCommand(flCmd)
1111
rootCmd.AddCommand(storageCmd)
12+
rootCmd.AddCommand(healthCmd)
1213
rootCmd.AddCommand(GetReputationCommand())
1314
}

internal/commands/health.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package commands
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"time"
8+
9+
"github.com/spf13/cobra"
10+
"github.com/theblitlabs/gologger"
11+
)
12+
13+
var healthCmd = &cobra.Command{
14+
Use: "health",
15+
Short: "Check health status of the parity client",
16+
Long: `Check the health status of the parity client and its connected services`,
17+
Run: runHealthCheck,
18+
}
19+
20+
var (
21+
healthDetailed bool
22+
healthEndpoint string
23+
healthTimeout time.Duration
24+
)
25+
26+
func init() {
27+
healthCmd.Flags().BoolVar(&healthDetailed, "detailed", false, "Get detailed health information")
28+
healthCmd.Flags().StringVar(&healthEndpoint, "endpoint", "http://localhost:3000", "Health check endpoint URL")
29+
healthCmd.Flags().DurationVar(&healthTimeout, "timeout", 10*time.Second, "Timeout for health check request")
30+
}
31+
32+
func runHealthCheck(cmd *cobra.Command, args []string) {
33+
logger := gologger.Get().With().Str("component", "health-cmd").Logger()
34+
35+
var url string
36+
if healthDetailed {
37+
url = fmt.Sprintf("%s/health/detailed", healthEndpoint)
38+
} else {
39+
url = fmt.Sprintf("%s/health", healthEndpoint)
40+
}
41+
42+
logger.Info().Str("url", url).Msg("Checking health status")
43+
44+
client := &http.Client{
45+
Timeout: healthTimeout,
46+
}
47+
48+
resp, err := client.Get(url)
49+
if err != nil {
50+
logger.Error().Err(err).Msg("Failed to connect to health endpoint")
51+
fmt.Printf("❌ Health check failed: %v\n", err)
52+
return
53+
}
54+
defer resp.Body.Close()
55+
56+
if resp.StatusCode != http.StatusOK {
57+
logger.Error().Int("status_code", resp.StatusCode).Msg("Health check returned non-OK status")
58+
fmt.Printf("❌ Health check failed with status: %d\n", resp.StatusCode)
59+
return
60+
}
61+
62+
var result map[string]interface{}
63+
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
64+
logger.Error().Err(err).Msg("Failed to decode health response")
65+
fmt.Printf("❌ Failed to decode health response: %v\n", err)
66+
return
67+
}
68+
69+
// Pretty print the JSON response
70+
prettyJSON, err := json.MarshalIndent(result, "", " ")
71+
if err != nil {
72+
logger.Error().Err(err).Msg("Failed to marshal health response")
73+
fmt.Printf("❌ Failed to format health response: %v\n", err)
74+
return
75+
}
76+
77+
fmt.Printf("✅ Health check successful\n")
78+
fmt.Printf("Status: %s\n", result["status"])
79+
fmt.Printf("Timestamp: %s\n", result["timestamp"])
80+
fmt.Printf("Version: %s\n", result["version"])
81+
82+
if healthDetailed {
83+
fmt.Printf("\nDetailed Information:\n")
84+
fmt.Println(string(prettyJSON))
85+
}
86+
}

0 commit comments

Comments
 (0)