Documentation
¶
Overview ¶
Package logging package contains functionality for viam-server logging.
Index ¶
- Constants
- Variables
- func CreateNewGRPCClient(ctx context.Context, cloudCfg *CloudConfig, logger Logger) (rpc.ClientConn, error)
- func EnableDebugMode(ctx context.Context) context.Context
- func EnableDebugModeWithKey(ctx context.Context, debugLogKey string) context.Context
- func FieldFromProto(field *structpb.Struct) (zap.Field, error)
- func FieldKeyAndValueFromProto(field *structpb.Struct) (string, any, error)
- func FieldToProto(field zap.Field) (*structpb.Struct, error)
- func GetName(ctx context.Context) string
- func IsDebugMode(ctx context.Context) bool
- func NewBlankLoggerWithRegistry(name string) (Logger, *Registry)
- func NewLoggerWithRegistry(name string) (Logger, *Registry)
- func NewObservedTestLoggerWithRegistry(tb testing.TB, name string) (Logger, *observer.ObservedLogs, *Registry)
- func NewZapLoggerConfig() zap.Config
- func RegisterEventLogger(rootLogger Logger)
- func ReplaceGlobal(logger Logger)
- func UnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, ...) error
- func UnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, ...) (interface{}, error)
- func ZapcoreFieldsToJSON(fields []zapcore.Field) (string, error)
- type Appender
- type AtomicLevel
- type CloudConfig
- type ConsoleAppender
- type Level
- type LogEntry
- type Logger
- func FromZapCompatible(logger ZapCompatibleLogger) Logger
- func Global() Logger
- func NewBlankLogger(name string) Logger
- func NewDebugLogger(name string) Logger
- func NewLogger(name string) Logger
- func NewObservedTestLogger(tb testing.TB) (Logger, *observer.ObservedLogs)
- func NewTestLogger(tb testing.TB) Logger
- type LoggerPatternConfig
- type MemLogger
- type NetAppender
- func (nl *NetAppender) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry
- func (nl *NetAppender) Close()
- func (nl *NetAppender) Enabled(level zapcore.Level) bool
- func (nl *NetAppender) SetConn(conn rpc.ClientConn, sharedConn bool)
- func (nl *NetAppender) Sync() error
- func (nl *NetAppender) With(f []zapcore.Field) zapcore.Core
- func (nl *NetAppender) Write(e zapcore.Entry, f []zapcore.Field) error
- type Registry
- type ZapCompatibleLogger
Constants ¶
const DefaultTimeFormatStr = "2006-01-02T15:04:05.000Z0700"
DefaultTimeFormatStr is the default time format string for log appenders.
Variables ¶
var (
// GlobalLogLevel should be used whenever a zap logger is created that wants to obey the debug
// flag from the CLI or robot config.
GlobalLogLevel = zap.NewAtomicLevelAt(zap.InfoLevel)
)
Functions ¶
func CreateNewGRPCClient ¶ added in v0.13.0
func CreateNewGRPCClient(ctx context.Context, cloudCfg *CloudConfig, logger Logger) (rpc.ClientConn, error)
CreateNewGRPCClient creates a new grpc cloud configured to communicate with the robot service based on the cloud config given.
func EnableDebugMode ¶ added in v0.16.0
func EnableDebugMode(ctx context.Context) context.Context
EnableDebugMode returns a new context with debug logging state attached with a randomly generated log key.
func EnableDebugModeWithKey ¶ added in v0.16.0
func EnableDebugModeWithKey(ctx context.Context, debugLogKey string) context.Context
EnableDebugModeWithKey returns a new context with debug logging state attached. An empty `debugLogKey` generates a random value.
func FieldFromProto ¶ added in v0.47.0
func FieldFromProto(field *structpb.Struct) (zap.Field, error)
FieldFromProto unmarshals a proto-encoded zap.Field.
func FieldKeyAndValueFromProto ¶ added in v0.23.0
func FieldKeyAndValueFromProto(field *structpb.Struct) (string, any, error)
FieldKeyAndValueFromProto examines a *structpb.Struct and returns its key string and native golang value.
func FieldToProto ¶ added in v0.23.0
func FieldToProto(field zap.Field) (*structpb.Struct, error)
FieldToProto converts a zap.Field to a *structpb.Struct.
func GetName ¶ added in v0.16.0
func GetName(ctx context.Context) string
GetName returns the debug log key included when enabling the context for debug logging.
func IsDebugMode ¶ added in v0.16.0
func IsDebugMode(ctx context.Context) bool
IsDebugMode returns whether the input context has debug logging enabled.
func NewBlankLoggerWithRegistry ¶ added in v0.59.0
func NewBlankLoggerWithRegistry(name string) (Logger, *Registry)
NewBlankLoggerWithRegistry returns a new logger that outputs Debug+ logs in UTC, but without any pre-existing appenders/outputs. It also returns the logger `Registry`.
func NewLoggerWithRegistry ¶ added in v0.43.0
func NewLoggerWithRegistry(name string) (Logger, *Registry)
NewLoggerWithRegistry is the same as NewLogger but also returns the associated Registry.
func NewObservedTestLoggerWithRegistry ¶ added in v0.43.0
func NewObservedTestLoggerWithRegistry(tb testing.TB, name string) (Logger, *observer.ObservedLogs, *Registry)
NewObservedTestLoggerWithRegistry is like NewObservedTestLogger but also returns the associated registry. It also takes a name for the logger.
func NewZapLoggerConfig ¶ added in v0.13.0
func NewZapLoggerConfig() zap.Config
NewZapLoggerConfig returns a new default logger config.
func RegisterEventLogger ¶ added in v0.59.0
func RegisterEventLogger(rootLogger Logger)
RegisterEventLogger does nothing on Unix. On Windows it will add an `Appender` for logging to windows event system.
func ReplaceGlobal ¶ added in v0.12.0
func ReplaceGlobal(logger Logger)
ReplaceGlobal replaces the global loggers.
func UnaryClientInterceptor ¶ added in v0.16.0
func UnaryClientInterceptor(
ctx context.Context,
method string,
req, reply interface{},
cc *grpc.ClientConn,
invoker grpc.UnaryInvoker,
opts ...grpc.CallOption,
) error
UnaryClientInterceptor adds debug directives from the current context (if any) to the outgoing request's metadata.
func UnaryServerInterceptor ¶ added in v0.16.0
func UnaryServerInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error)
UnaryServerInterceptor checks the incoming RPC metadata for a distributed tracing directive and attaches any information to a debug context.
func ZapcoreFieldsToJSON ¶ added in v0.59.0
func ZapcoreFieldsToJSON(fields []zapcore.Field) (string, error)
ZapcoreFieldsToJSON will serialize the Field objects into a JSON map of key/value pairs. It's unclear what circumstances will result in an error being returned.
Types ¶
type Appender ¶ added in v0.13.0
type Appender interface {
// Write submits a structured log entry to the appender for logging.
Write(zapcore.Entry, []zapcore.Field) error
// Sync is for signaling that any buffered logs to `Write` should be flushed. E.g: at shutdown.
Sync() error
}
Appender is an output for log entries. This is a subset of the `zapcore.Core` interface.
func NewFileAppender ¶ added in v0.59.0
func NewFileAppender(filename string) (Appender, io.Closer)
NewFileAppender will create an Appender that writes output to a log file. Log rotation will be enabled such that restarts of the viam-server with the same filename will move the old file out of the way. The `io.Closer` can be used to eventually close the opened log file.
func NewTestAppender ¶ added in v0.20.0
func NewTestAppender(tb testing.TB) Appender
NewTestAppender returns a logger appender that logs to the underlying `testing.TB` object. Writing logs with `tb.Log` does two things:
- Prepends the log with the filename/line number that called the `tb.Log` method. This is not useful to us.
- Correctly associates the log line with a Golang "Test*" function.
Additionally, this test appender will log in the local/machine timezone.
For tests that run in series (i.e: do not call `t.Parallel()`), writing to stdout (i.e: `fmt.Print`) this does not matter. Go's best effort detection works fine. But for tests running in parallel, the best-effort algorithm can map log lines to the wrong test. This is most noticeable when json logging is enabled. Where each log line has its test name, e.g:
{"Time":"2024-01-23T09:26:57.843619918-05:00","Action":"output","Package":"go.viam.com/rdk/robot","Test":"TestSessions/window_size=2s","Output":"local_robot.go:760: 2024-01-23T09:26:57.843-0500\tDEBUG\t\timpl/local_robot.go:760\thandlingweak update for..."}
A note about the filename/line that Go prepends to these test logs. Go normally finds this by walking up a couple stack frames to discover where a call to `t.Log` came from. However, it's not our desire for that to refer to the `tapp.tb.Log` call from the `testAppender.Write` method below. Go exposes a `tb.Helper()` method for this. All functions that call `tb.Helper` will add their stack frame to a filter. Go will walk up and report the first filename/line number from the first method that does not exempt itself.
Notably, zap's testing logger has a bug in this regard. Due to forgetting a `tb.Helper` call, test logs through their library always include `logger.go:130` instead of the actual log line.
type AtomicLevel ¶ added in v0.13.0
type AtomicLevel struct {
// contains filtered or unexported fields
}
AtomicLevel is a level that can be concurrently accessed.
func NewAtomicLevelAt ¶ added in v0.13.0
func NewAtomicLevelAt(initLevel Level) AtomicLevel
NewAtomicLevelAt creates a new AtomicLevel at the input `initLevel`.
type CloudConfig ¶ added in v0.13.0
type CloudConfig struct {
AppAddress string
ID string
Secret string
}
CloudConfig contains the necessary inputs to send logs to the app backend over grpc.
type ConsoleAppender ¶ added in v0.13.0
type ConsoleAppender struct {
io.Writer
}
ConsoleAppender will create human readable lines from log events and write them to the desired output sync. E.g: stdout or a file.
func NewStdoutAppender ¶ added in v0.13.0
func NewStdoutAppender() ConsoleAppender
NewStdoutAppender creates a new appender that prints to stdout.
func NewWriterAppender ¶ added in v0.13.0
func NewWriterAppender(writer io.Writer) ConsoleAppender
NewWriterAppender creates a new appender that prints to the input writer.
type Level ¶
type Level int
Level is an enum of log levels. Its value can be `DEBUG`, `INFO`, `WARN` or `ERROR`.
const (
// DEBUG log level.
DEBUG Level = iota - 1
// INFO log level.
INFO
// WARN log level.
WARN
// ERROR log level.
ERROR
)
func LevelFromString ¶
func LevelFromString(inp string) (Level, error)
LevelFromString parses an input string to a log level. The string must be one of `debug`, `info`, `warn`, `warning`, or `error`. The parsing is case-insensitive. An error is returned if the input does not match one of labeled cases.
func (Level) AsZap ¶ added in v0.13.0
func (level Level) AsZap() zapcore.Level
AsZap converts the Level to a `zapcore.Level`.
func (Level) MarshalJSON ¶
func (level Level) MarshalJSON() ([]byte, error)
MarshalJSON converts a log level to a json string.
func (*Level) UnmarshalJSON ¶
func (level *Level) UnmarshalJSON(data []byte) (err error)
UnmarshalJSON converts a json string to a log level.
type LogEntry ¶ added in v0.13.0
type LogEntry struct {
zapcore.Entry
// Fields are the key-value fields of the entry.
Fields []zapcore.Field
}
LogEntry embeds a zapcore Entry and slice of Fields.
func (*LogEntry) HashKey ¶ added in v0.58.0
func (le *LogEntry) HashKey() string
HashKey creates a hash key string for a `LogEntry`. Should be used to emplace a log entry in `recentMessageEntries`, i.e. `LogEntry`s that `HashKey` identically should be treated as identical with respect to noisiness and deduplication.
type Logger ¶ added in v0.12.0
type Logger interface {
ZapCompatibleLogger
SetLevel(level Level)
GetLevel() Level
Sublogger(subname string) Logger
NeverDeduplicate()
AddAppender(appender Appender)
AsZap() *zap.SugaredLogger
// Unconditionally logs a LogEntry object. Specifically any configured log level is ignored.
Write(*LogEntry)
WithFields(args ...interface{}) Logger
CDebug(ctx context.Context, args ...interface{})
CDebugf(ctx context.Context, template string, args ...interface{})
CDebugw(ctx context.Context, msg string, keysAndValues ...interface{})
CInfo(ctx context.Context, args ...interface{})
CInfof(ctx context.Context, template string, args ...interface{})
CInfow(ctx context.Context, msg string, keysAndValues ...interface{})
CWarn(ctx context.Context, args ...interface{})
CWarnf(ctx context.Context, template string, args ...interface{})
CWarnw(ctx context.Context, msg string, keysAndValues ...interface{})
CError(ctx context.Context, args ...interface{})
CErrorf(ctx context.Context, template string, args ...interface{})
CErrorw(ctx context.Context, msg string, keysAndValues ...interface{})
}
Logger interface for logging to.
func FromZapCompatible ¶ added in v0.12.0
func FromZapCompatible(logger ZapCompatibleLogger) Logger
FromZapCompatible upconverts a ZapCompatibleLogger to a logging.Logger. If the argument already satisfies logging.Logger, no changes will be made. A nil input returns a nil logger. An input of unknown type will create a new logger that's not associated with the input.
func NewBlankLogger ¶ added in v0.13.0
func NewBlankLogger(name string) Logger
NewBlankLogger returns a new logger that outputs Debug+ logs in UTC, but without any pre-existing appenders/outputs.
func NewDebugLogger ¶ added in v0.12.0
func NewDebugLogger(name string) Logger
NewDebugLogger returns a new logger that outputs Debug+ logs to stdout in UTC.
func NewLogger ¶ added in v0.12.0
func NewLogger(name string) Logger
NewLogger returns a new logger that outputs Info+ logs to stdout in UTC.
func NewObservedTestLogger ¶ added in v0.12.0
func NewObservedTestLogger(tb testing.TB) (Logger, *observer.ObservedLogs)
NewObservedTestLogger is like NewTestLogger but also saves logs to an in memory observer.
func NewTestLogger ¶ added in v0.12.0
func NewTestLogger(tb testing.TB) Logger
NewTestLogger returns a new logger that outputs Debug+ logs to stdout in local time.
type LoggerPatternConfig ¶ added in v0.34.0
type LoggerPatternConfig struct {
Pattern string `json:"pattern"`
Level string `json:"level"`
}
LoggerPatternConfig is an instance of a level specification for a given logger.
type MemLogger ¶ added in v0.30.0
type MemLogger struct {
Logger
Observer *observer.ObservedLogs
// contains filtered or unexported fields
}
MemLogger stores test logs in memory. And can write them on request with `OutputLogs`.
func NewInMemoryLogger ¶ added in v0.30.0
func NewInMemoryLogger(tb testing.TB) *MemLogger
NewInMemoryLogger creates a MemLogger that buffers test logs and only outputs them if requested or if the test fails. This is handy if a test is noisy, but the output is useful when the test fails.
func (*MemLogger) OutputLogs ¶ added in v0.30.0
func (memLogger *MemLogger) OutputLogs()
OutputLogs writes in-memory logs to the test object MemLogger was constructed with.
type NetAppender ¶ added in v0.13.0
type NetAppender struct {
// contains filtered or unexported fields
}
NetAppender can send log events to the app backend.
func NewNetAppender ¶ added in v0.13.0
func NewNetAppender(
config *CloudConfig,
conn rpc.ClientConn,
sharedConn bool,
loggerWithoutNet Logger,
) (*NetAppender, error)
NewNetAppender creates a NetAppender to send log events to the app backend. NetAppenders ought to be `Close`d prior to shutdown to flush remaining logs. Pass `nil` for `conn` if you want this to create its own connection.
func (*NetAppender) Check ¶ added in v0.13.0
func (nl *NetAppender) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry
Check checks if the entry should be logged. If so, add it to the CheckedEntry list of cores.
func (*NetAppender) Close ¶ added in v0.13.0
func (nl *NetAppender) Close()
Close the NetAppender. This makes a best effort at sending all logs before returning.
func (*NetAppender) Enabled ¶ added in v0.13.0
func (nl *NetAppender) Enabled(level zapcore.Level) bool
Enabled returns if the NetAppender serving as a `zapcore.Core` should log.
func (*NetAppender) SetConn ¶ added in v0.31.0
func (nl *NetAppender) SetConn(conn rpc.ClientConn, sharedConn bool)
SetConn sets the GRPC connection used by the NetAppender. sharedConn should be true in all external calls to this. If sharedConn=false, the NetAppender will close the connection in Close(). conn may be nil.
func (*NetAppender) Sync ¶ added in v0.13.0
func (nl *NetAppender) Sync() error
Sync is a no-op. sync is not exposed as multiple calls at the same time will cause double logs and panics.
type Registry ¶ added in v0.43.0
type Registry struct {
// DeduplicateLogs controls whether to deduplicate logs. Slightly odd to store this on
// the registry but preferable to having a global atomic.
DeduplicateLogs atomic.Bool
// contains filtered or unexported fields
}
Registry is a registry of loggers. It is stored on a logger, and holds a map of known subloggers (`loggers`) and a slice of configuration objects (`logConfig`).
func (*Registry) AddAppenderToAll ¶ added in v0.47.0
func (lr *Registry) AddAppenderToAll(appender Appender)
AddAppenderToAll adds the specified appender to all loggers in the registry.
func (*Registry) GetCurrentConfig ¶ added in v0.43.0
func (lr *Registry) GetCurrentConfig() []LoggerPatternConfig
GetCurrentConfig gets the current config.
type ZapCompatibleLogger ¶ added in v0.12.0
type ZapCompatibleLogger interface {
Desugar() *zap.Logger
Level() zapcore.Level
Named(name string) *zap.SugaredLogger
Sync() error
WithOptions(opts ...zap.Option) *zap.SugaredLogger
Debug(args ...interface{})
Debugf(template string, args ...interface{})
Debugw(msg string, keysAndValues ...interface{})
Info(args ...interface{})
Infof(template string, args ...interface{})
Infow(msg string, keysAndValues ...interface{})
Warn(args ...interface{})
Warnf(template string, args ...interface{})
Warnw(msg string, keysAndValues ...interface{})
Error(args ...interface{})
Errorf(template string, args ...interface{})
Errorw(msg string, keysAndValues ...interface{})
Fatal(args ...interface{})
Fatalf(template string, args ...interface{})
Fatalw(msg string, keysAndValues ...interface{})
}
ZapCompatibleLogger is a backwards compatibility layer for existing usages of the RDK as a library for Go application code or modules. Public (to the library) methods that take a logger as input should accept this type and upconvert to a Logger via a call to `FromZapCompatible`.