feat: custom gesture & room metrics

This commit is contained in:
efim 2023-12-02 11:26:00 +00:00
parent 42c73c5902
commit c3b0f8e9d5
4 changed files with 76 additions and 12 deletions

12
main.go
View File

@ -10,6 +10,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/redis/go-redis/v9"
"sunshine.industries/some-automoderation/metrics"
"sunshine.industries/some-automoderation/rooms"
"sunshine.industries/some-automoderation/routes"
"sunshine.industries/some-automoderation/sessions"
@ -26,7 +27,10 @@ func main() {
flag.IntVar(&redisPort, "redisPort", 7777, "Port on which server should connect to redis db")
flag.Parse()
promHandler := promhttp.Handler()
metrics := metrics.SetupMetrics()
promhttp.Handler()
promHandler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{})
promMux := http.NewServeMux()
promMux.Handle("/metrics", promHandler)
@ -40,11 +44,11 @@ func main() {
DB: 0,
})
roomsM := rooms.RedisRM { Rdb: rdb, }
sessions := sessions.RedisSM{ Rdb: rdb, }
roomsM := rooms.RedisRM{Rdb: rdb}
sessions := sessions.RedisSM{Rdb: rdb}
log.Printf("Server will start on port: %d; /metrics on %d; listening to redis on: %d\n", port, metricsPort, redisPort)
routes.RegisterRoutes(sessions, roomsM)
routes.RegisterRoutes(sessions, roomsM, &metrics)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
}

43
metrics/metrics.go Normal file
View File

@ -0,0 +1,43 @@
package metrics
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
)
type MetricsContainer struct {
Registry *prometheus.Registry
LiveConnectionsGauge prometheus.Gauge
RaiseGestureCounter *prometheus.CounterVec
SpeakerCounter *prometheus.CounterVec
}
const GestureNameLabel string = "gestureString"
func SetupMetrics() MetricsContainer {
registry := prometheus.NewRegistry()
liveConnectionsGauge := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "live_connections_total",
Help: "Total amount of live SSE subscriptions to room state",
})
raiseGestureCounter := prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "raise_gesture_total",
Help: "Total amount of raised hands",
}, []string{GestureNameLabel})
speakerCounter := prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "speaker_total",
Help: "Total amount of speaker turns",
}, []string{GestureNameLabel})
registry.MustRegister(liveConnectionsGauge, raiseGestureCounter, speakerCounter,
collectors.NewGoCollector(),
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
)
return MetricsContainer{
Registry: registry,
LiveConnectionsGauge: liveConnectionsGauge,
RaiseGestureCounter: raiseGestureCounter,
SpeakerCounter: speakerCounter,
}
}

View File

