1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-08-03 00:18:31 +00:00

Expose server statistics at /stats

This commit is contained in:
Kane York 2015-11-16 13:25:25 -08:00
parent a3971a27bf
commit c38b9b0018
4 changed files with 43 additions and 10 deletions

View file

@ -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 {

View file

@ -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())

View file

@ -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 {

View file

@ -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)
}