Add some logging
Functions added: - LogErrorf() - LogErrorln() - LogChatf() - LogChatln() - LogInfof() - LogInfoln() - LogDebugf() - LogDebugln() - LogDevf() - LogDevln() New settings configure the logging: LogLevel and LogFile. LogLevel can be set to one of: error, chat, info, or debug and will default to error. LogFile is an optional file to write to. Providing a file will not prevent output in the console. LogDevf() and LogDevln() only compile when the "dev" flag passed to build. This will cause Travis-CI to fail the build if it finds any calls to either function.
This commit is contained in:
parent
cd34480bba
commit
fdbf39f00c
3
.gitignore
vendored
3
.gitignore
vendored
@ -12,6 +12,9 @@
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# GoCode debug file
|
||||
debug
|
||||
|
||||
|
19
Makefile
19
Makefile
@ -1,15 +1,22 @@
|
||||
.PHONY: fmt vet get clean
|
||||
TAGS=
|
||||
|
||||
.PHONY: fmt vet get clean dev setdev
|
||||
|
||||
all: fmt vet MovieNight MovieNight.exe static/main.wasm
|
||||
|
||||
setdev:
|
||||
$(eval export TAGS=-tags "dev")
|
||||
|
||||
dev: setdev all
|
||||
|
||||
MovieNight.exe: *.go common/*.go
|
||||
GOOS=windows GOARCH=amd64 go build -o MovieNight.exe
|
||||
GOOS=windows GOARCH=amd64 go build -o MovieNight.exe $(TAGS)
|
||||
|
||||
MovieNight: *.go common/*.go
|
||||
GOOS=linux GOARCH=386 go build -o MovieNight
|
||||
GOOS=linux GOARCH=386 go build -o MovieNight $(TAGS)
|
||||
|
||||
static/main.wasm: wasm/*.go common/*.go
|
||||
GOOS=js GOARCH=wasm go build -o ./static/main.wasm wasm/*.go
|
||||
GOOS=js GOARCH=wasm go build -o ./static/main.wasm $(TAGS) wasm/*.go
|
||||
|
||||
clean:
|
||||
-rm MovieNight.exe MovieNight ./static/main.wasm
|
||||
@ -23,5 +30,5 @@ get:
|
||||
go get golang.org/x/tools/cmd/goimports
|
||||
|
||||
vet:
|
||||
go vet ./...
|
||||
GOOS=js GOARCH=wasm go vet ./...
|
||||
go vet $(TAGS) ./...
|
||||
GOOS=js GOARCH=wasm go vet $(TAGS) ./...
|
||||
|
@ -24,13 +24,13 @@ type Client struct {
|
||||
func (cl *Client) NewMsg(data common.ClientData) {
|
||||
switch data.Type {
|
||||
case common.CdAuth:
|
||||
fmt.Printf("[chat|hidden] <%s> get auth level\n", cl.name)
|
||||
LogChatf("[chat|hidden] <%s> get auth level\n", cl.name)
|
||||
err := cl.SendChatData(common.NewChatHiddenMessage(data.Type, cl.CmdLevel))
|
||||
if err != nil {
|
||||
fmt.Printf("Error sending auth level to client: %v\n", err)
|
||||
LogErrorf("Error sending auth level to client: %v\n", err)
|
||||
}
|
||||
case common.CdUsers:
|
||||
fmt.Printf("[chat|hidden] <%s> get list of users\n", cl.name)
|
||||
common.LogChatf("[chat|hidden] <%s> get list of users\n", cl.name)
|
||||
|
||||
names := chat.GetNames()
|
||||
idx := -1
|
||||
@ -42,7 +42,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||
|
||||
err := cl.SendChatData(common.NewChatHiddenMessage(data.Type, append(names[:idx], names[idx+1:]...)))
|
||||
if err != nil {
|
||||
fmt.Printf("Error sending users to client: %v\n", err)
|
||||
common.LogErrorf("Error sending chat data: %v\n", err)
|
||||
}
|
||||
case common.CdMessage:
|
||||
msg := html.EscapeString(data.Message)
|
||||
@ -68,7 +68,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||
common.CmdlUser,
|
||||
common.MsgCommandResponse))
|
||||
if err != nil {
|
||||
fmt.Printf("Error command results %v\n", err)
|
||||
common.LogErrorf("Error command results %v\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -79,7 +79,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||
msg = msg[0:400]
|
||||
}
|
||||
|
||||
fmt.Printf("[chat] <%s> %q\n", cl.name, msg)
|
||||
common.LogChatf("[chat] <%s> %q\n", cl.name, msg)
|
||||
|
||||
// Enable links for mods and admins
|
||||
if cl.CmdLevel >= common.CmdlMod {
|
||||
|
@ -61,19 +61,19 @@ var commands = &CommandControl{
|
||||
if settings.AdminPassword == pw {
|
||||
cl.CmdLevel = common.CmdlAdmin
|
||||
cl.belongsTo.AddModNotice(cl.name + " used the admin password")
|
||||
fmt.Printf("[auth] %s used the admin password\n", cl.name)
|
||||
common.LogInfof("[auth] %s used the admin password\n", cl.name)
|
||||
return "Admin rights granted."
|
||||
}
|
||||
|
||||
if cl.belongsTo.redeemModPass(pw) {
|
||||
cl.CmdLevel = common.CmdlMod
|
||||
cl.belongsTo.AddModNotice(cl.name + " used a mod password")
|
||||
fmt.Printf("[auth] %s used a mod password\n", cl.name)
|
||||
common.LogInfof("[auth] %s used a mod password\n", cl.name)
|
||||
return "Moderator privileges granted."
|
||||
}
|
||||
|
||||
cl.belongsTo.AddModNotice(cl.name + " attempted to auth without success")
|
||||
fmt.Printf("[auth] %s gave an invalid password\n", cl.name)
|
||||
common.LogInfof("[auth] %s gave an invalid password\n", cl.name)
|
||||
return "Invalid password."
|
||||
},
|
||||
},
|
||||
@ -217,7 +217,7 @@ var commands = &CommandControl{
|
||||
}
|
||||
|
||||
name := strings.TrimLeft(args[0], "@")
|
||||
fmt.Printf("[ban] Attempting to ban %s\n", name)
|
||||
common.LogInfof("[ban] Attempting to ban %s\n", name)
|
||||
return cl.belongsTo.Ban(name)
|
||||
},
|
||||
},
|
||||
@ -229,7 +229,7 @@ var commands = &CommandControl{
|
||||
return "missing name to unban."
|
||||
}
|
||||
name := strings.TrimLeft(args[0], "@")
|
||||
fmt.Printf("[ban] Attempting to unban %s\n", name)
|
||||
common.LogInfof("[ban] Attempting to unban %s\n", name)
|
||||
|
||||
err := settings.RemoveBan(name)
|
||||
if err != nil {
|
||||
@ -243,7 +243,7 @@ var commands = &CommandControl{
|
||||
common.CNPurge.String(): Command{
|
||||
HelpText: "Purge the chat.",
|
||||
Function: func(cl *Client, args []string) string {
|
||||
fmt.Println("[purge] clearing chat")
|
||||
common.LogInfoln("[purge] clearing chat")
|
||||
cl.belongsTo.AddCmdMsg(common.CmdPurgeChat, nil)
|
||||
return ""
|
||||
},
|
||||
@ -282,12 +282,12 @@ var commands = &CommandControl{
|
||||
cl.SendServerMessage("Reloading emotes")
|
||||
num, err := common.LoadEmotes()
|
||||
if err != nil {
|
||||
fmt.Printf("Unbale to reload emotes: %s\n", err)
|
||||
common.LogErrorf("Unbale to reload emotes: %s\n", err)
|
||||
return fmt.Sprintf("ERROR: %s", err)
|
||||
}
|
||||
|
||||
cl.belongsTo.AddModNotice(cl.name + " has reloaded emotes")
|
||||
fmt.Printf("Loaded %d emotes\n", num)
|
||||
common.LogInfof("Loaded %d emotes\n", num)
|
||||
return fmt.Sprintf("Emotes loaded: %d", num)
|
||||
},
|
||||
},
|
||||
@ -302,17 +302,17 @@ var commands = &CommandControl{
|
||||
},
|
||||
|
||||
common.CNIP.String(): Command{
|
||||
HelpText: "list users and IP in the server console",
|
||||
HelpText: "List users and IP in the server console. Requires logging level to be set to info or above.",
|
||||
Function: func(cl *Client, args []string) string {
|
||||
cl.belongsTo.clientsMtx.Lock()
|
||||
fmt.Println("Clients:")
|
||||
common.LogInfoln("Clients:")
|
||||
for uuid, client := range cl.belongsTo.clients {
|
||||
fmt.Printf(" [%s] %s %s\n", uuid, client.name, client.conn.Host())
|
||||
common.LogInfof(" [%s] %s %s\n", uuid, client.name, client.conn.Host())
|
||||
}
|
||||
|
||||
fmt.Println("TmpConn:")
|
||||
common.LogInfoln("TmpConn:")
|
||||
for uuid, conn := range cl.belongsTo.tempConn {
|
||||
fmt.Printf(" [%s] %s\n", uuid, conn.Host())
|
||||
common.LogInfof(" [%s] %s\n", uuid, conn.Host())
|
||||
}
|
||||
cl.belongsTo.clientsMtx.Unlock()
|
||||
return "see console for output"
|
||||
@ -327,33 +327,33 @@ func (cc *CommandControl) RunCommand(command string, args []string, sender *Clie
|
||||
|
||||
// Look for user command
|
||||
if userCmd, ok := cc.user[cmd]; ok {
|
||||
fmt.Printf("[user] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[user] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return userCmd.Function(sender, args)
|
||||
}
|
||||
|
||||
// Look for mod command
|
||||
if modCmd, ok := cc.mod[cmd]; ok {
|
||||
if sender.CmdLevel >= common.CmdlMod {
|
||||
fmt.Printf("[mod] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[mod] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return modCmd.Function(sender, args)
|
||||
}
|
||||
|
||||
fmt.Printf("[mod REJECTED] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[mod REJECTED] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return "You are not a mod Jebaited"
|
||||
}
|
||||
|
||||
// Look for admin command
|
||||
if adminCmd, ok := cc.admin[cmd]; ok {
|
||||
if sender.CmdLevel == common.CmdlAdmin {
|
||||
fmt.Printf("[admin] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[admin] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return adminCmd.Function(sender, args)
|
||||
}
|
||||
fmt.Printf("[admin REJECTED] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[admin REJECTED] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return "You are not the admin Jebaited"
|
||||
}
|
||||
|
||||
// Command not found
|
||||
fmt.Printf("[cmd] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
common.LogInfof("[cmd] %s /%s %s\n", sender.name, command, strings.Join(args, " "))
|
||||
return "Invalid command."
|
||||
}
|
||||
|
||||
@ -416,31 +416,31 @@ var cmdColor = Command{
|
||||
if strings.HasPrefix(args[0], "@") {
|
||||
name = strings.TrimLeft(args[0], "@")
|
||||
color = args[1]
|
||||
fmt.Println("Found explicit name: ", name)
|
||||
common.LogDebugln("[color:mod] Found explicit name: ", name)
|
||||
} else if strings.HasPrefix(args[1], "@") {
|
||||
name = strings.TrimLeft(args[1], "@")
|
||||
color = args[0]
|
||||
fmt.Println("Found explicit name: ", name)
|
||||
common.LogDebugln("[color:mod] Found explicit name: ", name)
|
||||
|
||||
// Check for explicit color
|
||||
} else if strings.HasPrefix(args[0], "#") {
|
||||
name = strings.TrimPrefix(args[1], "@") // this shouldn't be needed, but just in case.
|
||||
color = args[0]
|
||||
fmt.Println("Found explicit color: ", color)
|
||||
common.LogDebugln("[color:mod] Found explicit color: ", color)
|
||||
} else if strings.HasPrefix(args[1], "#") {
|
||||
name = strings.TrimPrefix(args[0], "@") // this shouldn't be needed, but just in case.
|
||||
color = args[1]
|
||||
fmt.Println("Found explicit color: ", color)
|
||||
common.LogDebugln("[color:mod] Found explicit color: ", color)
|
||||
|
||||
// Guess
|
||||
} else if common.IsValidColor(args[0]) {
|
||||
name = strings.TrimPrefix(args[1], "@")
|
||||
color = args[0]
|
||||
fmt.Println("Guessed name: ", name, " and color: ", color)
|
||||
common.LogDebugln("[color:mod] Guessed name: ", name, " and color: ", color)
|
||||
} else if common.IsValidColor(args[1]) {
|
||||
name = strings.TrimPrefix(args[0], "@")
|
||||
color = args[1]
|
||||
fmt.Println("Guessed name: ", name, " and color: ", color)
|
||||
common.LogDebugln("[color:mod] Guessed name: ", name, " and color: ", color)
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
@ -451,12 +451,12 @@ var cmdColor = Command{
|
||||
}
|
||||
|
||||
if color == "" {
|
||||
fmt.Printf("[color:mod] %s missing color\n", cl.name)
|
||||
common.LogInfof("[color:mod] %s missing color\n", cl.name)
|
||||
return "Missing color"
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
fmt.Printf("[color:mod] %s missing name\n", cl.name)
|
||||
common.LogInfof("[color:mod] %s missing name\n", cl.name)
|
||||
return "Missing name"
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ var cmdColor = Command{
|
||||
// Don't allow an unprivilaged user to change their color if
|
||||
// it was changed by a mod
|
||||
if cl.IsColorForced {
|
||||
fmt.Printf("[color] %s tried to change a forced color\n", cl.name)
|
||||
common.LogInfof("[color] %s tried to change a forced color\n", cl.name)
|
||||
return "You are not allowed to change your color."
|
||||
}
|
||||
|
||||
@ -484,7 +484,7 @@ var cmdColor = Command{
|
||||
}
|
||||
|
||||
cl.color = args[0]
|
||||
fmt.Printf("[color] %s new color: %s\n", cl.name, cl.color)
|
||||
common.LogInfof("[color] %s new color: %s\n", cl.name, cl.color)
|
||||
return "Color changed successfully."
|
||||
},
|
||||
}
|
||||
|
32
chatroom.go
32
chatroom.go
@ -45,7 +45,7 @@ func newChatRoom() (*ChatRoom, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading emotes: %s", err)
|
||||
}
|
||||
fmt.Printf("Loaded %d emotes\n", num)
|
||||
common.LogInfof("Loaded %d emotes\n", num)
|
||||
|
||||
//the "heartbeat" for broadcasting messages
|
||||
go cr.Broadcast()
|
||||
@ -113,10 +113,10 @@ func (cr *ChatRoom) Join(name, uid string) (*Client, error) {
|
||||
cr.clients[uid] = client
|
||||
delete(cr.tempConn, uid)
|
||||
|
||||
fmt.Printf("[join] %s %s\n", host, name)
|
||||
common.LogChatf("[join] %s %s\n", host, name)
|
||||
playingCommand, err := common.NewChatCommand(common.CmdPlaying, []string{cr.playing, cr.playingLink}).ToJSON()
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to encode playing command on join: %s\n", err)
|
||||
common.LogErrorf("Unable to encode playing command on join: %s\n", err)
|
||||
} else {
|
||||
client.Send(playingCommand)
|
||||
}
|
||||
@ -132,7 +132,7 @@ func (cr *ChatRoom) Leave(name, color string) {
|
||||
|
||||
client, suid, err := cr.getClient(name)
|
||||
if err != nil {
|
||||
fmt.Printf("[leave] Unable to get client suid %v\n", err)
|
||||
common.LogErrorf("[leave] Unable to get client suid %v\n", err)
|
||||
return
|
||||
}
|
||||
host := client.Host()
|
||||
@ -141,7 +141,7 @@ func (cr *ChatRoom) Leave(name, color string) {
|
||||
cr.delClient(suid)
|
||||
|
||||
cr.AddEventMsg(common.EvLeave, name, color)
|
||||
fmt.Printf("[leave] %s %s\n", host, name)
|
||||
common.LogChatf("[leave] %s %s\n", host, name)
|
||||
}
|
||||
|
||||
// kicked from the chatroom
|
||||
@ -168,7 +168,7 @@ func (cr *ChatRoom) Kick(name string) string {
|
||||
cr.delClient(suid)
|
||||
|
||||
cr.AddEventMsg(common.EvKick, name, color)
|
||||
fmt.Printf("[kick] %s %s has been kicked\n", host, name)
|
||||
common.LogInfof("[kick] %s %s has been kicked\n", host, name)
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -178,7 +178,7 @@ func (cr *ChatRoom) Ban(name string) string {
|
||||
|
||||
client, suid, err := cr.getClient(name)
|
||||
if err != nil {
|
||||
fmt.Printf("[ban] Unable to get client for name %q\n", name)
|
||||
common.LogErrorf("[ban] Unable to get client for name %q\n", name)
|
||||
return "Cannot find that name"
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ func (cr *ChatRoom) Ban(name string) string {
|
||||
|
||||
err = settings.AddBan(host, names)
|
||||
if err != nil {
|
||||
fmt.Printf("[BAN] Error banning %q: %s\n", name, err)
|
||||
common.LogErrorf("[BAN] Error banning %q: %s\n", name, err)
|
||||
cr.AddEventMsg(common.EvKick, name, color)
|
||||
} else {
|
||||
cr.AddEventMsg(common.EvBan, name, color)
|
||||
@ -229,7 +229,7 @@ func (cr *ChatRoom) AddMsg(from *Client, isAction, isServer bool, msg string) {
|
||||
select {
|
||||
case cr.queue <- common.NewChatMessage(from.name, from.color, msg, from.CmdLevel, t):
|
||||
default:
|
||||
fmt.Println("Unable to queue chat message. Channel full.")
|
||||
common.LogErrorln("Unable to queue chat message. Channel full.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ func (cr *ChatRoom) AddCmdMsg(command common.CommandType, args []string) {
|
||||
select {
|
||||
case cr.queue <- common.NewChatCommand(command, args):
|
||||
default:
|
||||
fmt.Println("Unable to queue command message. Channel full.")
|
||||
common.LogErrorln("Unable to queue command message. Channel full.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ func (cr *ChatRoom) AddModNotice(message string) {
|
||||
select {
|
||||
case cr.modqueue <- common.NewChatMessage("", "", message, common.CmdlUser, common.MsgNotice):
|
||||
default:
|
||||
fmt.Println("Unable to queue notice. Channel full.")
|
||||
common.LogErrorln("Unable to queue notice. Channel full.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ func (cr *ChatRoom) AddEventMsg(event common.EventType, name, color string) {
|
||||
select {
|
||||
case cr.queue <- common.NewChatEvent(event, name, color):
|
||||
default:
|
||||
fmt.Println("Unable to queue event message. Channel full.")
|
||||
common.LogErrorln("Unable to queue event message. Channel full.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ func (cr *ChatRoom) Broadcast() {
|
||||
send := func(data common.ChatData, client *Client) {
|
||||
err := client.SendChatData(data)
|
||||
if err != nil {
|
||||
fmt.Printf("Error sending data to client: %v\n", err)
|
||||
common.LogErrorf("Error sending data to client: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ func (cr *ChatRoom) Broadcast() {
|
||||
|
||||
data, err := msg.ToJSON()
|
||||
if err != nil {
|
||||
fmt.Printf("Error converting ChatData to ChatDataJSON: %v\n", err)
|
||||
common.LogErrorf("Error converting ChatData to ChatDataJSON: %v\n", err)
|
||||
cr.clientsMtx.Unlock()
|
||||
break
|
||||
}
|
||||
@ -342,7 +342,7 @@ func (cr *ChatRoom) Broadcast() {
|
||||
go func(c *chatConnection, suid string) {
|
||||
err = c.WriteData(data)
|
||||
if err != nil {
|
||||
fmt.Printf("Error writing data to connection: %v\n", err)
|
||||
common.LogErrorf("Error writing data to connection: %v\n", err)
|
||||
delete(cr.tempConn, suid)
|
||||
}
|
||||
}(conn, uuid)
|
||||
@ -484,7 +484,7 @@ func (cr *ChatRoom) changeName(oldName, newName string, forced bool) error {
|
||||
|
||||
if currentClient != nil {
|
||||
currentClient.name = newName
|
||||
fmt.Printf("%q -> %q\n", oldName, newName)
|
||||
common.LogDebugf("%q -> %q\n", oldName, newName)
|
||||
|
||||
if forced {
|
||||
cr.AddEventMsg(common.EvNameChangeForced, oldName+":"+newName, currentClient.color)
|
||||
|
@ -47,14 +47,15 @@ func LoadEmotes() (int, error) {
|
||||
globbed_files := []string(emotePNGs)
|
||||
globbed_files = append(globbed_files, emoteGIFs...)
|
||||
|
||||
fmt.Println("Loading emotes...")
|
||||
LogInfoln("Loading emotes...")
|
||||
emInfo := []string{}
|
||||
for _, file := range globbed_files {
|
||||
file = filepath.Base(file)
|
||||
key := file[0 : len(file)-4]
|
||||
newEmotes[key] = file
|
||||
fmt.Printf("%s ", key)
|
||||
emInfo = append(emInfo, key)
|
||||
}
|
||||
Emotes = newEmotes
|
||||
fmt.Println("")
|
||||
LogInfoln(strings.Join(emInfo, " "))
|
||||
return len(Emotes), nil
|
||||
}
|
||||
|
211
common/logging.go
Normal file
211
common/logging.go
Normal file
@ -0,0 +1,211 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
var loglevel LogLevel
|
||||
|
||||
type LogLevel string
|
||||
|
||||
const (
|
||||
LLError LogLevel = "error" // only log errors
|
||||
LLChat LogLevel = "chat" // log chat and commands
|
||||
LLInfo LogLevel = "info" // log info messages (not quite debug, but not chat)
|
||||
LLDebug LogLevel = "debug" // log everything
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefixError string = "[ERROR] "
|
||||
logPrefixChat string = "[CHAT] "
|
||||
logPrefixInfo string = "[INFO] "
|
||||
logPrefixDebug string = "[DEBUG] "
|
||||
logPrefixDev string = "[DEV] "
|
||||
)
|
||||
|
||||
var (
|
||||
logError *log.Logger
|
||||
logChat *log.Logger
|
||||
logInfo *log.Logger
|
||||
logDebug *log.Logger
|
||||
logDev *log.Logger
|
||||
)
|
||||
|
||||
//func ParseLogLevel(input string) LogLevel {
|
||||
// switch LogLevel(input) {
|
||||
// case LLError, LLChat, LLInfo, LLDebug:
|
||||
// return LogLevel(input)
|
||||
// default:
|
||||
// return LLError
|
||||
// }
|
||||
//}
|
||||
|
||||
func SetupLogging(level LogLevel, file string) error {
|
||||
switch level {
|
||||
case LLDebug:
|
||||
if file == "" {
|
||||
logError = log.New(os.Stderr, logPrefixError, log.LstdFlags)
|
||||
logChat = log.New(os.Stdout, logPrefixChat, log.LstdFlags)
|
||||
logDebug = log.New(os.Stdout, logPrefixDebug, log.LstdFlags)
|
||||
logInfo = log.New(os.Stdout, logPrefixInfo, log.LstdFlags)
|
||||
} else {
|
||||
f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to open log file for writing: %s", err)
|
||||
}
|
||||
logError = log.New(io.MultiWriter(os.Stderr, f), logPrefixError, log.LstdFlags)
|
||||
logChat = log.New(io.MultiWriter(os.Stdout, f), logPrefixChat, log.LstdFlags)
|
||||
logInfo = log.New(io.MultiWriter(os.Stdout, f), logPrefixInfo, log.LstdFlags)
|
||||
logDebug = log.New(io.MultiWriter(os.Stdout, f), logPrefixDebug, log.LstdFlags)
|
||||
}
|
||||
case LLChat:
|
||||
logDebug = nil
|
||||
if file == "" {
|
||||
logError = log.New(os.Stderr, logPrefixError, log.LstdFlags)
|
||||
logChat = log.New(os.Stdout, logPrefixChat, log.LstdFlags)
|
||||
logInfo = log.New(os.Stdout, logPrefixInfo, log.LstdFlags)
|
||||
} else {
|
||||
f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to open log file for writing: %s", err)
|
||||
}
|
||||
logError = log.New(io.MultiWriter(os.Stderr, f), logPrefixError, log.LstdFlags)
|
||||
logChat = log.New(io.MultiWriter(os.Stdout, f), logPrefixChat, log.LstdFlags)
|
||||
logInfo = log.New(io.MultiWriter(os.Stdout, f), logPrefixInfo, log.LstdFlags)
|
||||
}
|
||||
|
||||
case LLInfo:
|
||||
logDebug = nil
|
||||
logChat = nil
|
||||
if file == "" {
|
||||
logError = log.New(os.Stderr, logPrefixError, log.LstdFlags)
|
||||
logInfo = log.New(os.Stdout, logPrefixInfo, log.LstdFlags)
|
||||
} else {
|
||||
f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to open log file for writing: %s", err)
|
||||
}
|
||||
logError = log.New(io.MultiWriter(os.Stderr, f), logPrefixError, log.LstdFlags)
|
||||
logInfo = log.New(io.MultiWriter(os.Stdout, f), logPrefixInfo, log.LstdFlags)
|
||||
}
|
||||
|
||||
// Default to error
|
||||
default:
|
||||
logChat = nil
|
||||
logDebug = nil
|
||||
logInfo = nil
|
||||
if file == "" {
|
||||
logError = log.New(os.Stderr, logPrefixError, log.LstdFlags)
|
||||
} else {
|
||||
f, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to open log file for writing: %s", err)
|
||||
}
|
||||
logError = log.New(io.MultiWriter(os.Stderr, f), logPrefixError, log.LstdFlags)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LogErrorf(format string, v ...interface{}) {
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
logError.Printf(format, v...)
|
||||
}
|
||||
|
||||
func LogErrorln(v ...interface{}) {
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
logError.Println(v...)
|
||||
}
|
||||
|
||||
func LogChatf(format string, v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging chat and commands is turned off.
|
||||
if logChat == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logChat.Printf(format, v...)
|
||||
}
|
||||
|
||||
func LogChatln(v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging chat and commands is turned off.
|
||||
if logChat == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logChat.Println(v...)
|
||||
}
|
||||
|
||||
func LogInfof(format string, v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging info is turned off.
|
||||
if logInfo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logInfo.Printf(format, v...)
|
||||
}
|
||||
|
||||
func LogInfoln(v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging info is turned off.
|
||||
if logInfo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logInfo.Println(v...)
|
||||
}
|
||||
|
||||
func LogDebugf(format string, v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging debug is turned off.
|
||||
if logDebug == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logDebug.Printf(format, v...)
|
||||
}
|
||||
|
||||
func LogDebugln(v ...interface{}) {
|
||||
// if logError isn't set to something, logging wasn't setup.
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
// logging debug is turned off.
|
||||
if logDebug == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logDebug.Println(v...)
|
||||
}
|
19
common/logging_dev.go
Normal file
19
common/logging_dev.go
Normal file
@ -0,0 +1,19 @@
|
||||
// +build dev
|
||||
|
||||
package common
|
||||
|
||||
func LogDevf(format string, v ...interface{}) {
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
logError.Printf(format, v...)
|
||||
}
|
||||
|
||||
func LogDevln(v ...interface{}) {
|
||||
if logError == nil {
|
||||
panic("Logging not setup!")
|
||||
}
|
||||
|
||||
logError.Println(v...)
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/zorchenhimer/MovieNight/common"
|
||||
)
|
||||
|
||||
type chatConnection struct {
|
||||
@ -31,7 +32,7 @@ func (cc *chatConnection) WriteData(data interface{}) error {
|
||||
err := cc.WriteJSON(data)
|
||||
if err != nil {
|
||||
if operr, ok := err.(*net.OpError); ok {
|
||||
fmt.Println("OpError: " + operr.Err.Error())
|
||||
common.LogDebugln("OpError: " + operr.Err.Error())
|
||||
}
|
||||
return fmt.Errorf("Error writing data to %s %s: %v", cc.clientName, cc.Host(), err)
|
||||
}
|
||||
|
44
handlers.go
44
handlers.go
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
@ -58,7 +57,7 @@ func wsStaticFiles(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
goodPath := r.URL.Path[8:len(r.URL.Path)]
|
||||
fmt.Printf("[static] serving %q from folder ./static/\n", goodPath)
|
||||
common.LogDebugf("[static] serving %q from folder ./static/\n", goodPath)
|
||||
|
||||
http.ServeFile(w, r, "./static/"+goodPath)
|
||||
}
|
||||
@ -70,7 +69,7 @@ func wsWasmFile(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func wsImages(w http.ResponseWriter, r *http.Request) {
|
||||
base := filepath.Base(r.URL.Path)
|
||||
fmt.Println("[img] ", base)
|
||||
common.LogDebugln("[img] ", base)
|
||||
http.ServeFile(w, r, "./static/img/"+base)
|
||||
}
|
||||
|
||||
@ -91,7 +90,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
fmt.Println("Error upgrading to websocket:", err)
|
||||
common.LogErrorln("Error upgrading to websocket:", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -107,7 +106,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
uid, err := chat.JoinTemp(chatConn)
|
||||
if err != nil {
|
||||
fmt.Printf("[handler] could not do a temp join, %v\n", err)
|
||||
common.LogErrorf("[handler] could not do a temp join, %v\n", err)
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
@ -117,7 +116,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var data common.ClientData
|
||||
err := chatConn.ReadData(&data)
|
||||
if err != nil {
|
||||
fmt.Printf("[handler] Client closed connection: %s\n", conn.RemoteAddr().String())
|
||||
common.LogInfof("[handler] Client closed connection: %s\n", conn.RemoteAddr().String())
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
@ -126,14 +125,14 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case UserFormatError, UserTakenError:
|
||||
fmt.Printf("[handler|%s] %v\n", errorName(err), err)
|
||||
common.LogInfof("[handler|%s] %v\n", errorName(err), err)
|
||||
case BannedUserError:
|
||||
fmt.Printf("[handler|%s] %v\n", errorName(err), err)
|
||||
common.LogInfof("[handler|%s] %v\n", errorName(err), err)
|
||||
// close connection since banned users shouldn't be connecting
|
||||
conn.Close()
|
||||
default:
|
||||
// for now all errors not caught need to be warned
|
||||
fmt.Printf("[handler|uncaught] %v\n", err)
|
||||
common.LogErrorf("[handler|uncaught] %v\n", err)
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
@ -156,7 +155,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func handleHelpTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
t, err := template.ParseFiles("./static/base.html", "./static/help.html")
|
||||
if err != nil {
|
||||
fmt.Printf("Error parsing template file, %v\n", err)
|
||||
common.LogErrorf("Error parsing template file, %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -182,14 +181,14 @@ func handleHelpTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err = t.Execute(w, data)
|
||||
if err != nil {
|
||||
fmt.Printf("Error executing file, %v", err)
|
||||
common.LogErrorf("Error executing file, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleIndexTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
t, err := template.ParseFiles("./static/base.html", "./static/main.html")
|
||||
if err != nil {
|
||||
fmt.Printf("Error parsing template file, %v\n", err)
|
||||
common.LogErrorf("Error parsing template file, %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -220,7 +219,7 @@ func handleIndexTemplate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err = t.Execute(w, data)
|
||||
if err != nil {
|
||||
fmt.Printf("Error executing file, %v", err)
|
||||
common.LogErrorf("Error executing file, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,22 +227,22 @@ func handlePublish(conn *rtmp.Conn) {
|
||||
streams, _ := conn.Streams()
|
||||
|
||||
l.Lock()
|
||||
fmt.Println("request string->", conn.URL.RequestURI())
|
||||
common.LogDebugln("request string->", conn.URL.RequestURI())
|
||||
urlParts := strings.Split(strings.Trim(conn.URL.RequestURI(), "/"), "/")
|
||||
fmt.Println("urlParts->", urlParts)
|
||||
common.LogDebugln("urlParts->", urlParts)
|
||||
|
||||
if len(urlParts) > 2 {
|
||||
fmt.Println("Extra garbage after stream key")
|
||||
common.LogErrorln("Extra garbage after stream key")
|
||||
return
|
||||
}
|
||||
|
||||
if len(urlParts) != 2 {
|
||||
fmt.Println("Missing stream key")
|
||||
common.LogErrorln("Missing stream key")
|
||||
return
|
||||
}
|
||||
|
||||
if urlParts[1] != settings.GetStreamKey() {
|
||||
fmt.Println("Due to key not match, denied stream")
|
||||
common.LogErrorln("Stream key is incorrect. Denying stream.")
|
||||
return //If key not match, deny stream
|
||||
}
|
||||
|
||||
@ -259,13 +258,13 @@ func handlePublish(conn *rtmp.Conn) {
|
||||
}
|
||||
l.Unlock()
|
||||
if ch == nil {
|
||||
fmt.Println("Unable to start stream, channel is nil.")
|
||||
common.LogErrorln("Unable to start stream, channel is nil.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Stream started")
|
||||
common.LogInfoln("Stream started")
|
||||
avutil.CopyPackets(ch.que, conn)
|
||||
fmt.Println("Stream finished")
|
||||
common.LogInfoln("Stream finished")
|
||||
|
||||
l.Lock()
|
||||
delete(channels, streamPath)
|
||||
@ -303,7 +302,8 @@ func handleDefault(w http.ResponseWriter, r *http.Request) {
|
||||
avutil.CopyFile(muxer, cursor)
|
||||
} else {
|
||||
if r.URL.Path != "/" {
|
||||
fmt.Println("[http 404] ", r.URL.Path)
|
||||
// not really an error for the server, but for the client.
|
||||
common.LogInfoln("[http 404] ", r.URL.Path)
|
||||
http.NotFound(w, r)
|
||||
} else {
|
||||
handleIndexTemplate(w, r)
|
||||
|
20
main.go
20
main.go
@ -2,13 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/nareix/joy4/format"
|
||||
"github.com/nareix/joy4/format/rtmp"
|
||||
"github.com/zorchenhimer/MovieNight/common"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -35,7 +35,7 @@ func main() {
|
||||
// Load emotes before starting server.
|
||||
var err error
|
||||
if chat, err = newChatRoom(); err != nil {
|
||||
fmt.Println(err)
|
||||
common.LogErrorln(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@ -43,15 +43,17 @@ func main() {
|
||||
addr = settings.ListenAddress
|
||||
}
|
||||
|
||||
common.LogDevln("This should break things")
|
||||
|
||||
// A stream key was passed on the command line. Use it, but don't save
|
||||
// it over the stream key in the settings.json file.
|
||||
if sKey != "" {
|
||||
settings.SetTempKey(sKey)
|
||||
}
|
||||
|
||||
fmt.Println("Stream key: ", settings.GetStreamKey())
|
||||
fmt.Println("Admin password: ", settings.AdminPassword)
|
||||
fmt.Println("Listen and serve ", addr)
|
||||
common.LogInfoln("Stream key: ", settings.GetStreamKey())
|
||||
common.LogInfoln("Admin password: ", settings.AdminPassword)
|
||||
common.LogInfoln("Listen and serve ", addr)
|
||||
|
||||
go startServer()
|
||||
go startRmtpServer()
|
||||
@ -66,7 +68,8 @@ func startRmtpServer() {
|
||||
}
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
fmt.Printf("Error trying to start server: %v\n", err)
|
||||
// If the server cannot start, don't pretend we can continue.
|
||||
panic("Error trying to start rtmp server: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +90,8 @@ func startServer() {
|
||||
|
||||
err := http.ListenAndServe(addr, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error trying to start rmtp server: %v\n", err)
|
||||
// If the server cannot start, don't pretend we can continue.
|
||||
panic("Error trying to start chat/http server: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +99,7 @@ func handleInterrupt(exit chan bool) {
|
||||
ch := make(chan os.Signal)
|
||||
signal.Notify(ch, os.Interrupt)
|
||||
<-ch
|
||||
fmt.Println("Closing server")
|
||||
common.LogInfoln("Closing server")
|
||||
if settings.StreamStats {
|
||||
stats.Print()
|
||||
}
|
||||
|
18
settings.go
18
settings.go
@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/zorchenhimer/MovieNight/common"
|
||||
)
|
||||
|
||||
var settings *Settings
|
||||
@ -27,6 +29,8 @@ type Settings struct {
|
||||
StreamKey string
|
||||
ListenAddress string
|
||||
Bans []BanInfo
|
||||
LogLevel common.LogLevel
|
||||
LogFile string
|
||||
}
|
||||
|
||||
type BanInfo struct {
|
||||
@ -45,8 +49,8 @@ func init() {
|
||||
panic("Missing stream key is settings.json")
|
||||
}
|
||||
|
||||
if settings.TitleLength <= 0 {
|
||||
settings.TitleLength = 50
|
||||
if err = common.SetupLogging(settings.LogLevel, settings.LogFile); err != nil {
|
||||
panic("Unable to setup logger: " + err.Error())
|
||||
}
|
||||
|
||||
// Save admin password to file
|
||||
@ -79,8 +83,14 @@ func LoadSettings(filename string) (*Settings, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to generate admin password: %s", err)
|
||||
}
|
||||
|
||||
// Don't use LogInfof() here. Log isn't setup yet when LoadSettings() is called from init().
|
||||
fmt.Printf("Settings reloaded. New admin password: %s\n", s.AdminPassword)
|
||||
|
||||
if s.TitleLength <= 0 {
|
||||
s.TitleLength = 50
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@ -122,7 +132,7 @@ func (s *Settings) AddBan(host string, names []string) error {
|
||||
}
|
||||
settings.Bans = append(settings.Bans, b)
|
||||
|
||||
fmt.Printf("[BAN] %q (%s) has been banned.\n", strings.Join(names, ", "), host)
|
||||
common.LogInfof("[BAN] %q (%s) has been banned.\n", strings.Join(names, ", "), host)
|
||||
|
||||
return settings.Save()
|
||||
}
|
||||
@ -136,7 +146,7 @@ func (s *Settings) RemoveBan(name string) error {
|
||||
for _, b := range s.Bans {
|
||||
for _, n := range b.Names {
|
||||
if n == name {
|
||||
fmt.Printf("[ban] Removed ban for %s [%s]\n", b.IP, n)
|
||||
common.LogInfof("[ban] Removed ban for %s [%s]\n", b.IP, n)
|
||||
} else {
|
||||
newBans = append(newBans, b)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user