You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.8 KiB
108 lines
2.8 KiB
2 weeks ago
|
package health
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"time"
|
||
|
|
||
|
"github.com/azoic/wormhole-server/pkg/metrics"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
type HealthCheckServer struct {
|
||
|
server *http.Server
|
||
|
logger *logrus.Logger
|
||
|
metrics *metrics.Metrics
|
||
|
}
|
||
|
|
||
|
type HealthResponse struct {
|
||
|
Status string `json:"status"`
|
||
|
Timestamp string `json:"timestamp"`
|
||
|
Uptime string `json:"uptime"`
|
||
|
Metrics map[string]interface{} `json:"metrics,omitempty"`
|
||
|
}
|
||
|
|
||
|
func NewHealthCheckServer(addr, port string, logger *logrus.Logger, metrics *metrics.Metrics) *HealthCheckServer {
|
||
|
mux := http.NewServeMux()
|
||
|
hcs := &HealthCheckServer{
|
||
|
logger: logger,
|
||
|
metrics: metrics,
|
||
|
}
|
||
|
|
||
|
mux.HandleFunc("/health", hcs.healthHandler)
|
||
|
mux.HandleFunc("/metrics", hcs.metricsHandler)
|
||
|
mux.HandleFunc("/", hcs.rootHandler)
|
||
|
|
||
|
hcs.server = &http.Server{
|
||
|
Addr: fmt.Sprintf("%s:%s", addr, port),
|
||
|
Handler: mux,
|
||
|
}
|
||
|
|
||
|
return hcs
|
||
|
}
|
||
|
|
||
|
func (hcs *HealthCheckServer) Start() error {
|
||
|
hcs.logger.WithField("address", hcs.server.Addr).Info("Health check server starting")
|
||
|
return hcs.server.ListenAndServe()
|
||
|
}
|
||
|
|
||
|
func (hcs *HealthCheckServer) Stop(ctx context.Context) error {
|
||
|
hcs.logger.Info("Stopping health check server...")
|
||
|
return hcs.server.Shutdown(ctx)
|
||
|
}
|
||
|
|
||
|
func (hcs *HealthCheckServer) healthHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
response := HealthResponse{
|
||
|
Status: "healthy",
|
||
|
Timestamp: time.Now().Format(time.RFC3339),
|
||
|
Uptime: time.Since(hcs.metrics.StartTime).String(),
|
||
|
}
|
||
|
|
||
|
w.Header().Set("Content-Type", "application/json")
|
||
|
w.WriteHeader(http.StatusOK)
|
||
|
json.NewEncoder(w).Encode(response)
|
||
|
}
|
||
|
|
||
|
func (hcs *HealthCheckServer) metricsHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
response := HealthResponse{
|
||
|
Status: "healthy",
|
||
|
Timestamp: time.Now().Format(time.RFC3339),
|
||
|
Uptime: time.Since(hcs.metrics.StartTime).String(),
|
||
|
Metrics: hcs.metrics.GetStats(),
|
||
|
}
|
||
|
|
||
|
w.Header().Set("Content-Type", "application/json")
|
||
|
w.WriteHeader(http.StatusOK)
|
||
|
json.NewEncoder(w).Encode(response)
|
||
|
}
|
||
|
|
||
|
func (hcs *HealthCheckServer) rootHandler(w http.ResponseWriter, r *http.Request) {
|
||
|
html := `
|
||
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Wormhole SOCKS5 Proxy</title>
|
||
|
<style>
|
||
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
||
|
.status { color: green; font-weight: bold; }
|
||
|
.metrics { background: #f5f5f5; padding: 10px; margin: 10px 0; }
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>Wormhole SOCKS5 Proxy</h1>
|
||
|
<p>Status: <span class="status">Running</span></p>
|
||
|
<p>Endpoints:</p>
|
||
|
<ul>
|
||
|
<li><a href="/health">/health</a> - Health check</li>
|
||
|
<li><a href="/metrics">/metrics</a> - Metrics</li>
|
||
|
</ul>
|
||
|
</body>
|
||
|
</html>`
|
||
|
|
||
|
w.Header().Set("Content-Type", "text/html")
|
||
|
w.WriteHeader(http.StatusOK)
|
||
|
w.Write([]byte(html))
|
||
|
}
|