mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-03 08:28:31 +00:00
Expose server statistics at /stats
This commit is contained in:
parent
a3971a27bf
commit
c38b9b0018
4 changed files with 43 additions and 10 deletions
|
@ -64,7 +64,7 @@ func getCacheKey(remoteCommand, data string) string {
|
|||
// The backend can POST here to publish a message to clients with no caching.
|
||||
// The POST arguments are `cmd`, `args`, `channel`, and `scope`.
|
||||
// The `scope` argument is required because no attempt is made to infer the scope from the command, unlike /cached_pub.
|
||||
func HBackendPublishRequest(w http.ResponseWriter, r *http.Request) {
|
||||
func HTTPBackendUncachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
formData, err := UnsealRequest(r.Form)
|
||||
if err != nil {
|
||||
|
|
|
@ -60,9 +60,11 @@ func SetupServerAndHandle(config *ConfigFile, serveMux *http.ServeMux) {
|
|||
BannerHTML = bannerBytes
|
||||
|
||||
serveMux.HandleFunc("/", HTTPHandleRootURL)
|
||||
serveMux.HandleFunc("/stats", HTTPShowStatistics)
|
||||
|
||||
serveMux.HandleFunc("/drop_backlog", HTTPBackendDropBacklog)
|
||||
serveMux.HandleFunc("/uncached_pub", HBackendPublishRequest)
|
||||
serveMux.HandleFunc("/cached_pub", HBackendUpdateAndPublish)
|
||||
serveMux.HandleFunc("/uncached_pub", HTTPBackendUncachedPublish)
|
||||
serveMux.HandleFunc("/cached_pub", HTTPBackendCachedPublish)
|
||||
|
||||
announceForm, err := SealRequest(url.Values{
|
||||
"startup": []string{"1"},
|
||||
|
@ -118,25 +120,34 @@ func HTTPHandleRootURL(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// ErrProtocolGeneric is sent in a ErrorCommand Reply.
|
||||
var ErrProtocolGeneric error = errors.New("FFZ Socket protocol error.")
|
||||
|
||||
// ErrProtocolNegativeMsgID is sent in a ErrorCommand Reply when a negative MessageID is received.
|
||||
var ErrProtocolNegativeMsgID error = errors.New("FFZ Socket protocol error: negative or zero message ID.")
|
||||
|
||||
// ErrExpectedSingleString is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedSingleString = errors.New("Error: Expected single string as arguments.")
|
||||
|
||||
// ErrExpectedSingleInt is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedSingleInt = errors.New("Error: Expected single integer as arguments.")
|
||||
|
||||
// ErrExpectedTwoStrings is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedTwoStrings = errors.New("Error: Expected array of string, string as arguments.")
|
||||
|
||||
// ErrExpectedStringAndBool is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedStringAndBool = errors.New("Error: Expected array of string, bool as arguments.")
|
||||
|
||||
// ErrExpectedStringAndInt is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedStringAndInt = errors.New("Error: Expected array of string, int as arguments.")
|
||||
|
||||
// ErrExpectedStringAndIntGotFloat is sent in a ErrorCommand Reply when the Arguments are of the wrong type.
|
||||
var ErrExpectedStringAndIntGotFloat = errors.New("Error: Second argument was a float, expected an integer.")
|
||||
|
||||
// CloseGotBinaryMessage is the termination reason when the client sends a binary websocket frame.
|
||||
var CloseGotBinaryMessage = websocket.CloseError{Code: websocket.CloseUnsupportedData, Text: "got binary packet"}
|
||||
|
||||
// CloseTimedOut is the termination reason when the client fails to send or respond to ping frames.
|
||||
var CloseTimedOut = websocket.CloseError{Code: websocket.CloseNoStatusReceived, Text: "no ping replies for 5 minutes"}
|
||||
|
||||
// CloseFirstMessageNotHello is the termination reason
|
||||
var CloseFirstMessageNotHello = websocket.CloseError{
|
||||
Text: "Error - the first message sent must be a 'hello'",
|
||||
|
@ -305,7 +316,7 @@ func getDeadline() time.Time {
|
|||
}
|
||||
|
||||
func CloseConnection(conn *websocket.Conn, closeMsg *websocket.CloseError) {
|
||||
Statistics.DisconnectCodes[closeMsg.Code]++
|
||||
Statistics.DisconnectCodes[strconv.Itoa(closeMsg.Code)]++
|
||||
Statistics.DisconnectReasons[closeMsg.Text]++
|
||||
|
||||
conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(closeMsg.Code, closeMsg.Text), getDeadline())
|
||||
|
|
|
@ -351,7 +351,7 @@ func HTTPBackendDropBacklog(w http.ResponseWriter, r *http.Request) {
|
|||
// Publish a message to clients, and update the in-server cache for the message.
|
||||
// notes:
|
||||
// `scope` is implicit in the command
|
||||
func HBackendUpdateAndPublish(w http.ResponseWriter, r *http.Request) {
|
||||
func HTTPBackendCachedPublish(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
formData, err := UnsealRequest(r.Form)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,26 +1,48 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type StatsData struct {
|
||||
ClientConnectsTotal int64
|
||||
ClientDisconnectsTotal int64
|
||||
ClientConnectsTotal int64
|
||||
ClientDisconnectsTotal int64
|
||||
FirstNotHelloDisconnects int64
|
||||
|
||||
DisconnectCodes map[int]int64
|
||||
DisconnectCodes map[string]int64
|
||||
DisconnectReasons map[string]int64
|
||||
|
||||
CommandsIssuedTotal int64
|
||||
CommandsIssuedMap map[Command]int64
|
||||
CommandsIssuedMap map[Command]int64
|
||||
|
||||
MessagesSent int64
|
||||
|
||||
Version int
|
||||
}
|
||||
|
||||
const StatsDataVersion = 1
|
||||
|
||||
func newStatsData() *StatsData {
|
||||
return &StatsData{
|
||||
CommandsIssuedMap: make(map[Command]int64),
|
||||
DisconnectCodes: make(map[int]int64),
|
||||
DisconnectCodes: make(map[string]int64),
|
||||
DisconnectReasons: make(map[string]int64),
|
||||
Version: StatsDataVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// Statistics is several variables that get incremented during normal operation of the server.
|
||||
// Its structure should be versioned as it is exposed via JSON.
|
||||
var Statistics = newStatsData()
|
||||
|
||||
func HTTPShowStatistics(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
jsonBytes, _ := json.Marshal(Statistics)
|
||||
outBuf := bytes.NewBuffer(nil)
|
||||
json.Indent(outBuf, jsonBytes, "", "\t")
|
||||
|
||||
outBuf.WriteTo(w)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue