mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-09 06:31:25 +02:00
Hook into logging machinery. Signed-off-by: Alexey Palazhchenko <alexey.palazhchenko@talos-systems.com>
142 lines
3.2 KiB
Go
142 lines
3.2 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package logging
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"strings"
|
|
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// LogWriter is a wrapper around zap.Logger that implements io.Writer interface.
|
|
type LogWriter struct {
|
|
dest *zap.Logger
|
|
level zapcore.Level
|
|
}
|
|
|
|
// NewWriter creates new log zap log writer.
|
|
func NewWriter(l *zap.Logger, level zapcore.Level) io.Writer {
|
|
return &LogWriter{
|
|
dest: l,
|
|
level: level,
|
|
}
|
|
}
|
|
|
|
// Write implements io.Writer interface.
|
|
func (lw *LogWriter) Write(line []byte) (int, error) {
|
|
checked := lw.dest.Check(lw.level, strings.TrimSpace(string(line)))
|
|
if checked == nil {
|
|
return 0, nil
|
|
}
|
|
|
|
checked.Write()
|
|
|
|
return len(line), nil
|
|
}
|
|
|
|
// logWrapper wraps around standard logger.
|
|
type logWrapper struct {
|
|
log *log.Logger
|
|
}
|
|
|
|
// Write implements io.Writer interface.
|
|
func (lw *logWrapper) Write(line []byte) (int, error) {
|
|
if lw.log == nil {
|
|
log.Print(string(line))
|
|
} else {
|
|
lw.log.Print(string(line))
|
|
}
|
|
|
|
return len(line), nil
|
|
}
|
|
|
|
// StdWriter creates a sync writer that writes all logs to the std logger.
|
|
var StdWriter = &logWrapper{nil}
|
|
|
|
// LogDestination defines logging destination Config.
|
|
type LogDestination struct {
|
|
// Level log level.
|
|
level zapcore.LevelEnabler
|
|
writer io.Writer
|
|
config zapcore.EncoderConfig
|
|
}
|
|
|
|
// EncoderOption defines a log destination encoder config setter.
|
|
type EncoderOption func(config *zapcore.EncoderConfig)
|
|
|
|
// WithoutTimestamp disables timestamp.
|
|
func WithoutTimestamp() EncoderOption {
|
|
return func(config *zapcore.EncoderConfig) {
|
|
config.EncodeTime = nil
|
|
}
|
|
}
|
|
|
|
// WithoutLogLevels disable log level.
|
|
func WithoutLogLevels() EncoderOption {
|
|
return func(config *zapcore.EncoderConfig) {
|
|
config.EncodeLevel = nil
|
|
}
|
|
}
|
|
|
|
// WithColoredLevels enables log level colored output.
|
|
func WithColoredLevels() EncoderOption {
|
|
return func(config *zapcore.EncoderConfig) {
|
|
config.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
|
}
|
|
}
|
|
|
|
// NewLogDestination creates new log destination.
|
|
func NewLogDestination(writer io.Writer, logLevel zapcore.LevelEnabler, options ...EncoderOption) *LogDestination {
|
|
config := zap.NewDevelopmentEncoderConfig()
|
|
config.ConsoleSeparator = " "
|
|
config.StacktraceKey = "error"
|
|
|
|
for _, option := range options {
|
|
option(&config)
|
|
}
|
|
|
|
return &LogDestination{
|
|
level: logLevel,
|
|
config: config,
|
|
writer: writer,
|
|
}
|
|
}
|
|
|
|
// Wrap is a simple helper to wrap io.Writer with default arguments.
|
|
func Wrap(writer io.Writer) *zap.Logger {
|
|
return ZapLogger(
|
|
NewLogDestination(writer, zapcore.DebugLevel),
|
|
)
|
|
}
|
|
|
|
// ZapLogger creates new default Zap Logger.
|
|
func ZapLogger(dests ...*LogDestination) *zap.Logger {
|
|
if len(dests) == 0 {
|
|
panic("at least one writer must be defined")
|
|
}
|
|
|
|
cores := []zapcore.Core{}
|
|
|
|
for _, dest := range dests {
|
|
consoleEncoder := zapcore.NewConsoleEncoder(dest.config)
|
|
|
|
cores = append(cores, zapcore.NewCore(consoleEncoder, zapcore.AddSync(dest.writer), dest.level))
|
|
}
|
|
|
|
core := zapcore.NewTee(cores...)
|
|
|
|
logger := zap.New(core)
|
|
|
|
return logger
|
|
}
|
|
|
|
// Component helper for creating zap.Field.
|
|
func Component(name string) zapcore.Field {
|
|
return zap.String("component", name)
|
|
}
|