mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2025-12-23 14:25:50 +00:00
92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
// Copyright 2020-2024 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
|
|
// there is no "cli" case because it is not a supported option via our config
|
|
default:
|
|
return errInvalidLogFormat
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const (
|
|
FormatJSON LogFormat = "json"
|
|
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 or 'json'")
|
|
)
|
|
|
|
var _ json.Unmarshaler = func() *LogFormat {
|
|
var f LogFormat
|
|
return &f
|
|
}()
|
|
|
|
type LogSpec struct {
|
|
Level LogLevel `json:"level,omitempty"`
|
|
Format LogFormat `json:"format,omitempty"`
|
|
}
|
|
|
|
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"
|
|
default:
|
|
return errInvalidLogFormat
|
|
}
|
|
|
|
log, flush, err := newLogr(ctx, encoding, klogLevel)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
setGlobalLoggers(log, flush)
|
|
|
|
if spec.Format == FormatCLI {
|
|
return nil // do not spawn go routines on the CLI to allow the CLI to call this more than once
|
|
}
|
|
|
|
// 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
|
|
}
|