diff --git a/internal/config/config.go b/internal/config/config.go index 308e90b43..ee362efe0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -80,7 +80,8 @@ type ( // Log contains configuration for logging. Log struct { - Level string `mapstructure:"level"` // Logging level + Level string `mapstructure:"level"` // Logging level + Output string `mapstructure:"output"` // Logging output format, e.g., text, json } // Tracer contains configuration for distributed tracing. diff --git a/pkg/cmd/flags/serve.go b/pkg/cmd/flags/serve.go index 055e8d8b4..7abcfe71e 100644 --- a/pkg/cmd/flags/serve.go +++ b/pkg/cmd/flags/serve.go @@ -138,6 +138,14 @@ func RegisterServeFlags(cmd *cobra.Command) { panic(err) } + flags.String("log-output", conf.Log.Output, "logger output valid values json, text") + if err = viper.BindPFlag("logger.output", flags.Lookup("log-output")); err != nil { + panic(err) + } + if err = viper.BindEnv("logger.output", "PERMIFY_LOG_OUTPUT"); err != nil { + panic(err) + } + // AUTHN flags.Bool("authn-enabled", conf.Authn.Enabled, "enable server authentication") if err = viper.BindPFlag("authn.enabled", flags.Lookup("authn-enabled")); err != nil { diff --git a/pkg/cmd/serve.go b/pkg/cmd/serve.go index 04ccde835..a0a36c34c 100644 --- a/pkg/cmd/serve.go +++ b/pkg/cmd/serve.go @@ -89,9 +89,21 @@ func serve() func(cmd *cobra.Command, args []string) error { red := color.New(color.FgGreen) _, _ = red.Printf(internal.Banner, internal.Version) - logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ - Level: getLogLevel(cfg.Log.Level), - })) + var handler slog.Handler + switch cfg.Log.Output { + case "json": + handler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ + Level: getLogLevel(cfg.Log.Level), + }) + case "text": + handler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ + Level: getLogLevel(cfg.Log.Level), + }) + default: + return fmt.Errorf("invalid log output: %s", cfg.Log.Output) + } + + logger := slog.New(handler) slog.SetDefault(logger)