c6c2c525a6
Also fix some tests that were broken by bumping golang and dependencies in the previous commits. Note that in addition to changes made to satisfy the linter which do not impact the behavior of the code, this commit also adds ReadHeaderTimeout to all usages of http.Server to satisfy the linter (and because it seemed like a good suggestion).
108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package plog
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go.uber.org/zap/zapcore"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
"k8s.io/component-base/logs"
|
|
|
|
"go.pinniped.dev/internal/constable"
|
|
)
|
|
|
|
type LogFormat string
|
|
|
|
func (l *LogFormat) UnmarshalJSON(b []byte) error {
|
|
switch string(b) {
|
|
case `""`, `"json"`:
|
|
*l = FormatJSON
|
|
case `"text"`:
|
|
*l = FormatText
|
|
// there is no "cli" case because it is not a supported option via our config
|
|
default:
|
|
return errInvalidLogFormat
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const (
|
|
FormatJSON LogFormat = "json"
|
|
FormatText LogFormat = "text"
|
|
FormatCLI LogFormat = "cli" // only used by the pinniped CLI and not the server components
|
|
|
|
errInvalidLogLevel = constable.Error("invalid log level, valid choices are the empty string, info, debug, trace and all")
|
|
errInvalidLogFormat = constable.Error("invalid log format, valid choices are the empty string, json and text")
|
|
)
|
|
|
|
var _ json.Unmarshaler = func() *LogFormat {
|
|
var f LogFormat
|
|
return &f
|
|
}()
|
|
|
|
type LogSpec struct {
|
|
Level LogLevel `json:"level,omitempty"`
|
|
Format LogFormat `json:"format,omitempty"`
|
|
}
|
|
|
|
func MaybeSetDeprecatedLogLevel(level *LogLevel, log *LogSpec) {
|
|
if level != nil {
|
|
Warning("logLevel is deprecated, set log.level instead")
|
|
log.Level = *level
|
|
}
|
|
}
|
|
|
|
func ValidateAndSetLogLevelAndFormatGlobally(ctx context.Context, spec LogSpec) error {
|
|
klogLevel := klogLevelForPlogLevel(spec.Level)
|
|
if klogLevel < 0 {
|
|
return errInvalidLogLevel
|
|
}
|
|
|
|
// set the global log levels used by our code and the kube code underneath us
|
|
if _, err := logs.GlogSetter(strconv.Itoa(int(klogLevel))); err != nil {
|
|
panic(err) // programmer error
|
|
}
|
|
globalLevel.SetLevel(zapcore.Level(-klogLevel)) // klog levels are inverted when zap handles them
|
|
|
|
var encoding string
|
|
switch spec.Format {
|
|
case "", FormatJSON:
|
|
encoding = "json"
|
|
case FormatCLI:
|
|
encoding = "console"
|
|
case FormatText:
|
|
encoding = "text"
|
|
default:
|
|
return errInvalidLogFormat
|
|
}
|
|
|
|
log, flush, err := newLogr(ctx, encoding, klogLevel)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
setGlobalLoggers(log, flush)
|
|
|
|
//nolint:exhaustive // the switch above is exhaustive for format already
|
|
switch spec.Format {
|
|
case FormatCLI:
|
|
return nil // do not spawn go routines on the CLI to allow the CLI to call this more than once
|
|
case FormatText:
|
|
Warning("setting log.format to 'text' is deprecated - this option will be removed in a future release")
|
|
}
|
|
|
|
// do spawn go routines on the server
|
|
go wait.UntilWithContext(ctx, func(_ context.Context) { flush() }, time.Minute)
|
|
go func() {
|
|
<-ctx.Done()
|
|
flush() // best effort flush before shutdown as this is not coordinated with a wait group
|
|
}()
|
|
|
|
return nil
|
|
}
|