84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package matrixbot
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type healthResponse struct {
|
|
Status string `json:"status"`
|
|
Mode string `json:"mode"`
|
|
Rooms int `json:"rooms"`
|
|
LastSync string `json:"last_sync,omitempty"`
|
|
LastEvent string `json:"last_event,omitempty"`
|
|
LastSend string `json:"last_send,omitempty"`
|
|
LastSendError string `json:"last_send_error,omitempty"`
|
|
Received int64 `json:"received"`
|
|
Responded int64 `json:"responded"`
|
|
Dropped int64 `json:"dropped"`
|
|
RateLimited int64 `json:"rate_limited"`
|
|
EncryptedSkipped int64 `json:"encrypted_skipped"`
|
|
}
|
|
|
|
func (b *Bot) startHealthServer(ctx context.Context) {
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/healthz", b.handleHealth)
|
|
mux.HandleFunc("/metrics", b.handleHealth)
|
|
|
|
srv := &http.Server{
|
|
Addr: b.cfg.HealthAddr,
|
|
Handler: mux,
|
|
}
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
if err := srv.Shutdown(shutdownCtx); err != nil {
|
|
log.Printf("Matrix health server shutdown error: %v", err)
|
|
}
|
|
}()
|
|
|
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
log.Printf("Matrix health server error: %v", err)
|
|
}
|
|
}
|
|
|
|
func (b *Bot) handleHealth(w http.ResponseWriter, _ *http.Request) {
|
|
snapshot := b.stats.Snapshot()
|
|
mode := "active"
|
|
if b.cfg.Shadow {
|
|
mode = "shadow"
|
|
}
|
|
payload := healthResponse{
|
|
Status: "ok",
|
|
Mode: mode,
|
|
Rooms: len(b.allowedRooms),
|
|
LastSync: formatTime(snapshot.LastSync),
|
|
LastEvent: formatTime(snapshot.LastEvent),
|
|
LastSend: formatTime(snapshot.LastSend),
|
|
LastSendError: snapshot.LastSendError,
|
|
Received: snapshot.Received,
|
|
Responded: snapshot.Responded,
|
|
Dropped: snapshot.Dropped,
|
|
RateLimited: snapshot.RateLimited,
|
|
EncryptedSkipped: snapshot.EncryptedSkipped,
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
if err := json.NewEncoder(w).Encode(payload); err != nil {
|
|
log.Printf("Matrix health encode error: %v", err)
|
|
}
|
|
}
|
|
|
|
func formatTime(t time.Time) string {
|
|
if t.IsZero() {
|
|
return ""
|
|
}
|
|
return t.UTC().Format(time.RFC3339)
|
|
}
|