Skip to content

Commit c90ee46

Browse files
authored
RSDK-9752: Add -log-file to viam-server. (viamrobotics#4716)
1 parent 2b2ad24 commit c90ee46

File tree

5 files changed

+67
-4
lines changed

5 files changed

+67
-4
lines changed

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ require (
7777
go.uber.org/zap v1.27.0
7878
go.viam.com/api v0.1.380
7979
go.viam.com/test v1.2.4
80-
go.viam.com/utils v0.1.120
80+
go.viam.com/utils v0.1.123
8181
goji.io v2.0.2+incompatible
8282
golang.org/x/image v0.19.0
8383
golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b
@@ -94,6 +94,7 @@ require (
9494
google.golang.org/grpc v1.66.0
9595
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0
9696
google.golang.org/protobuf v1.35.1
97+
gopkg.in/natefinch/lumberjack.v2 v2.2.1
9798
gopkg.in/src-d/go-billy.v4 v4.3.2
9899
gorgonia.org/tensor v0.9.24
99100
gotest.tools/gotestsum v1.10.0

go.sum

+4-2
Original file line numberDiff line numberDiff line change
@@ -1517,8 +1517,8 @@ go.viam.com/api v0.1.380 h1:VgRHDlPBku+kjIp4omxmPNmRVZezytFUUOFJ2xpRFR8=
15171517
go.viam.com/api v0.1.380/go.mod h1:g5eipXHNm0rQmW7DWya6avKcmzoypLmxnMlAaIsE5Ls=
15181518
go.viam.com/test v1.2.4 h1:JYgZhsuGAQ8sL9jWkziAXN9VJJiKbjoi9BsO33TW3ug=
15191519
go.viam.com/test v1.2.4/go.mod h1:zI2xzosHdqXAJ/kFqcN+OIF78kQuTV2nIhGZ8EzvaJI=
1520-
go.viam.com/utils v0.1.120 h1:qwHt053zgcg6HtdDpP6Aj6lkmxZYyL1w6d43Ef18uso=
1521-
go.viam.com/utils v0.1.120/go.mod h1:g1CaEkf7aJCrSI/Sfkx+6cBS1+Y3fPT2pvMQbp7TTBI=
1520+
go.viam.com/utils v0.1.123 h1:0nxG3Rp9MmFn+qFbPQ4qSptz+hvm9MENbPXvKUBgRqU=
1521+
go.viam.com/utils v0.1.123/go.mod h1:g1CaEkf7aJCrSI/Sfkx+6cBS1+Y3fPT2pvMQbp7TTBI=
15221522
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 h1:WJhcL4p+YeDxmZWg141nRm7XC8IDmhz7lk5GpadO1Sg=
15231523
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
15241524
gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs=
@@ -2057,6 +2057,8 @@ gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
20572057
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
20582058
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
20592059
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
2060+
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
2061+
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
20602062
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
20612063
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
20622064
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=

logging/appender.go

+23
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88

99
"go.uber.org/zap/zapcore"
10+
"gopkg.in/natefinch/lumberjack.v2"
1011
)
1112

1213
// DefaultTimeFormatStr is the default time format string for log appenders.
@@ -36,6 +37,28 @@ func NewWriterAppender(writer io.Writer) ConsoleAppender {
3637
return ConsoleAppender{writer}
3738
}
3839

40+
// NewFileAppender will create an Appender that writes output to a log file. Log rotation will be
41+
// enabled such that restarts of the viam-server with the same filename will move the old file out
42+
// of the way. The `io.Closer` can be used to eventually close the opened log file.
43+
func NewFileAppender(filename string) (Appender, io.Closer) {
44+
logger := &lumberjack.Logger{
45+
Filename: filename,
46+
// 1 Terabyte -- basically infinite. Don't rollover on size. Just restarts.
47+
MaxSize: 1024 * 1024,
48+
}
49+
50+
// Dan: If we're restarting, explicitly call `Rotate` to write to a different file. This is a
51+
// convention I think is nice, but by no means a correctness requirement.
52+
if err := logger.Rotate(); err != nil {
53+
Global().Fatal("Error creating log file: ", err)
54+
}
55+
56+
// We only have `NewFileAppender` return an io.Closer, rather than `NewWriterAppender` because
57+
// `NewWriterAppender` accepts stdout from `NewStdoutAppender`. And I'm not certain that it's a
58+
// good idea to be calling `stdout.Close`.
59+
return NewWriterAppender(logger), logger
60+
}
61+
3962
// ZapcoreFieldsToJSON will serialize the Field objects into a JSON map of key/value pairs. It's
4063
// unclear what circumstances will result in an error being returned.
4164
func ZapcoreFieldsToJSON(fields []zapcore.Field) (string, error) {

logging/logging.go

+18
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ func NewBlankLogger(name string) Logger {
131131
return logger
132132
}
133133

134+
// NewBlankLoggerWithRegistry returns a new logger that outputs Debug+ logs in UTC, but without any
135+
// pre-existing appenders/outputs. It also returns the logger `Registry`.
136+
func NewBlankLoggerWithRegistry(name string) (Logger, *Registry) {
137+
logger := &impl{
138+
name: name,
139+
level: NewAtomicLevelAt(DEBUG),
140+
appenders: []Appender{},
141+
registry: newRegistry(),
142+
testHelper: func() {},
143+
recentMessageCounts: make(map[string]int),
144+
recentMessageEntries: make(map[string]LogEntry),
145+
recentMessageWindowStart: time.Now(),
146+
}
147+
148+
logger.registry.registerLogger(name, logger)
149+
return logger, logger.registry
150+
}
151+
134152
// NewTestLogger returns a new logger that outputs Debug+ logs to stdout in local time.
135153
func NewTestLogger(tb testing.TB) Logger {
136154
logger, _ := NewObservedTestLogger(tb)

web/server/entrypoint.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type Arguments struct {
5151
DisableMulticastDNS bool `flag:"disable-mdns,usage=disable server discovery through multicast DNS"`
5252
DumpResourcesPath string `flag:"dump-resources,usage=dump all resource registrations as json to the provided file path"`
5353
EnableFTDC bool `flag:"ftdc,default=true,usage=enable fulltime data capture for diagnostics"`
54+
OutputLogFile string `flag:"log-file,usage=write logs to a file with log rotation"`
5455
}
5556

5657
type robotServer struct {
@@ -70,6 +71,9 @@ func logViamEnvVariables(logger logging.Logger) {
7071
if value, exists := os.LookupEnv("VIAM_MODULE_STARTUP_TIMEOUT"); exists {
7172
viamEnvVariables = append(viamEnvVariables, "VIAM_MODULE_STARTUP_TIMEOUT", value)
7273
}
74+
if value, exists := os.LookupEnv("CWD"); exists {
75+
viamEnvVariables = append(viamEnvVariables, "CWD", value)
76+
}
7377
if rutils.PlatformHomeDir() != "" {
7478
viamEnvVariables = append(viamEnvVariables, "HOME", rutils.PlatformHomeDir())
7579
}
@@ -115,7 +119,22 @@ func RunServer(ctx context.Context, args []string, _ logging.Logger) (err error)
115119
return dumpResourceRegistrations(argsParsed.DumpResourcesPath)
116120
}
117121

118-
logger, registry := logging.NewLoggerWithRegistry("rdk")
122+
logger, registry := logging.NewBlankLoggerWithRegistry("rdk")
123+
// Dan: We changed from a constructor that defaulted to INFO to `NewBlankLoggerWithRegistry`
124+
// which defaults to DEBUG. We pessimistically set the level to INFO to ensure parity. Though I
125+
// expect `InitLoggingSettings` will always put the logger into the right state without any
126+
// observable side-effects.
127+
logger.SetLevel(logging.INFO)
128+
if argsParsed.OutputLogFile != "" {
129+
logWriter, closer := logging.NewFileAppender(argsParsed.OutputLogFile)
130+
defer func() {
131+
utils.UncheckedError(closer.Close())
132+
}()
133+
logger.AddAppender(logWriter)
134+
} else {
135+
logger.AddAppender(logging.NewStdoutAppender())
136+
}
137+
119138
logging.RegisterEventLogger(logger)
120139
logging.ReplaceGlobal(logger)
121140
config.InitLoggingSettings(logger, argsParsed.Debug)

0 commit comments

Comments
 (0)