90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
|
package logging
|
||
|
|
||
|
import (
|
||
|
"github.com/hashicorp/go-hclog"
|
||
|
"google.golang.org/grpc/codes"
|
||
|
)
|
||
|
|
||
|
type options struct {
|
||
|
levelFunc CodeToLevel
|
||
|
}
|
||
|
|
||
|
var defaultOptions = &options{}
|
||
|
|
||
|
type Option func(*options)
|
||
|
|
||
|
func evaluateClientOpt(opts []Option) *options {
|
||
|
optCopy := &options{}
|
||
|
*optCopy = *defaultOptions
|
||
|
optCopy.levelFunc = DefaultCodeToLevel
|
||
|
for _, o := range opts {
|
||
|
o(optCopy)
|
||
|
}
|
||
|
return optCopy
|
||
|
}
|
||
|
|
||
|
func WithStatusCodeToLevelFunc(fn CodeToLevel) Option {
|
||
|
return func(opts *options) {
|
||
|
opts.levelFunc = fn
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// CodeToLevel function defines the mapping between gRPC return codes and hclog level.
|
||
|
type CodeToLevel func(code codes.Code) hclog.Level
|
||
|
|
||
|
func DefaultCodeToLevel(code codes.Code) hclog.Level {
|
||
|
switch code {
|
||
|
// Trace Logs -- Useful for Nomad developers but not necessarily always wanted
|
||
|
case codes.OK:
|
||
|
return hclog.Trace
|
||
|
|
||
|
// Debug logs
|
||
|
case codes.Canceled:
|
||
|
return hclog.Debug
|
||
|
case codes.InvalidArgument:
|
||
|
return hclog.Debug
|
||
|
case codes.ResourceExhausted:
|
||
|
return hclog.Debug
|
||
|
case codes.FailedPrecondition:
|
||
|
return hclog.Debug
|
||
|
case codes.Aborted:
|
||
|
return hclog.Debug
|
||
|
case codes.OutOfRange:
|
||
|
return hclog.Debug
|
||
|
case codes.NotFound:
|
||
|
return hclog.Debug
|
||
|
case codes.AlreadyExists:
|
||
|
return hclog.Debug
|
||
|
|
||
|
// Info Logs - More curious/interesting than debug, but not necessarily critical
|
||
|
case codes.Unknown:
|
||
|
return hclog.Info
|
||
|
case codes.DeadlineExceeded:
|
||
|
return hclog.Info
|
||
|
case codes.PermissionDenied:
|
||
|
return hclog.Info
|
||
|
case codes.Unauthenticated:
|
||
|
// unauthenticated requests are probably usually fine?
|
||
|
return hclog.Info
|
||
|
case codes.Unavailable:
|
||
|
// unavailable errors indicate the upstream is not currently available. Info
|
||
|
// because I would guess these are usually transient and will be handled by
|
||
|
// retry mechanisms before being served as a higher level warning.
|
||
|
return hclog.Info
|
||
|
|
||
|
// Warn Logs - These are almost definitely bad in most cases - usually because
|
||
|
// the upstream is broken.
|
||
|
case codes.Unimplemented:
|
||
|
return hclog.Warn
|
||
|
case codes.Internal:
|
||
|
return hclog.Warn
|
||
|
case codes.DataLoss:
|
||
|
return hclog.Warn
|
||
|
|
||
|
default:
|
||
|
// Codes that aren't implemented as part of a CodeToLevel case are probably
|
||
|
// unknown and should be surfaced.
|
||
|
return hclog.Info
|
||
|
}
|
||
|
}
|