107 lines
4.0 KiB
Go
107 lines
4.0 KiB
Go
// Package metrics provides in-process Prometheus-format instrumentation.
|
|
// All counters and gauges use atomic operations and are safe for concurrent use.
|
|
package metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
var startTime = time.Now()
|
|
|
|
// Counters and gauges — updated by callers in ws.go and api.go.
|
|
var (
|
|
wsConns atomic.Int64 // current open WebSocket connections (gauge)
|
|
msgIn atomic.Int64 // total WS messages received (counter)
|
|
msgOut atomic.Int64 // total WS messages sent (counter)
|
|
writeOps atomic.Int64 // total signal write operations (counter)
|
|
historyReqs atomic.Int64 // total history requests served (counter)
|
|
)
|
|
|
|
// IncWsConns increments the active WebSocket connection gauge.
|
|
func IncWsConns() { wsConns.Add(1) }
|
|
|
|
// DecWsConns decrements the active WebSocket connection gauge.
|
|
func DecWsConns() { wsConns.Add(-1) }
|
|
|
|
// IncMsgIn increments the total inbound WS message counter.
|
|
func IncMsgIn() { msgIn.Add(1) }
|
|
|
|
// IncMsgOut increments the total outbound WS message counter.
|
|
func IncMsgOut() { msgOut.Add(1) }
|
|
|
|
// IncWrites increments the signal write operation counter.
|
|
func IncWrites() { writeOps.Add(1) }
|
|
|
|
// IncHistoryReqs increments the history request counter.
|
|
func IncHistoryReqs() { historyReqs.Add(1) }
|
|
|
|
// Stats is a point-in-time snapshot of the in-process counters, for rendering
|
|
// as JSON in the admin pane (the Prometheus Handler renders the same data as
|
|
// text).
|
|
type Stats struct {
|
|
UptimeSeconds float64 `json:"uptimeSeconds"`
|
|
WsConnections int64 `json:"wsConnections"`
|
|
MsgIn int64 `json:"msgIn"`
|
|
MsgOut int64 `json:"msgOut"`
|
|
WriteOps int64 `json:"writeOps"`
|
|
HistoryReqs int64 `json:"historyReqs"`
|
|
}
|
|
|
|
// Snapshot returns the current values of all counters and gauges.
|
|
func Snapshot() Stats {
|
|
return Stats{
|
|
UptimeSeconds: time.Since(startTime).Seconds(),
|
|
WsConnections: wsConns.Load(),
|
|
MsgIn: msgIn.Load(),
|
|
MsgOut: msgOut.Load(),
|
|
WriteOps: writeOps.Load(),
|
|
HistoryReqs: historyReqs.Load(),
|
|
}
|
|
}
|
|
|
|
// Handler returns an http.HandlerFunc that renders Prometheus-format metrics.
|
|
// activeSubs is called each request to read the current number of unique signal
|
|
// subscriptions from the broker; pass nil to omit the metric.
|
|
func Handler(activeSubs func() int) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "text/plain; version=0.0.4; charset=utf-8")
|
|
|
|
uptime := time.Since(startTime).Seconds()
|
|
subs := 0
|
|
if activeSubs != nil {
|
|
subs = activeSubs()
|
|
}
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_uptime_seconds Seconds elapsed since the server started\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_uptime_seconds counter\n")
|
|
fmt.Fprintf(w, "uopi_uptime_seconds %.3f\n\n", uptime)
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_ws_connections Current number of open WebSocket connections\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_ws_connections gauge\n")
|
|
fmt.Fprintf(w, "uopi_ws_connections %d\n\n", wsConns.Load())
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_signal_subscriptions Current number of unique upstream signal subscriptions\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_signal_subscriptions gauge\n")
|
|
fmt.Fprintf(w, "uopi_signal_subscriptions %d\n\n", subs)
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_ws_messages_in_total Total WebSocket messages received from clients\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_ws_messages_in_total counter\n")
|
|
fmt.Fprintf(w, "uopi_ws_messages_in_total %d\n\n", msgIn.Load())
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_ws_messages_out_total Total WebSocket messages sent to clients\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_ws_messages_out_total counter\n")
|
|
fmt.Fprintf(w, "uopi_ws_messages_out_total %d\n\n", msgOut.Load())
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_write_ops_total Total signal write operations\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_write_ops_total counter\n")
|
|
fmt.Fprintf(w, "uopi_write_ops_total %d\n\n", writeOps.Load())
|
|
|
|
fmt.Fprintf(w, "# HELP uopi_history_requests_total Total historical data requests served\n")
|
|
fmt.Fprintf(w, "# TYPE uopi_history_requests_total counter\n")
|
|
fmt.Fprintf(w, "uopi_history_requests_total %d\n\n", historyReqs.Load())
|
|
}
|
|
}
|