Skip to content

Commit

Permalink
JSON log output (#1027)
Browse files Browse the repository at this point in the history
* WIP JSON log output

* Dont need isatty directly

* Dont output banner/startup info as reg text if not running with console output

* Dont run tests with -v as zap will log tests that fail

* Simplify

* Add test

* Update cmd/flipt/main.go

Co-authored-by: George <me@georgemac.com>

* Update cmd/flipt/main.go

Co-authored-by: George <me@georgemac.com>

* starting -> available

Co-authored-by: George <me@georgemac.com>
  • Loading branch information
markphelps and GeorgeMac authored Sep 14, 2022
1 parent 4914fdf commit 5c7037e
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 21 deletions.
1 change: 0 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,4 @@ tasks:
vars:
COVERAGE_FILE: coverage.txt
TEST_PATTERN: .
TEST_FLAGS: -v
TEST_OPTS: -race
48 changes: 35 additions & 13 deletions cmd/flipt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ var (

cfgPath string
forceMigrate bool

version = devVersion
commit string
date string
Expand All @@ -94,7 +93,7 @@ func main() {
once sync.Once
loggerConfig = zap.Config{
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
Development: true,
Development: false,
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
// Keys can be anything except the empty string.
Expand Down Expand Up @@ -213,6 +212,13 @@ func main() {
if err != nil {
logger().Fatal("parsing log level", zap.String("level", cfg.Log.Level), zap.Error(err))
}

if cfg.Log.Encoding > config.LogEncodingConsole {
loggerConfig.Encoding = cfg.Log.Encoding.String()

// don't encode with colors if not using console log output
loggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
}
})

rootCmd.SetVersionTemplate(banner)
Expand All @@ -234,27 +240,30 @@ func main() {
}

func run(ctx context.Context, logger *zap.Logger) error {
color.Cyan(banner)
fmt.Println()

ctx, cancel := context.WithCancel(ctx)

defer cancel()

interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)

defer signal.Stop(interrupt)

shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer shutdownCancel()

var (
isRelease = isRelease()
isRelease = isRelease()
isConsole = cfg.Log.Encoding == config.LogEncodingConsole

updateAvailable bool
cv, lv semver.Version
)

if isConsole {
color.Cyan("%s\n", banner)
} else {
logger.Info("flipt starting", zap.String("version", version), zap.String("commit", commit), zap.String("date", date), zap.String("go_version", goVersion))
}

if isRelease {
var err error
cv, err = semver.ParseTolerant(version)
Expand Down Expand Up @@ -639,13 +648,26 @@ func run(ctx context.Context, logger *zap.Logger) error {

logger.Debug("starting http server")

color.Green("\nAPI: %s://%s:%d/api/v1", cfg.Server.Protocol, cfg.Server.Host, httpPort)
var (
apiAddr = fmt.Sprintf("%s://%s:%d/api/v1", cfg.Server.Protocol, cfg.Server.Host, httpPort)
uiAddr = fmt.Sprintf("%s://%s:%d", cfg.Server.Protocol, cfg.Server.Host, httpPort)
)

if cfg.UI.Enabled {
color.Green("UI: %s://%s:%d", cfg.Server.Protocol, cfg.Server.Host, httpPort)
}
if isConsole {
color.Green("\nAPI: %s", apiAddr)

if cfg.UI.Enabled {
color.Green("UI: %s", uiAddr)
}

fmt.Println()
} else {
logger.Info("api available", zap.String("address", apiAddr))

fmt.Println()
if cfg.UI.Enabled {
logger.Info("ui available", zap.String("address", uiAddr))
}
}

if cfg.Server.Protocol == config.HTTPS {
httpServer.TLSConfig = &tls.Config{
Expand Down
41 changes: 36 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,35 @@ type Config struct {
}

type LogConfig struct {
Level string `json:"level,omitempty"`
File string `json:"file,omitempty"`
Level string `json:"level,omitempty"`
File string `json:"file,omitempty"`
Encoding LogEncoding `json:"encoding,omitempty"`
}

type LogEncoding uint8

func (e LogEncoding) String() string {
return logEncodingToString[e]
}

const (
_ LogEncoding = iota
LogEncodingConsole
LogEncodingJSON
)

var (
logEncodingToString = map[LogEncoding]string{
LogEncodingConsole: "console",
LogEncodingJSON: "json",
}

stringToLogEncoding = map[string]LogEncoding{
"console": LogEncodingConsole,
"json": LogEncodingJSON,
}
)

type UIConfig struct {
Enabled bool `json:"enabled"`
}
Expand Down Expand Up @@ -189,7 +214,8 @@ var (
func Default() *Config {
return &Config{
Log: LogConfig{
Level: "INFO",
Level: "INFO",
Encoding: LogEncodingConsole,
},

UI: UIConfig{
Expand Down Expand Up @@ -248,8 +274,9 @@ func Default() *Config {

const (
// Logging
logLevel = "log.level"
logFile = "log.file"
logLevel = "log.level"
logFile = "log.file"
logEncoding = "log.encoding"

// UI
uiEnabled = "ui.enabled"
Expand Down Expand Up @@ -325,6 +352,10 @@ func Load(path string) (*Config, error) {
cfg.Log.File = viper.GetString(logFile)
}

if viper.IsSet(logEncoding) {
cfg.Log.Encoding = stringToLogEncoding[viper.GetString(logEncoding)]
}

// UI
if viper.IsSet(uiEnabled) {
cfg.UI.Enabled = viper.GetBool(uiEnabled)
Expand Down
35 changes: 33 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ func TestDatabaseProtocol(t *testing.T) {
}
}

func TestLogEncoding(t *testing.T) {
tests := []struct {
name string
encoding LogEncoding
want string
}{
{
name: "console",
encoding: LogEncodingConsole,
want: "console",
},
{
name: "json",
encoding: LogEncodingJSON,
want: "json",
},
}

for _, tt := range tests {
var (
encoding = tt.encoding
want = tt.want
)

t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, want, encoding.String())
})
}
}

func TestLoad(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -197,8 +227,9 @@ func TestLoad(t *testing.T) {
expected: func() *Config {
cfg := Default()
cfg.Log = LogConfig{
Level: "WARN",
File: "testLogFile.txt",
Level: "WARN",
File: "testLogFile.txt",
Encoding: LogEncodingJSON,
}
cfg.UI = UIConfig{
Enabled: false,
Expand Down
1 change: 1 addition & 0 deletions config/testdata/advanced.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
log:
level: WARN
file: "testLogFile.txt"
encoding: "json"

ui:
enabled: false
Expand Down

0 comments on commit 5c7037e

Please sign in to comment.