-
Notifications
You must be signed in to change notification settings - Fork 110
/
log.go
79 lines (65 loc) · 2.48 KB
/
log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package module
import (
"context"
"os"
"time"
"go.uber.org/zap/zapcore"
"go.viam.com/rdk/logging"
)
type moduleAppender struct {
stdoutAppender *logging.ConsoleAppender
// If Module is set, moduleAppender sends log events to the Unix socket at
// Module.parentAddr via gRPC. Otherwise, moduleAppender logs to STDOUT.
module *Module
}
func newModuleAppender() *moduleAppender {
stdoutAppender := logging.NewStdoutAppender()
return &moduleAppender{stdoutAppender: &stdoutAppender}
}
func (ma *moduleAppender) setModule(m *Module) {
ma.module = m
}
// Write sends the log entry back to the module's parent via gRPC or, if not
// possible, outputs the log entry to the underlying stream.
func (ma *moduleAppender) Write(log zapcore.Entry, fields []zapcore.Field) error {
if ma.module == nil {
return ma.stdoutAppender.Write(log, fields)
}
// Only give 5 seconds for ModuleLog call in case parent (RDK) is shutting
// down or otherwise unreachable.
moduleLogCtx, moduleLogCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer moduleLogCancel()
return ma.module.parent.Log(moduleLogCtx, log, fields)
}
// Sync is a no-op (moduleAppenders do not currently have buffers that needs
// flushing via Sync).
func (ma *moduleAppender) Sync() error {
return nil
}
// TODO(RSDK-6280): Preserve timezones for moduleLogger.
type moduleLogger struct {
logging.Logger
modAppender *moduleAppender
}
// NewLoggerFromArgs can be used to create a logging.Logger at "DebugLevel" if
// "--log-level=debug" is the third argument in os.Args and at "InfoLevel"
// otherwise. See config.Module.LogLevel documentation for more info on how
// to start modules with a "log-level" commandline argument. The created logger
// will send log events back to the module's parent (the RDK) via gRPC when
// possible and to STDOUT when not possible.
func NewLoggerFromArgs(moduleName string) logging.Logger {
modAppender := newModuleAppender()
baseLogger := logging.NewBlankLogger(moduleName)
baseLogger.AddAppender(modAppender)
// Use DEBUG logging only if 3rd OS argument is "--log-level=debug".
if len(os.Args) < 3 || os.Args[2] != "--log-level=debug" {
baseLogger.SetLevel(logging.INFO)
}
return &moduleLogger{baseLogger, modAppender}
}
// startLoggingViaGRPC switches the moduleLogger to gRPC logging. To be used
// once a ReadyRequest has been received from the parent, and the module's
// parent's address is known.
func (ml *moduleLogger) startLoggingViaGRPC(m *Module) {
ml.modAppender.setModule(m)
}