Add "server status" command

Right now, it prints the number of active users and number of
downstream connections.
This commit is contained in:
Simon Ser 2021-10-05 19:12:25 +02:00
parent 0d2829c180
commit f93616fb41
3 changed files with 38 additions and 2 deletions

View File

@ -320,6 +320,9 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just
*user delete* <username> *user delete* <username>
Delete a soju user. Only admins can delete accounts. Delete a soju user. Only admins can delete accounts.
*server status*
Show some bouncer statistics. Only admins can query this information.
# AUTHORS # AUTHORS
Maintained by Simon Ser <contact@emersion.fr>, who is assisted by other Maintained by Simon Ser <contact@emersion.fr>, who is assisted by other

View File

@ -57,6 +57,7 @@ type Server struct {
db Database db Database
stopWG sync.WaitGroup stopWG sync.WaitGroup
connCount int64 // atomic
lock sync.Mutex lock sync.Mutex
listeners map[net.Listener]struct{} listeners map[net.Listener]struct{}
@ -165,6 +166,7 @@ func (s *Server) addUserLocked(user *User) *user {
var lastDownstreamID uint64 = 0 var lastDownstreamID uint64 = 0
func (s *Server) handle(ic ircConn) { func (s *Server) handle(ic ircConn) {
atomic.AddInt64(&s.connCount, 1)
id := atomic.AddUint64(&lastDownstreamID, 1) id := atomic.AddUint64(&lastDownstreamID, 1)
dc := newDownstreamConn(s, ic, id) dc := newDownstreamConn(s, ic, id)
if err := dc.runUntilRegistered(); err != nil { if err := dc.runUntilRegistered(); err != nil {
@ -177,6 +179,7 @@ func (s *Server) handle(ic ircConn) {
dc.user.events <- eventDownstreamDisconnected{dc} dc.user.events <- eventDownstreamDisconnected{dc}
} }
dc.Close() dc.Close()
atomic.AddInt64(&s.connCount, -1)
} }
func (s *Server) Serve(ln net.Listener) error { func (s *Server) Serve(ln net.Listener) error {
@ -249,3 +252,17 @@ func parseForwarded(h http.Header) map[string]string {
_, params, _ := mime.ParseMediaType("hack; " + forwarded) _, params, _ := mime.ParseMediaType("hack; " + forwarded)
return params return params
} }
type ServerStats struct {
Users int
Downstreams int64
}
func (s *Server) Stats() *ServerStats {
var stats ServerStats
s.lock.Lock()
stats.Users = len(s.users)
s.lock.Unlock()
stats.Downstreams = atomic.LoadInt64(&s.connCount)
return &stats
}

View File

@ -292,6 +292,16 @@ func init() {
}, },
}, },
}, },
"server": {
children: serviceCommandSet{
"status": {
desc: "show server statistics",
handle: handleServiceServerStatus,
admin: true,
},
},
admin: true,
},
} }
} }
@ -1007,3 +1017,9 @@ func handleServiceChannelUpdate(dc *downstreamConn, params []string) error {
sendServicePRIVMSG(dc, fmt.Sprintf("updated channel %q", name)) sendServicePRIVMSG(dc, fmt.Sprintf("updated channel %q", name))
return nil return nil
} }
func handleServiceServerStatus(dc *downstreamConn, params []string) error {
stats := dc.user.srv.Stats()
sendServicePRIVMSG(dc, fmt.Sprintf("%v users, %v downstreams", stats.Users, stats.Downstreams))
return nil
}