@ -10,6 +10,7 @@ import (
"strconv"
"strings"
"sunshine.industries/some-automoderation/metrics"
"sunshine.industries/some-automoderation/rooms"
"sunshine.industries/some-automoderation/sessions"
)
@ -23,6 +24,7 @@ func registerPageRoutes(
templateFs *embed.FS,
sessionSM sessions.SessionManagement,
roomsM rooms.RoomManager,
metrics *metrics.MetricsContainer,
) {
http.Handle(roomPath, // ending in / captures all following path sections, i.e room name
http.StripPrefix(roomPath, roomPageRoute(templateFs, roomsM, sessionSM)))
@ -30,15 +32,15 @@ func registerPageRoutes(
http.Handle(raiseHandPath, // ending in / captures all following path sections, i.e gesture num
authedPageMiddleware(
sessionSM,
http.StripPrefix(raiseHandPath, raiseGestureHandRoute(roomsM))))
http.StripPrefix(raiseHandPath, raiseGestureHandRoute(roomsM, metrics))))
http.Handle("/rooms/releaseHand",
authedPageMiddleware(sessionSM, releaseHandRoute(roomsM)))
authedPageMiddleware(sessionSM, releaseHandRoute(roomsM, metrics)))
http.Handle(subscribeRoomPath,
authedPageMiddleware(
sessionSM,
http.StripPrefix(subscribeRoomPath, streamingRoomStates(templateFs, roomsM))))
http.StripPrefix(subscribeRoomPath, streamingRoomStates(templateFs, roomsM, metrics))))
http.HandleFunc("/rooms/preview-templates", roomTemplatesPreview(templateFs))
@ -48,8 +50,11 @@ func registerPageRoutes(
func streamingRoomStates(
templateFs *embed.FS,
roomsM rooms.RoomManager,
metrics *metrics.MetricsContainer,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
metrics.LiveConnectionsGauge.Inc()
defer metrics.LiveConnectionsGauge.Dec()
r.ParseForm()
roomName := r.FormValue("roomName")
defer log.Printf("/rooms/subscribe/%s stream ended\n", roomName)
@ -112,6 +117,7 @@ func streamingRoomStates(
// TODO should return control for raised state
func raiseGestureHandRoute(
roomsM rooms.RoomManager,
metrics *metrics.MetricsContainer,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
gestureInd, err := strconv.Atoi(r.URL.Path)
@ -120,6 +126,7 @@ func raiseGestureHandRoute(
log.Printf("/rooms/raiseGesture error %s gettin hand symbol index from path %s\n", err, r.URL.Path)
return
}
metrics.RaiseGestureCounter.WithLabelValues(selectedGesture.String()).Inc()
log.Printf("/rooms/raiseGesture successfully got gesture %d : %s", selectedGesture, selectedGesture.String())
session, found := getContextSession(r.Context())
if !found {
@ -129,6 +136,10 @@ func raiseGestureHandRoute(
}
var room rooms.Room
err = roomsM.Update(r.Context(), session.RoomId, func(fromRoom rooms.Room) (toRoom rooms.Room) {
if fromRoom.CurrentSpeaker == rooms.PersonId(0) {
// room had no speaker, need count new speaker turn
metrics.SpeakerCounter.WithLabelValues(selectedGesture.String()).Inc()
}
toRoom = fromRoom.RaiseHand(session.PersonId, selectedGesture)
room = toRoom
return toRoom
@ -167,6 +178,7 @@ func raiseGestureHandRoute(
// TODO should return lowered control for passed hand gesture, i guess optional
func releaseHandRoute(
roomsM rooms.RoomManager,
metrics *metrics.MetricsContainer,
) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, found := getContextSession(r.Context())
@ -179,6 +191,10 @@ func releaseHandRoute(
err := roomsM.Update(r.Context(), session.RoomId, func(fromRoom rooms.Room) (toRoom rooms.Room) {
toRoom = fromRoom
toRoom.ReleaseHand(session.PersonId)
if fromRoom.CurrentSpeaker != toRoom.CurrentSpeaker && toRoom.CurrentSpeaker != rooms.PersonId(0) {
gesture := toRoom.ParticipantHands[toRoom.CurrentSpeaker]
metrics.SpeakerCounter.WithLabelValues(gesture.String()).Inc()
}
return toRoom
})
if err != nil {

View File

@ -4,6 +4,7 @@ import (
"embed"
"net/http"
"sunshine.industries/some-automoderation/metrics"
"sunshine.industries/some-automoderation/rooms"
"sunshine.industries/some-automoderation/sessions"
)
@ -14,7 +15,7 @@ var templateFs embed.FS
//go:embed static
var staticFilesFs embed.FS
func RegisterRoutes(sessionsM sessions.SessionManagement, rooms rooms.RoomManager) {
func RegisterRoutes(sessionsM sessions.SessionManagement, rooms rooms.RoomManager, metrics *metrics.MetricsContainer) {
// login page
registerLoginRoutes(&templateFs, sessionsM, rooms)
@ -22,7 +23,7 @@ func RegisterRoutes(sessionsM sessions.SessionManagement, rooms rooms.RoomManage
http.Handle("/", indexPageRoute(&templateFs, sessionsM, rooms))
// main conversation room page
registerPageRoutes(&templateFs, sessionsM, rooms)
registerPageRoutes(&templateFs, sessionsM, rooms, metrics)
// static resources route
http.Handle("/static/",