mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
add named logger + color formatting
This commit is contained in:
parent
09c7ca8f8f
commit
ae6feed8fc
@ -42,5 +42,5 @@ func setCliOptions() {
|
|||||||
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
|
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rootCmd.Flags().CountVarP(&cliOpts.Verbosity, "verbose", "v", "increase verbosity (-v, -vv, -vvv ...)")
|
rootCmd.Flags().CountVarP(&cliOpts.Verbosity, "verbose", "v", "increase verbosity (-v = info, -vv = debug)")
|
||||||
}
|
}
|
||||||
|
|||||||
12
cmd/init.go
12
cmd/init.go
@ -1,15 +1,16 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom"
|
"github.com/anchore/imgbom/imgbom"
|
||||||
"github.com/anchore/imgbom/internal/config"
|
"github.com/anchore/imgbom/internal/config"
|
||||||
|
"github.com/anchore/imgbom/internal/format"
|
||||||
"github.com/anchore/imgbom/internal/log"
|
"github.com/anchore/imgbom/internal/log"
|
||||||
"github.com/anchore/imgbom/internal/logger"
|
"github.com/anchore/imgbom/internal/logger"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var appConfig *config.Application
|
var appConfig *config.Application
|
||||||
@ -25,10 +26,10 @@ func initAppConfig() {
|
|||||||
|
|
||||||
func initLogging() {
|
func initLogging() {
|
||||||
config := logger.LogConfig{
|
config := logger.LogConfig{
|
||||||
EnableConsole: appConfig.Log.FileLocation == "" && !appConfig.Quiet,
|
EnableConsole: (appConfig.Log.FileLocation == "" || appConfig.CliOptions.Verbosity > 0) && !appConfig.Quiet,
|
||||||
EnableFile: appConfig.Log.FileLocation != "",
|
EnableFile: appConfig.Log.FileLocation != "",
|
||||||
Level: appConfig.Log.LevelOpt,
|
Level: appConfig.Log.LevelOpt,
|
||||||
FormatAsJSON: appConfig.Log.FormatAsJSON,
|
Structured: appConfig.Log.Structured,
|
||||||
FileLocation: appConfig.Log.FileLocation,
|
FileLocation: appConfig.Log.FileLocation,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,10 +37,11 @@ func initLogging() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func logAppConfig() {
|
func logAppConfig() {
|
||||||
appCfgStr, err := json.MarshalIndent(&appConfig, " ", " ")
|
appCfgStr, err := yaml.Marshal(&appConfig)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Could not display application config: %+v", err)
|
log.Debugf("Could not display application config: %+v", err)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Application config:\n%+v", string(appCfgStr))
|
log.Debugf("Application config:\n%+v", format.Magenta.Format(string(appCfgStr)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
go.mod
1
go.mod
@ -14,4 +14,5 @@ require (
|
|||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
github.com/spf13/viper v1.7.0
|
github.com/spf13/viper v1.7.0
|
||||||
go.uber.org/zap v1.15.0
|
go.uber.org/zap v1.15.0
|
||||||
|
gopkg.in/yaml.v2 v2.2.8
|
||||||
)
|
)
|
||||||
|
|||||||
3
go.sum
3
go.sum
@ -131,6 +131,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
|
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
@ -280,8 +281,10 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
|
|||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||||
|
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
|||||||
@ -95,7 +95,6 @@ func (pres *Presenter) Present(output io.Writer, img *stereoscopeImg.Image, cata
|
|||||||
"id": src.ID(),
|
"id": src.ID(),
|
||||||
"presenter": "json",
|
"presenter": "json",
|
||||||
}).Errorf("could not get metadata from catalog")
|
}).Errorf("could not get metadata from catalog")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srcObj := source{
|
srcObj := source{
|
||||||
|
|||||||
@ -20,9 +20,9 @@ type CliOnlyOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Application struct {
|
type Application struct {
|
||||||
configPath string
|
ConfigPath string
|
||||||
PresenterOpt presenter.Option
|
PresenterOpt presenter.Option
|
||||||
Presenter string `mapstructure:"output"`
|
Output string `mapstructure:"output"`
|
||||||
ScopeOpt scope.Option
|
ScopeOpt scope.Option
|
||||||
Scope string `mapstructure:"scope"`
|
Scope string `mapstructure:"scope"`
|
||||||
Quiet bool `mapstructure:"quiet"`
|
Quiet bool `mapstructure:"quiet"`
|
||||||
@ -31,7 +31,7 @@ type Application struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Logging struct {
|
type Logging struct {
|
||||||
FormatAsJSON bool `mapstructure:"structured"`
|
Structured bool `mapstructure:"structured"`
|
||||||
LevelOpt zapcore.Level
|
LevelOpt zapcore.Level
|
||||||
Level string `mapstructure:"level"`
|
Level string `mapstructure:"level"`
|
||||||
FileLocation string `mapstructure:"file"`
|
FileLocation string `mapstructure:"file"`
|
||||||
@ -59,7 +59,7 @@ func LoadConfigFromFile(v *viper.Viper, cliOpts *CliOnlyOptions) (*Application,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to parse config: %w", err)
|
return nil, fmt.Errorf("unable to parse config: %w", err)
|
||||||
}
|
}
|
||||||
config.configPath = v.ConfigFileUsed()
|
config.ConfigPath = v.ConfigFileUsed()
|
||||||
|
|
||||||
err = config.Build()
|
err = config.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,9 +71,9 @@ func LoadConfigFromFile(v *viper.Viper, cliOpts *CliOnlyOptions) (*Application,
|
|||||||
|
|
||||||
func (cfg *Application) Build() error {
|
func (cfg *Application) Build() error {
|
||||||
// set the presenter
|
// set the presenter
|
||||||
presenterOption := presenter.ParseOption(cfg.Presenter)
|
presenterOption := presenter.ParseOption(cfg.Output)
|
||||||
if presenterOption == presenter.UnknownPresenter {
|
if presenterOption == presenter.UnknownPresenter {
|
||||||
return fmt.Errorf("bad --output value '%s'", cfg.Presenter)
|
return fmt.Errorf("bad --output value '%s'", cfg.Output)
|
||||||
}
|
}
|
||||||
cfg.PresenterOpt = presenterOption
|
cfg.PresenterOpt = presenterOption
|
||||||
|
|
||||||
@ -100,10 +100,10 @@ func (cfg *Application) Build() error {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// set the log level implicitly
|
// set the log level implicitly
|
||||||
switch cfg.CliOptions.Verbosity {
|
switch v := cfg.CliOptions.Verbosity; {
|
||||||
case 1:
|
case v == 1:
|
||||||
cfg.Log.LevelOpt = zapcore.InfoLevel
|
cfg.Log.LevelOpt = zapcore.InfoLevel
|
||||||
case 2:
|
case v >= 2:
|
||||||
cfg.Log.LevelOpt = zapcore.DebugLevel
|
cfg.Log.LevelOpt = zapcore.DebugLevel
|
||||||
default:
|
default:
|
||||||
cfg.Log.LevelOpt = zapcore.ErrorLevel
|
cfg.Log.LevelOpt = zapcore.ErrorLevel
|
||||||
@ -133,14 +133,21 @@ func readConfig(v *viper.Viper, configPath string) error {
|
|||||||
|
|
||||||
// start searching for valid configs in order...
|
// start searching for valid configs in order...
|
||||||
|
|
||||||
// 1. look for .<appname>/config.yaml (in the current directory)
|
// 1. look for .<appname>.yaml (in the current directory)
|
||||||
|
v.AddConfigPath(".")
|
||||||
|
v.SetConfigName(internal.ApplicationName)
|
||||||
|
if err := v.ReadInConfig(); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. look for .<appname>/config.yaml (in the current directory)
|
||||||
v.AddConfigPath("." + internal.ApplicationName)
|
v.AddConfigPath("." + internal.ApplicationName)
|
||||||
v.SetConfigName("config")
|
v.SetConfigName("config")
|
||||||
if err := v.ReadInConfig(); err == nil {
|
if err := v.ReadInConfig(); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. look for ~/.<appname>.yaml
|
// 3. look for ~/.<appname>.yaml
|
||||||
home, err := homedir.Dir()
|
home, err := homedir.Dir()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
v.AddConfigPath(home)
|
v.AddConfigPath(home)
|
||||||
@ -150,7 +157,7 @@ func readConfig(v *viper.Viper, configPath string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. look for <appname>/config.yaml in xdg locations (starting with xdg home config dir, then moving upwards)
|
// 4. look for <appname>/config.yaml in xdg locations (starting with xdg home config dir, then moving upwards)
|
||||||
v.AddConfigPath(path.Join(xdg.ConfigHome, internal.ApplicationName))
|
v.AddConfigPath(path.Join(xdg.ConfigHome, internal.ApplicationName))
|
||||||
for _, dir := range xdg.ConfigDirs {
|
for _, dir := range xdg.ConfigDirs {
|
||||||
v.AddConfigPath(path.Join(dir, internal.ApplicationName))
|
v.AddConfigPath(path.Join(dir, internal.ApplicationName))
|
||||||
|
|||||||
21
internal/format/color.go
Normal file
21
internal/format/color.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package format
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultColor Color = iota + 30
|
||||||
|
Red
|
||||||
|
Green
|
||||||
|
Yellow
|
||||||
|
Blue
|
||||||
|
Magenta
|
||||||
|
Cyan
|
||||||
|
White
|
||||||
|
)
|
||||||
|
|
||||||
|
type Color uint8
|
||||||
|
|
||||||
|
// TODO: not cross platform (windows...)
|
||||||
|
func (c Color) Format(s string) string {
|
||||||
|
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", c, s)
|
||||||
|
}
|
||||||
@ -4,14 +4,25 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/anchore/imgbom/imgbom/logger"
|
"github.com/anchore/imgbom/imgbom/logger"
|
||||||
|
"github.com/anchore/imgbom/internal/format"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var levelToColor = map[zapcore.Level]format.Color{
|
||||||
|
zapcore.DebugLevel: format.Magenta,
|
||||||
|
zapcore.InfoLevel: format.Blue,
|
||||||
|
zapcore.WarnLevel: format.Yellow,
|
||||||
|
zapcore.ErrorLevel: format.Red,
|
||||||
|
zapcore.DPanicLevel: format.Red,
|
||||||
|
zapcore.PanicLevel: format.Red,
|
||||||
|
zapcore.FatalLevel: format.Red,
|
||||||
|
}
|
||||||
|
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
EnableConsole bool
|
EnableConsole bool
|
||||||
EnableFile bool
|
EnableFile bool
|
||||||
FormatAsJSON bool
|
Structured bool
|
||||||
Level zapcore.Level
|
Level zapcore.Level
|
||||||
FileLocation string
|
FileLocation string
|
||||||
}
|
}
|
||||||
@ -20,6 +31,12 @@ type ZapLogger struct {
|
|||||||
sugaredLogger *zap.SugaredLogger
|
sugaredLogger *zap.SugaredLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Consider a human readable text encoder for better field handeling:
|
||||||
|
// - https://github.com/uber-go/zap/issues/570
|
||||||
|
// - https://github.com/uber-go/zap/pull/123
|
||||||
|
// - TextEncoder w/ old interface: https://github.com/uber-go/zap/blob/6c2107996402d47d559199b78e1c44747fe732f9/text_encoder.go
|
||||||
|
// - New interface example: https://github.com/uber-go/zap/blob/c2633d6de2d6e1170ad8f150660e3cf5310067c8/zapcore/json_encoder.go
|
||||||
|
// - Register the encoder: https://github.com/uber-go/zap/blob/v1.15.0/encoder.go
|
||||||
func NewZapLogger(config LogConfig) *ZapLogger {
|
func NewZapLogger(config LogConfig) *ZapLogger {
|
||||||
cores := []zapcore.Core{}
|
cores := []zapcore.Core{}
|
||||||
|
|
||||||
@ -31,8 +48,8 @@ func NewZapLogger(config LogConfig) *ZapLogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.EnableFile {
|
if config.EnableFile {
|
||||||
writer := zapcore.AddSync(getLogWriter(config.FileLocation))
|
writer := zapcore.AddSync(logFileWriter(config.FileLocation))
|
||||||
core := zapcore.NewCore(getFileEncoder(config), writer, config.Level)
|
core := zapcore.NewCore(fileEncoder(config), writer, config.Level)
|
||||||
cores = append(cores, core)
|
cores = append(cores, core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,27 +67,53 @@ func NewZapLogger(config LogConfig) *ZapLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *ZapLogger) GetNamedLogger(name string) *ZapLogger {
|
||||||
|
return &ZapLogger{
|
||||||
|
sugaredLogger: l.sugaredLogger.Named(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getConsoleEncoder(config LogConfig) zapcore.Encoder {
|
func getConsoleEncoder(config LogConfig) zapcore.Encoder {
|
||||||
encoderConfig := zap.NewProductionEncoderConfig()
|
encoderConfig := zap.NewProductionEncoderConfig()
|
||||||
if config.FormatAsJSON {
|
if config.Structured {
|
||||||
|
encoderConfig.EncodeName = zapcore.FullNameEncoder
|
||||||
|
encoderConfig.EncodeCaller = zapcore.FullCallerEncoder
|
||||||
return zapcore.NewJSONEncoder(encoderConfig)
|
return zapcore.NewJSONEncoder(encoderConfig)
|
||||||
}
|
}
|
||||||
encoderConfig.EncodeTime = nil
|
encoderConfig.EncodeTime = nil
|
||||||
encoderConfig.EncodeCaller = nil
|
encoderConfig.EncodeCaller = nil
|
||||||
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
encoderConfig.EncodeLevel = consoleLevelEncoder
|
||||||
|
encoderConfig.EncodeName = nameEncoder
|
||||||
return zapcore.NewConsoleEncoder(encoderConfig)
|
return zapcore.NewConsoleEncoder(encoderConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileEncoder(config LogConfig) zapcore.Encoder {
|
func nameEncoder(loggerName string, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
enc.AppendString("[" + loggerName + "]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func consoleLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
|
||||||
|
if level != zapcore.InfoLevel {
|
||||||
|
color, ok := levelToColor[level]
|
||||||
|
if !ok {
|
||||||
|
enc.AppendString("[" + level.CapitalString() + "]")
|
||||||
|
} else {
|
||||||
|
enc.AppendString("[" + color.Format(level.CapitalString()) + "]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileEncoder(config LogConfig) zapcore.Encoder {
|
||||||
encoderConfig := zap.NewProductionEncoderConfig()
|
encoderConfig := zap.NewProductionEncoderConfig()
|
||||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||||
if config.FormatAsJSON {
|
encoderConfig.EncodeName = zapcore.FullNameEncoder
|
||||||
|
encoderConfig.EncodeCaller = zapcore.FullCallerEncoder
|
||||||
|
if config.Structured {
|
||||||
return zapcore.NewJSONEncoder(encoderConfig)
|
return zapcore.NewJSONEncoder(encoderConfig)
|
||||||
}
|
}
|
||||||
return zapcore.NewConsoleEncoder(encoderConfig)
|
return zapcore.NewConsoleEncoder(encoderConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLogWriter(location string) zapcore.WriteSyncer {
|
func logFileWriter(location string) zapcore.WriteSyncer {
|
||||||
file, _ := os.Create(location)
|
file, _ := os.Create(location)
|
||||||
return zapcore.AddSync(file)
|
return zapcore.AddSync(file)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user