Skip to content

Commit af51516

Browse files
authored
Do not use logging (#956)
Fixes #567 ## What was changed - When executing short-lived transactional commands (e.g. `start`, `list` etc, as opposed to the long-running `server start-dev` process) report errors/warnings as unstructured plain text instead of structured logging-formatted messages. - The logger is now used only by the server and SDK ## Why? CLIs should report errors/warnings by printing to stderr. They should not use structured logging messages for this. ## How was this tested - New in-codebase tests - Manually.
1 parent 65cf715 commit af51516

13 files changed

Lines changed: 71 additions & 40 deletions

cliext/flags.gen.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ func (v *CommonOptions) BuildFlags(f *pflag.FlagSet) {
3838
f.StringVar(&v.Profile, "profile", "", "Profile to use for config file. EXPERIMENTAL.")
3939
f.BoolVar(&v.DisableConfigFile, "disable-config-file", false, "If set, disables loading environment config from config file. EXPERIMENTAL.")
4040
f.BoolVar(&v.DisableConfigEnv, "disable-config-env", false, "If set, disables loading environment config from environment variables. EXPERIMENTAL.")
41-
v.LogLevel = NewFlagStringEnum([]string{"debug", "info", "warn", "error", "never"}, "info")
42-
f.Var(&v.LogLevel, "log-level", "Log level. Default is \"info\" for most commands and \"warn\" for \"server start-dev\". Accepted values: debug, info, warn, error, never.")
41+
v.LogLevel = NewFlagStringEnum([]string{"debug", "info", "warn", "error", "never"}, "never")
42+
f.Var(&v.LogLevel, "log-level", "Log level. Default is \"never\" for most commands and \"warn\" for \"server start-dev\". Accepted values: debug, info, warn, error, never.")
4343
v.LogFormat = NewFlagStringEnum([]string{"text", "json", "pretty"}, "text")
4444
f.Var(&v.LogFormat, "log-format", "Log format. Accepted values: text, json.")
4545
v.Output = NewFlagStringEnum([]string{"text", "json", "jsonl", "none"}, "text")

cliext/option-sets.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ option-sets:
5151
- never
5252
description: |
5353
Log level.
54-
Default is "info" for most commands and "warn" for "server start-dev".
55-
default: info
54+
Default is "never" for most commands and "warn" for "server start-dev".
55+
default: never
5656
- name: log-format
5757
type: string-enum
5858
description: Log format.

internal/temporalcli/commands.config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ func writeEnvConfigFile(cctx *CommandContext, conf *envconfig.ClientConfig) erro
325325
}
326326

327327
// Write to file, making dirs as needed
328-
cctx.Logger.Info("Writing config file", "file", configFile)
329328
if err := os.MkdirAll(filepath.Dir(configFile), 0700); err != nil {
330329
return fmt.Errorf("failed making config file parent dirs: %w", err)
331330
} else if err := os.WriteFile(configFile, b, 0600); err != nil {

internal/temporalcli/commands.env.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
func (c *TemporalEnvCommand) envNameAndKey(cctx *CommandContext, args []string, keyFlag string) (string, string, error) {
1515
if len(args) > 0 {
16-
cctx.Logger.Warn("Arguments to env commands are deprecated; please use --env and --key (or -k) instead")
16+
fmt.Fprintln(cctx.Options.Stderr, "Warning: Arguments to env commands are deprecated; please use --env and --key (or -k) instead")
1717

1818
if c.Parent.Env != "default" || keyFlag != "" {
1919
return "", "", fmt.Errorf("cannot specify both an argument and flags; please use flags instead")
@@ -49,10 +49,8 @@ func (c *TemporalEnvDeleteCommand) run(cctx *CommandContext, args []string) erro
4949
env, _ := cctx.DeprecatedEnvConfigValues[envName]
5050
// User can remove single flag or all in env
5151
if key != "" {
52-
cctx.Logger.Info("Deleting env property", "env", envName, "property", key)
5352
delete(env, key)
5453
} else {
55-
cctx.Logger.Info("Deleting env", "env", env)
5654
delete(cctx.DeprecatedEnvConfigValues, envName)
5755
}
5856
return writeDeprecatedEnvConfigToFile(cctx)
@@ -129,7 +127,6 @@ func (c *TemporalEnvSetCommand) run(cctx *CommandContext, args []string) error {
129127
if cctx.DeprecatedEnvConfigValues[envName] == nil {
130128
cctx.DeprecatedEnvConfigValues[envName] = map[string]string{}
131129
}
132-
cctx.Logger.Info("Setting env property", "env", envName, "property", key, "value", value)
133130
cctx.DeprecatedEnvConfigValues[envName][key] = value
134131
return writeDeprecatedEnvConfigToFile(cctx)
135132
}
@@ -138,7 +135,6 @@ func writeDeprecatedEnvConfigToFile(cctx *CommandContext) error {
138135
if cctx.Options.DeprecatedEnvConfig.EnvConfigFile == "" {
139136
return fmt.Errorf("unable to find place for env file (unknown HOME dir)")
140137
}
141-
cctx.Logger.Info("Writing env file", "file", cctx.Options.DeprecatedEnvConfig.EnvConfigFile)
142138
return writeDeprecatedEnvConfigFile(cctx.Options.DeprecatedEnvConfig.EnvConfigFile, cctx.DeprecatedEnvConfigValues)
143139
}
144140

internal/temporalcli/commands.env_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package temporalcli_test
22

33
import (
44
"os"
5+
"strings"
56
"testing"
67

78
"gopkg.in/yaml.v3"
@@ -104,3 +105,32 @@ func TestEnv_InputValidation(t *testing.T) {
104105
res = h.Execute("env", "set", "myenv1.foo")
105106
h.ErrorContains(res.Err, `no value provided`)
106107
}
108+
109+
func TestEnv_DeprecationWarningBypassesLogger(t *testing.T) {
110+
h := NewCommandHarness(t)
111+
defer h.Close()
112+
113+
tmpFile, err := os.CreateTemp("", "")
114+
h.NoError(err)
115+
h.Options.DeprecatedEnvConfig.EnvConfigFile = tmpFile.Name()
116+
defer os.Remove(h.Options.DeprecatedEnvConfig.EnvConfigFile)
117+
res := h.Execute("env", "set", "--env", "myenv1", "-k", "foo", "-v", "bar")
118+
h.NoError(res.Err)
119+
120+
// Using deprecated argument syntax should produce a warning on stderr.
121+
// The warning must bypass the logger so it appears regardless of log level.
122+
for _, logLevel := range []string{"never", "error", "info"} {
123+
t.Run("log-level="+logLevel, func(t *testing.T) {
124+
res = h.Execute("env", "get", "--log-level", logLevel, "myenv1")
125+
h.NoError(res.Err)
126+
127+
stderr := res.Stderr.String()
128+
h.Contains(stderr, "Warning:")
129+
h.Contains(stderr, "deprecated")
130+
131+
// Must be a plain-text warning, not a structured log message
132+
h.False(strings.Contains(stderr, "time="), "warning should not be a structured log message")
133+
h.False(strings.Contains(stderr, "level="), "warning should not be a structured log message")
134+
})
135+
}
136+
}

internal/temporalcli/commands.gen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,7 @@ func NewTemporalServerStartDevCommand(cctx *CommandContext, parent *TemporalServ
21172117
s.Command.Flags().StringVar(&s.UiCodecEndpoint, "ui-codec-endpoint", "", "UI remote codec HTTP endpoint.")
21182118
s.Command.Flags().StringArrayVar(&s.SqlitePragma, "sqlite-pragma", nil, "SQLite pragma statements in \"PRAGMA=VALUE\" format.")
21192119
s.Command.Flags().StringArrayVar(&s.DynamicConfigValue, "dynamic-config-value", nil, "Dynamic configuration value using `KEY=VALUE` pairs. Keys must be identifiers, and values must be JSON values. For example: `YourKey=\"YourString\"` Can be passed multiple times.")
2120-
s.Command.Flags().BoolVar(&s.LogConfig, "log-config", false, "Log the server config to stderr.")
2120+
s.Command.Flags().BoolVar(&s.LogConfig, "log-config", false, "Print the server config to stderr.")
21212121
s.Command.Flags().StringArrayVar(&s.SearchAttribute, "search-attribute", nil, "Search attributes to register using `KEY=VALUE` pairs. Keys must be identifiers, and values must be the search attribute type, which is one of the following: Text, Keyword, Int, Double, Bool, Datetime, KeywordList.")
21222122
s.Command.Run = func(c *cobra.Command, args []string) {
21232123
if err := s.run(cctx, args); err != nil {

internal/temporalcli/commands.go

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ type CommandContext struct {
4848
FlagsWithEnvVars []*pflag.Flag
4949

5050
// These values may not be available until after pre-run of main command
51-
Printer *printer.Printer
51+
Printer *printer.Printer
52+
// The logger is for the SDK and server. The CLI itself should print warnings or errors to
53+
// stderr but should not use logging.
5254
Logger *slog.Logger
5355
JSONOutput bool
5456
JSONShorthandPayloads bool
@@ -143,11 +145,7 @@ func (c *CommandContext) preprocessOptions() error {
143145
if c.Err() != nil {
144146
err = fmt.Errorf("program interrupted")
145147
}
146-
if c.Logger != nil {
147-
c.Logger.Error(err.Error())
148-
} else {
149-
fmt.Fprintln(os.Stderr, err)
150-
}
148+
fmt.Fprintf(c.Options.Stderr, "Error: %v\n", err)
151149
os.Exit(1)
152150
}
153151
}
@@ -260,13 +258,11 @@ func UnmarshalProtoJSONWithOptions(b []byte, m proto.Message, jsonShorthandPaylo
260258
return opts.Unmarshal(b, m)
261259
}
262260

263-
// Set flag values from environment file & variables. Returns a callback to log anything interesting
264-
// since logging will not yet be initialized when this runs.
265-
func (c *CommandContext) populateFlagsFromEnv(flags *pflag.FlagSet) (func(*slog.Logger), error) {
261+
// Set flag values from environment file & variables.
262+
func (c *CommandContext) populateFlagsFromEnv(flags *pflag.FlagSet) error {
266263
if flags == nil {
267-
return func(logger *slog.Logger) {}, nil
264+
return nil
268265
}
269-
var logCalls []func(*slog.Logger)
270266
var flagErr error
271267
flags.VisitAll(func(flag *pflag.Flag) {
272268
// If the flag was already changed by the user, we don't overwrite
@@ -289,20 +285,14 @@ func (c *CommandContext) populateFlagsFromEnv(flags *pflag.FlagSet) (func(*slog.
289285
return
290286
}
291287
if flag.Changed {
292-
logCalls = append(logCalls, func(l *slog.Logger) {
293-
l.Info("Env var overrode --env setting", "env_var", anns[0], "flag", flag.Name)
294-
})
288+
fmt.Fprintf(c.Options.Stderr,
289+
"Warning: env var %s overrode --env setting for flag --%s\n", anns[0], flag.Name)
295290
}
296291
flag.Changed = true
297292
}
298293
}
299294
})
300-
logFn := func(logger *slog.Logger) {
301-
for _, call := range logCalls {
302-
call(logger)
303-
}
304-
}
305-
return logFn, flagErr
295+
return flagErr
306296
}
307297

308298
// Returns error if JSON output enabled
@@ -459,8 +449,7 @@ func (c *TemporalCommand) initCommand(cctx *CommandContext) {
459449
cctx.CurrentCommand = cmd
460450
// Populate environ. We will make the error return here which will cause
461451
// usage to be printed.
462-
logCalls, err := cctx.populateFlagsFromEnv(cmd.Flags())
463-
if err != nil {
452+
if err := cctx.populateFlagsFromEnv(cmd.Flags()); err != nil {
464453
return err
465454
}
466455

@@ -472,8 +461,6 @@ func (c *TemporalCommand) initCommand(cctx *CommandContext) {
472461

473462
res := c.preRun(cctx)
474463

475-
logCalls(cctx.Logger)
476-
477464
// Always disable color if JSON output is on (must be run after preRun so JSONOutput is set)
478465
if cctx.JSONOutput {
479466
color.NoColor = true

internal/temporalcli/commands.operator_namespace.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func (c *TemporalOperatorCommand) getNSFromFlagOrArg0(cctx *CommandContext, args
1919
}
2020

2121
if len(args) > 0 {
22-
cctx.Logger.Warn("Passing the namespace as an argument is now deprecated; please switch to using -n instead")
22+
fmt.Fprintln(cctx.Options.Stderr, "Warning: Passing the namespace as an argument is now deprecated; please switch to using -n instead")
2323
return args[0], nil
2424
}
2525
return c.Namespace, nil

internal/temporalcli/commands.server.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ func (t *TemporalServerStartDevCommand) run(cctx *CommandContext, args []string)
134134
// Log config if requested
135135
if t.LogConfig {
136136
opts.LogConfig = func(b []byte) {
137-
cctx.Logger.Info("Logging config")
138137
_, _ = cctx.Options.Stderr.Write(b)
139138
}
140139
}

internal/temporalcli/commands.workflow_exec.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (c *TemporalWorkflowExecuteCommand) run(cctx *CommandContext, args []string
9494
// Log print failure and return workflow failure if workflow failed
9595
if closeEvent.EventType != enums.EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED {
9696
if err != nil {
97-
cctx.Logger.Error("Workflow failed, and printing the output also failed", "error", err)
97+
fmt.Fprintf(cctx.Options.Stderr, "Warning: printing workflow output failed: %v\n", err)
9898
}
9999
err = fmt.Errorf("workflow failed")
100100
}

0 commit comments

Comments
 (0)