mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 09:48:32 +02:00
metrics: implement uptime and system metrics
This commit is contained in:
82
internal/metrics/period/handler.go
Normal file
82
internal/metrics/period/handler.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package period
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/coder/websocket"
|
||||
"github.com/coder/websocket/wsjson"
|
||||
metricsutils "github.com/yusing/go-proxy/internal/metrics/utils"
|
||||
"github.com/yusing/go-proxy/internal/net/gphttp"
|
||||
"github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
|
||||
"github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
|
||||
)
|
||||
|
||||
// ServeHTTP serves the data for the given period.
|
||||
//
|
||||
// If the period is not specified, it serves the last result.
|
||||
//
|
||||
// If the period is specified, it serves the data for the given period.
|
||||
//
|
||||
// If the period is invalid, it returns a 400 error.
|
||||
//
|
||||
// If the data is not found, it returns a 204 error.
|
||||
//
|
||||
// If the request is a websocket request, it serves the data for the given period for every interval.
|
||||
func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
|
||||
if httpheaders.IsWebsocket(r.Header) {
|
||||
interval := metricsutils.QueryDuration(query, "interval", 0)
|
||||
|
||||
minInterval := 1 * time.Second
|
||||
if interval == 0 {
|
||||
interval = pollInterval
|
||||
}
|
||||
if interval < minInterval {
|
||||
interval = minInterval
|
||||
}
|
||||
gpwebsocket.Periodic(w, r, interval, func(conn *websocket.Conn) error {
|
||||
data, err := p.getRespData(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
return wsjson.Write(r.Context(), conn, data)
|
||||
})
|
||||
} else {
|
||||
data, err := p.getRespData(r)
|
||||
if err != nil {
|
||||
gphttp.ServerError(w, r, err)
|
||||
return
|
||||
}
|
||||
if data == nil {
|
||||
http.Error(w, "no data", http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
gphttp.RespondJSON(w, r, data)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Poller[T, AggregateT]) getRespData(r *http.Request) (any, error) {
|
||||
query := r.URL.Query()
|
||||
period := query.Get("period")
|
||||
if period == "" {
|
||||
return p.GetLastResult(), nil
|
||||
}
|
||||
rangeData, ok := p.Get(Filter(period))
|
||||
if !ok {
|
||||
return nil, errors.New("invalid period")
|
||||
}
|
||||
total, aggregated := p.aggregate(rangeData, query)
|
||||
if total == -1 {
|
||||
return nil, errors.New("bad request")
|
||||
}
|
||||
return map[string]any{
|
||||
"total": total,
|
||||
"data": aggregated,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user