Skip to content

Commit e0256aa

Browse files
committed
adding multiple log targets support for simple game server go
1 parent e489909 commit e0256aa

File tree

3 files changed

+76
-29
lines changed

3 files changed

+76
-29
lines changed

go.work.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
44
github.com/centrifugal/centrifuge v0.21.1/go.mod h1:uAFqaz85mlIw995eZblWzfuMj1Ok4jWNGZUMYbpQfbE=
55
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
66
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
7+
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
78
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
89
github.com/igm/sockjs-go/v3 v3.0.2/go.mod h1:UqchsOjeagIBFHvd+RZpLaVRbCwGilEC08EDHsD1jYE=
910
github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI=

simple-game-server-go/go.sum

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
github.com/FZambia/eagle v0.0.2 h1:35qHDuXSQevZ4w9A51k4wU7OE/tPHTEWXoywA93hvkY=
22
github.com/FZambia/sentinel v1.1.0 h1:qrCBfxc8SvJihYNjBWgwUI93ZCvFe/PJIPTHKmlp8a8=
3-
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.3.1 h1:piV2hAtoc5ke3ywkIvUs82J+CphjWXoN3219isDmY00=
4-
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.3.1/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
5-
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.0 h1:nH2XUCCx1BAV6hXhjSaIA+rOrzX2CRPz4/Yx/sZ26Do=
6-
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.0/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
73
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.4 h1:2KQYKCx44tEurLU5TlhmPhvKyvXo5QyBiTEfFqiC25g=
84
github.com/Unity-Technologies/unity-gaming-services-go-sdk v0.5.4/go.mod h1:WgDwSafd4alCs+HdK0z+7htBVZIe+LUrLQgM738WDd0=
95
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=

simple-game-server-go/main.go

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,105 @@ package main
22

33
import (
44
"flag"
5+
"io"
56
"os"
67
"path/filepath"
78
"runtime/debug"
9+
"strings"
810

9-
"github.com/Unity-Technologies/multiplay-examples/simple-game-server-go/internal/game"
1011
"github.com/sirupsen/logrus"
12+
13+
"github.com/Unity-Technologies/multiplay-examples/simple-game-server-go/internal/game"
1114
)
1215

1316
// parseFlags parses the supported flags and returns the values supplied to these flags.
1417
func parseFlags(args []string) (string, string, string, error) {
1518
dir, _ := os.UserHomeDir()
1619
f := flag.NewFlagSet("simple-game-server-go", flag.ContinueOnError)
1720

18-
var log, logFile, tracebackLevel string
19-
f.StringVar(&log, "log", filepath.Join(dir, "logs"), "path to the log directory to write to")
21+
var logTargets, logFile, tracebackLevel string
22+
f.StringVar(&logTargets, "log", "stdout,"+filepath.Join(dir, "logs"), "comma-separated log targets: 'stdout', file path, or directory")
2023
f.StringVar(&logFile, "logFile", "", "path to the log file to write to")
21-
f.StringVar(
22-
&tracebackLevel,
23-
"tracebackLevel",
24-
"",
25-
"the amount of detail printed by the runtime prints before exiting due to an unrecovered panic",
26-
)
24+
f.StringVar(&tracebackLevel, "tracebackLevel", "none", "the amount of detail printed by the runtime prints before exiting due to an unrecovered panic")
2725

2826
// Flags which are not used, but must be present to satisfy the default parameters in the Unity Dashboard.
2927
var port, queryPort uint
3028
f.UintVar(&port, "port", 8000, "port for the game server to bind to")
3129
f.UintVar(&queryPort, "queryport", 8001, "port for the query endpoint to bind to")
3230

33-
return log, logFile, tracebackLevel, f.Parse(args)
31+
return logTargets, logFile, tracebackLevel, f.Parse(args)
32+
}
33+
34+
// logWritersFromTargets creates a multi-writer from the specified log targets and log file.
35+
// If no valid targets are provided, it defaults to writing to stdout.
36+
func logWritersFromTargets(logTargets string, logFile string, logger *logrus.Logger) io.Writer {
37+
targets := make([]io.Writer, 0)
38+
for _, t := range splitAndTrim(logTargets) {
39+
switch t {
40+
case "stdout":
41+
targets = append(targets, os.Stdout)
42+
case "stderr":
43+
targets = append(targets, os.Stderr)
44+
default:
45+
// If it's a directory, use server.log inside it
46+
info, err := os.Stat(t)
47+
if err == nil && info.IsDir() {
48+
t = filepath.Join(t, "server.log")
49+
}
50+
f, err := os.OpenFile(t, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
51+
if err != nil {
52+
logger.WithError(err).Warningf("could not open log target %s for writing", t)
53+
continue
54+
}
55+
targets = append(targets, f)
56+
}
57+
}
58+
// logFile takes precedence
59+
if logFile != "" {
60+
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
61+
if err == nil {
62+
targets = append(targets, f)
63+
} else {
64+
logger.WithError(err).Warning("could not open log file for writing")
65+
}
66+
}
67+
if len(targets) == 0 {
68+
return os.Stdout
69+
}
70+
return io.MultiWriter(targets...)
71+
}
72+
73+
// splitAndTrim splits a string by the OS-specific path list separator and trims each part.
74+
func splitAndTrim(s string) []string {
75+
parts := make([]string, 0)
76+
for _, p := range filepath.SplitList(s) {
77+
for _, t := range splitComma(p) {
78+
trimmed := filepath.Clean(t)
79+
if trimmed != "" {
80+
parts = append(parts, trimmed)
81+
}
82+
}
83+
}
84+
return parts
85+
}
86+
87+
// splitComma splits a string by commas and trims each part, returning a slice of non-empty strings.
88+
func splitComma(s string) []string {
89+
res := make([]string, 0)
90+
for _, t := range strings.Split(s, ",") {
91+
trimmed := filepath.Clean(t)
92+
if trimmed != "" {
93+
res = append(res, trimmed)
94+
}
95+
}
96+
return res
3497
}
3598

3699
func main() {
37100
logger := logrus.New()
38101
logger.SetFormatter(&logrus.JSONFormatter{})
39102

40-
log, logFile, tracebackLevel, err := parseFlags(os.Args[1:])
103+
logTargets, logFile, tracebackLevel, err := parseFlags(os.Args[1:])
41104
if err != nil {
42105
logger.WithError(err).Fatal("error parsing flags")
43106
}
@@ -47,20 +110,7 @@ func main() {
47110
debug.SetTraceback(tracebackLevel)
48111
}
49112

50-
// Let -logFile take precedence over -log
51-
if logFile == "" && log != "" {
52-
logFile = filepath.Join(log, "server.log")
53-
}
54-
55-
if logFile != "" {
56-
f, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666)
57-
if err == nil {
58-
defer f.Close()
59-
logger.Out = f
60-
} else {
61-
logger.WithError(err).Warning("could not open log file for writing")
62-
}
63-
}
113+
logger.Out = logWritersFromTargets(logTargets, logFile, logger)
64114

65115
g, err := game.New(logger)
66116
if err != nil {

0 commit comments

Comments
 (0)