in istioctl/cmd/proxyconfig.go [665:805]
func logCmd() *cobra.Command {
var podName, podNamespace string
var podNames []string
logCmd := &cobra.Command{
Use: "log [<type>/]<name>[.<namespace>]",
Short: "(experimental) Retrieves logging levels of the Envoy in the specified pod",
Long: "(experimental) Retrieve information about logging levels of the Envoy instance in the specified pod, and update optionally",
Example: ` # Retrieve information about logging levels for a given pod from Envoy.
istioctl proxy-config log <pod-name[.namespace]>
# Update levels of the all loggers
istioctl proxy-config log <pod-name[.namespace]> --level none
# Update levels of the specified loggers.
istioctl proxy-config log <pod-name[.namespace]> --level http:debug,redis:debug
# Reset levels of all the loggers to default value (warning).
istioctl proxy-config log <pod-name[.namespace]> -r
`,
Aliases: []string{"o"},
Args: func(cmd *cobra.Command, args []string) error {
if labelSelector == "" && len(args) < 1 {
cmd.Println(cmd.UsageString())
return fmt.Errorf("log requires pod name or --selector")
}
if reset && loggerLevelString != "" {
cmd.Println(cmd.UsageString())
return fmt.Errorf("--level cannot be combined with --reset")
}
return nil
},
RunE: func(c *cobra.Command, args []string) error {
var err error
var loggerNames []string
if labelSelector != "" {
if podNames, podNamespace, err = getPodNameBySelector(labelSelector); err != nil {
return err
}
for _, pod := range podNames {
name, err = setupEnvoyLogConfig("", pod, podNamespace)
loggerNames = append(loggerNames, name)
}
if err != nil {
return err
}
if len(podNames) > 0 {
podName = podNames[0]
}
} else {
if podName, podNamespace, err = getPodName(args[0]); err != nil {
return err
}
name, err := setupEnvoyLogConfig("", podName, podNamespace)
loggerNames = append(loggerNames, name)
if err != nil {
return err
}
}
destLoggerLevels := map[string]Level{}
if reset {
// reset logging level to `defaultOutputLevel`, and ignore the `level` option
levelString, _ := getLogLevelFromConfigMap()
level, ok := stringToLevel[levelString]
if ok {
destLoggerLevels[defaultLoggerName] = level
} else {
log.Warnf("unable to get logLevel from ConfigMap istio-sidecar-injector, using default value: %v",
levelToString[defaultOutputLevel])
destLoggerLevels[defaultLoggerName] = defaultOutputLevel
}
} else if loggerLevelString != "" {
levels := strings.Split(loggerLevelString, ",")
for _, ol := range levels {
if !strings.Contains(ol, ":") && !strings.Contains(ol, "=") {
level, ok := stringToLevel[ol]
if ok {
destLoggerLevels = map[string]Level{
defaultLoggerName: level,
}
} else {
return fmt.Errorf("unrecognized logging level: %v", ol)
}
} else {
loggerLevel := regexp.MustCompile(`[:=]`).Split(ol, 2)
for _, logName := range loggerNames {
if !strings.Contains(logName, loggerLevel[0]) {
return fmt.Errorf("unrecognized logger name: %v", loggerLevel[0])
}
}
level, ok := stringToLevel[loggerLevel[1]]
if !ok {
return fmt.Errorf("unrecognized logging level: %v", loggerLevel[1])
}
destLoggerLevels[loggerLevel[0]] = level
}
}
}
var resp string
if len(destLoggerLevels) == 0 {
resp, err = setupEnvoyLogConfig("", podName, podNamespace)
} else {
if ll, ok := destLoggerLevels[defaultLoggerName]; ok {
// update levels of all loggers first
resp, err = setupEnvoyLogConfig(defaultLoggerName+"="+levelToString[ll], podName, podNamespace)
delete(destLoggerLevels, defaultLoggerName)
}
for lg, ll := range destLoggerLevels {
resp, err = setupEnvoyLogConfig(lg+"="+levelToString[ll], podName, podNamespace)
}
}
if err != nil {
return err
}
_, _ = fmt.Fprint(c.OutOrStdout(), resp)
return nil
},
ValidArgsFunction: validPodsNameArgs,
}
levelListString := fmt.Sprintf("[%s, %s, %s, %s, %s, %s, %s]",
levelToString[TraceLevel],
levelToString[DebugLevel],
levelToString[InfoLevel],
levelToString[WarningLevel],
levelToString[ErrorLevel],
levelToString[CriticalLevel],
levelToString[OffLevel])
s := strings.Join(activeLoggers, ", ")
logCmd.PersistentFlags().BoolVarP(&reset, "reset", "r", reset, "Reset levels to default value (warning).")
logCmd.PersistentFlags().StringVarP(&labelSelector, "selector", "l", "", "Label selector")
logCmd.PersistentFlags().StringVar(&loggerLevelString, "level", loggerLevelString,
fmt.Sprintf("Comma-separated minimum per-logger level of messages to output, in the form of"+
" [<logger>:]<level>,[<logger>:]<level>,... where logger can be one of %s and level can be one of %s",
s, levelListString))
return logCmd
}