2018-06-29 08:41:18 +00:00
|
|
|
// Copyright (c) 2018 Intel Corporation
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package logging
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-10-22 21:38:13 +00:00
|
|
|
"io"
|
2018-06-29 08:41:18 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2020-06-16 01:35:15 +00:00
|
|
|
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
2018-06-29 08:41:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Level type
|
|
|
|
type Level uint32
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// PanicLevel...MaxLevel indicates the logging level
|
2018-06-29 08:41:18 +00:00
|
|
|
const (
|
|
|
|
PanicLevel Level = iota
|
|
|
|
ErrorLevel
|
2019-03-07 16:00:46 +00:00
|
|
|
VerboseLevel
|
2018-06-29 08:41:18 +00:00
|
|
|
DebugLevel
|
|
|
|
MaxLevel
|
|
|
|
UnknownLevel
|
|
|
|
)
|
|
|
|
|
|
|
|
var loggingStderr bool
|
2020-06-16 01:35:15 +00:00
|
|
|
var loggingW io.Writer
|
2018-06-29 08:41:18 +00:00
|
|
|
var loggingLevel Level
|
2022-04-11 15:22:48 +00:00
|
|
|
var logger *lumberjack.Logger
|
2018-08-06 06:55:30 +00:00
|
|
|
|
2018-06-29 08:41:18 +00:00
|
|
|
const defaultTimestampFormat = time.RFC3339
|
|
|
|
|
2022-04-11 15:22:48 +00:00
|
|
|
// LogOptions specifies the configuration of the log
|
|
|
|
type LogOptions struct {
|
|
|
|
MaxAge *int `json:"maxAge,omitempty"`
|
|
|
|
MaxSize *int `json:"maxSize,omitempty"`
|
|
|
|
MaxBackups *int `json:"maxBackups,omitempty"`
|
|
|
|
Compress *bool `json:"compress,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetLogOptions set the LoggingOptions of NetConf
|
|
|
|
func SetLogOptions(options *LogOptions) {
|
|
|
|
// give some default value
|
|
|
|
logger.MaxSize = 100
|
|
|
|
logger.MaxAge = 5
|
|
|
|
logger.MaxBackups = 5
|
|
|
|
logger.Compress = true
|
|
|
|
if options != nil {
|
|
|
|
if options.MaxAge != nil {
|
|
|
|
logger.MaxAge = *options.MaxAge
|
|
|
|
}
|
|
|
|
if options.MaxSize != nil {
|
|
|
|
logger.MaxSize = *options.MaxSize
|
|
|
|
}
|
|
|
|
if options.MaxBackups != nil {
|
|
|
|
logger.MaxBackups = *options.MaxBackups
|
|
|
|
}
|
|
|
|
if options.Compress != nil {
|
|
|
|
logger.Compress = *options.Compress
|
|
|
|
}
|
|
|
|
}
|
|
|
|
loggingW = logger
|
|
|
|
}
|
|
|
|
|
2018-06-29 08:41:18 +00:00
|
|
|
func (l Level) String() string {
|
|
|
|
switch l {
|
|
|
|
case PanicLevel:
|
|
|
|
return "panic"
|
2019-03-07 16:00:46 +00:00
|
|
|
case VerboseLevel:
|
|
|
|
return "verbose"
|
2018-06-29 08:41:18 +00:00
|
|
|
case ErrorLevel:
|
|
|
|
return "error"
|
|
|
|
case DebugLevel:
|
|
|
|
return "debug"
|
|
|
|
}
|
|
|
|
return "unknown"
|
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
func printf(level Level, format string, a ...interface{}) {
|
2018-06-29 08:41:18 +00:00
|
|
|
header := "%s [%s] "
|
|
|
|
t := time.Now()
|
|
|
|
if level > loggingLevel {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if loggingStderr {
|
|
|
|
fmt.Fprintf(os.Stderr, header, t.Format(defaultTimestampFormat), level)
|
|
|
|
fmt.Fprintf(os.Stderr, format, a...)
|
|
|
|
fmt.Fprintf(os.Stderr, "\n")
|
|
|
|
}
|
|
|
|
|
2020-06-16 01:35:15 +00:00
|
|
|
if loggingW != nil {
|
|
|
|
fmt.Fprintf(loggingW, header, t.Format(defaultTimestampFormat), level)
|
|
|
|
fmt.Fprintf(loggingW, format, a...)
|
|
|
|
fmt.Fprintf(loggingW, "\n")
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// Debugf prints logging if logging level >= debug
|
2018-06-29 08:41:18 +00:00
|
|
|
func Debugf(format string, a ...interface{}) {
|
2019-06-24 07:57:03 +00:00
|
|
|
printf(DebugLevel, format, a...)
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// Verbosef prints logging if logging level >= verbose
|
2019-03-07 16:00:46 +00:00
|
|
|
func Verbosef(format string, a ...interface{}) {
|
2019-06-24 07:57:03 +00:00
|
|
|
printf(VerboseLevel, format, a...)
|
2019-03-07 16:00:46 +00:00
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// Errorf prints logging if logging level >= error
|
2018-08-06 06:55:30 +00:00
|
|
|
func Errorf(format string, a ...interface{}) error {
|
2019-06-24 07:57:03 +00:00
|
|
|
printf(ErrorLevel, format, a...)
|
2018-08-06 06:55:30 +00:00
|
|
|
return fmt.Errorf(format, a...)
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|
|
|
|
|
2021-09-10 12:50:23 +00:00
|
|
|
// Panicf prints logging plus stack trace. This should be used only for unrecoverable error
|
2018-06-29 08:41:18 +00:00
|
|
|
func Panicf(format string, a ...interface{}) {
|
2019-06-24 07:57:03 +00:00
|
|
|
printf(PanicLevel, format, a...)
|
|
|
|
printf(PanicLevel, "========= Stack trace output ========")
|
|
|
|
printf(PanicLevel, "%+v", errors.New("Multus Panic"))
|
|
|
|
printf(PanicLevel, "========= Stack trace output end ========")
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// GetLoggingLevel gets current logging level
|
2019-03-07 16:00:46 +00:00
|
|
|
func GetLoggingLevel() Level {
|
|
|
|
return loggingLevel
|
|
|
|
}
|
|
|
|
|
|
|
|
func getLoggingLevel(levelStr string) Level {
|
2018-06-29 08:41:18 +00:00
|
|
|
switch strings.ToLower(levelStr) {
|
|
|
|
case "debug":
|
|
|
|
return DebugLevel
|
2019-03-07 16:00:46 +00:00
|
|
|
case "verbose":
|
|
|
|
return VerboseLevel
|
2018-06-29 08:41:18 +00:00
|
|
|
case "error":
|
|
|
|
return ErrorLevel
|
|
|
|
case "panic":
|
|
|
|
return PanicLevel
|
|
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "multus logging: cannot set logging level to %s\n", levelStr)
|
|
|
|
return UnknownLevel
|
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// SetLogLevel sets logging level
|
2018-08-06 06:55:30 +00:00
|
|
|
func SetLogLevel(levelStr string) {
|
2019-03-07 16:00:46 +00:00
|
|
|
level := getLoggingLevel(levelStr)
|
2018-06-29 08:41:18 +00:00
|
|
|
if level < MaxLevel {
|
|
|
|
loggingLevel = level
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// SetLogStderr sets flag for logging stderr output
|
2018-08-06 06:55:30 +00:00
|
|
|
func SetLogStderr(enable bool) {
|
2018-06-29 08:41:18 +00:00
|
|
|
loggingStderr = enable
|
|
|
|
}
|
|
|
|
|
2019-06-24 07:57:03 +00:00
|
|
|
// SetLogFile sets logging file
|
2018-08-06 06:55:30 +00:00
|
|
|
func SetLogFile(filename string) {
|
2018-06-29 08:41:18 +00:00
|
|
|
if filename == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-04-11 15:22:48 +00:00
|
|
|
logger.Filename = filename
|
|
|
|
loggingW = logger
|
2020-06-16 01:35:15 +00:00
|
|
|
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2018-07-12 03:15:53 +00:00
|
|
|
loggingStderr = true
|
2020-06-16 01:35:15 +00:00
|
|
|
loggingW = nil
|
2018-06-29 08:41:18 +00:00
|
|
|
loggingLevel = PanicLevel
|
2022-04-11 15:22:48 +00:00
|
|
|
logger = &lumberjack.Logger{}
|
2018-06-29 08:41:18 +00:00
|
|
|
}
|