diff --git a/chatcommands.go b/chatcommands.go index 16ff2d4..09b3958 100644 --- a/chatcommands.go +++ b/chatcommands.go @@ -249,6 +249,23 @@ var commands = &CommandControl{ return "", nil }, }, + + common.CNStats.String(): Command{ + HelpText: "Show some stats for stream.", + Function: func(cl *Client, args []string) (string, error) { + cl.belongsTo.clientsMtx.Lock() + users := len(cl.belongsTo.clients) + cl.belongsTo.clientsMtx.Unlock() + + // Just print max users and time alive here + return fmt.Sprintf("Current users in chat: %d
Max users in chat: %d
Server uptime: %s
Stream uptime: %s", + users, + stats.getMaxUsers(), + time.Since(stats.start), + stats.getStreamLength(), + ), nil + }, + }, }, mod: map[string]Command{ diff --git a/chatroom.go b/chatroom.go index b71567d..2d37572 100644 --- a/chatroom.go +++ b/chatroom.go @@ -109,6 +109,8 @@ func (cr *ChatRoom) Join(conn *chatConnection, data common.JoinData) (*Client, e sendHiddenMessage(common.CdJoin, nil) sendHiddenMessage(common.CdEmote, common.Emotes) + stats.updateMaxUsers(len(cr.clients)) + return client, nil } diff --git a/common/chatcommands.go b/common/chatcommands.go index 8238422..d86433f 100644 --- a/common/chatcommands.go +++ b/common/chatcommands.go @@ -21,6 +21,7 @@ var ( CNAuth ChatCommandNames = []string{"auth"} CNUsers ChatCommandNames = []string{"users"} CNNick ChatCommandNames = []string{"nick", "name"} + CNStats ChatCommandNames = []string{"stats"} // Mod Commands CNSv ChatCommandNames = []string{"sv"} CNPlaying ChatCommandNames = []string{"playing"} @@ -50,6 +51,7 @@ var ChatCommands = []ChatCommandNames{ CNAuth, CNUsers, CNNick, + CNStats, // Mod CNSv, CNPlaying, CNUnmod, CNKick, CNBan, CNUnban, CNPurge, CNPin, diff --git a/handlers.go b/handlers.go index ce48890..42252e1 100644 --- a/handlers.go +++ b/handlers.go @@ -373,10 +373,14 @@ func handlePublish(conn *rtmp.Conn) { return } + stats.startStream() + common.LogInfoln("Stream started") avutil.CopyPackets(ch.que, conn) common.LogInfoln("Stream finished") + stats.endStream() + l.Lock() delete(channels, streamPath) l.Unlock() diff --git a/stats.go b/stats.go index c96ef3d..4fc8b26 100644 --- a/stats.go +++ b/stats.go @@ -10,12 +10,16 @@ import ( type streamStats struct { messageIn int messageOut int + maxUsers int start time.Time mutex sync.Mutex + + streamStart time.Time + streamLive bool // True if live } func newStreamStats() streamStats { - return streamStats{start: time.Now()} + return streamStats{start: time.Now(), streamLive: false} } func (s *streamStats) msgInInc() { @@ -23,14 +27,59 @@ func (s *streamStats) msgInInc() { s.messageIn++ s.mutex.Unlock() } + func (s *streamStats) msgOutInc() { s.mutex.Lock() s.messageOut++ s.mutex.Unlock() } +func (s *streamStats) updateMaxUsers(count int) { + s.mutex.Lock() + if count > s.maxUsers { + s.maxUsers = count + } + s.mutex.Unlock() +} + +func (s *streamStats) getMaxUsers() int { + s.mutex.Lock() + defer s.mutex.Unlock() + + return s.maxUsers +} + func (s *streamStats) Print() { + s.mutex.Lock() + defer s.mutex.Unlock() + common.LogInfof("Messages In: %d\n", s.messageIn) common.LogInfof("Messages Out: %d\n", s.messageOut) + common.LogInfof("Max users in chat: %d\n", s.maxUsers) common.LogInfof("Total Time: %s\n", time.Since(s.start)) } + +func (s *streamStats) startStream() { + s.mutex.Lock() + defer s.mutex.Unlock() + + s.streamLive = true + s.streamStart = time.Now() +} + +func (s *streamStats) endStream() { + s.mutex.Lock() + defer s.mutex.Unlock() + + s.streamLive = false +} + +func (s *streamStats) getStreamLength() time.Duration { + s.mutex.Lock() + defer s.mutex.Unlock() + + if !s.streamLive { + return 0 + } + return time.Since(s.streamStart) +}