From 91b1684891cc8dd97d57d268367bd2c679fda9cc Mon Sep 17 00:00:00 2001 From: Jianjun Shen Date: Sat, 3 Oct 2020 21:32:40 -0700 Subject: [PATCH] Support get/set log verbosity level by antctl and controller/agent API Add antctl log-level command that calls controller or agent /loglevel API to get/set the log verbosity level of controller or agent in the runtime. Change antctl to allow an empty response of an controller or agent call. --- build/yamls/antrea-aks.yml | 1 + build/yamls/antrea-eks.yml | 1 + build/yamls/antrea-gke.yml | 1 + build/yamls/antrea-ipsec.yml | 1 + build/yamls/antrea.yml | 1 + build/yamls/base/antctl.yml | 1 + docs/antctl.md | 20 ++++++++++ pkg/agent/apiserver/apiserver.go | 2 + pkg/antctl/antctl.go | 38 ++++++++++++++++++ pkg/antctl/command_definition.go | 23 +++++++---- pkg/antctl/command_list.go | 4 ++ pkg/apiserver/apiserver.go | 2 + pkg/apiserver/handlers/loglevel/handler.go | 46 ++++++++++++++++++++++ pkg/log/log_level.go | 46 ++++++++++++++++++++++ 14 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 pkg/apiserver/handlers/loglevel/handler.go create mode 100644 pkg/log/log_level.go diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml index 66cd54ed7a4..00a1b0879c9 100644 --- a/build/yamls/antrea-aks.yml +++ b/build/yamls/antrea-aks.yml @@ -731,6 +731,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml index 2234707c352..5afd3a17450 100644 --- a/build/yamls/antrea-eks.yml +++ b/build/yamls/antrea-eks.yml @@ -731,6 +731,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml index 53be82082d9..ed380d24354 100644 --- a/build/yamls/antrea-gke.yml +++ b/build/yamls/antrea-gke.yml @@ -731,6 +731,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml index d517bc92324..ed8ffac556b 100644 --- a/build/yamls/antrea-ipsec.yml +++ b/build/yamls/antrea-ipsec.yml @@ -731,6 +731,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml index f8f5a868b4a..9f0fffa82b7 100644 --- a/build/yamls/antrea.yml +++ b/build/yamls/antrea.yml @@ -731,6 +731,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/build/yamls/base/antctl.yml b/build/yamls/base/antctl.yml index 66fe0198a9c..de515fdb9d9 100644 --- a/build/yamls/base/antctl.yml +++ b/build/yamls/base/antctl.yml @@ -53,6 +53,7 @@ rules: - /agentinfo - /addressgroups - /appliedtogroups + - /loglevel - /networkpolicies - /ovsflows - /ovstracing diff --git a/docs/antctl.md b/docs/antctl.md index d5eafc771a0..d6bcbb40250 100644 --- a/docs/antctl.md +++ b/docs/antctl.md @@ -15,6 +15,7 @@ running in two different modes: - [Installation](#installation) - [Usage](#usage) + - [Showing or changing log verbosity level](#showing-or-changing-log-verbosity-level) - [Collecting support information](#collecting-support-information) - [controllerinfo and agentinfo commands](#controllerinfo-and-agentinfo-commands) - [NetworkPolicy commands](#networkpolicy-commands) @@ -75,6 +76,25 @@ one by setting the `KUBECONFIG` environment variable or with `--kubeconfig` The following sub-sections introduce a few commands which are useful for troubleshooting the Antrea system. +### Showing or changing log verbosity level +Starting from version 0.10.0, Antrea supports showing or changing the log +verbosity level of Antrea Controller or Agent using the `antctl log-level` +command. The command can only run locally inside the `antrea-controller` or +`antrea-agent` container. + +The following command prints the current log verbosity level: + +```bash +antctl log-level +``` + +This command updates the log verbosity level (the `level` argument must be an +integer): + +```bash +antctl log-level +``` + ### Collecting support information Starting with version 0.7.0, Antrea supports the `antctl supportbundle` command, diff --git a/pkg/agent/apiserver/apiserver.go b/pkg/agent/apiserver/apiserver.go index ebda37b83fd..cd438fff756 100644 --- a/pkg/agent/apiserver/apiserver.go +++ b/pkg/agent/apiserver/apiserver.go @@ -40,6 +40,7 @@ import ( agentquerier "github.com/vmware-tanzu/antrea/pkg/agent/querier" systeminstall "github.com/vmware-tanzu/antrea/pkg/apis/system/install" systemv1beta1 "github.com/vmware-tanzu/antrea/pkg/apis/system/v1beta1" + "github.com/vmware-tanzu/antrea/pkg/apiserver/handlers/loglevel" "github.com/vmware-tanzu/antrea/pkg/apiserver/registry/system/supportbundle" "github.com/vmware-tanzu/antrea/pkg/ovs/ovsctl" "github.com/vmware-tanzu/antrea/pkg/querier" @@ -69,6 +70,7 @@ func (s *agentAPIServer) Run(stopCh <-chan struct{}) error { } func installHandlers(aq agentquerier.AgentQuerier, npq querier.AgentNetworkPolicyInfoQuerier, s *genericapiserver.GenericAPIServer) { + s.Handler.NonGoRestfulMux.HandleFunc("/loglevel", loglevel.HandleFunc()) s.Handler.NonGoRestfulMux.HandleFunc("/agentinfo", agentinfo.HandleFunc(aq)) s.Handler.NonGoRestfulMux.HandleFunc("/podinterfaces", podinterface.HandleFunc(aq)) s.Handler.NonGoRestfulMux.HandleFunc("/networkpolicies", networkpolicy.HandleFunc(aq)) diff --git a/pkg/antctl/antctl.go b/pkg/antctl/antctl.go index 6009dc5f232..586cf239eef 100644 --- a/pkg/antctl/antctl.go +++ b/pkg/antctl/antctl.go @@ -59,8 +59,46 @@ var CommandList = &commandList{ }, addonTransform: version.AgentTransform, }, + transformedResponse: reflect.TypeOf(version.Response{}), }, + { + use: "log-level", + short: "Show or set log verbosity level", + long: "Show or set the log verbosity level of ${component}", + example: ` Show the current log verbosity level + $ antctl log-level + Set the log verbosity level to 2 + $ antctl log-level 2`, + commandGroup: flat, + controllerEndpoint: &endpoint{ + nonResourceEndpoint: &nonResourceEndpoint{ + path: "/loglevel", + params: []flagInfo{ + { + name: "level", + usage: "The integer log verbosity level to set", + arg: true, + }, + }, + outputType: single, + }, + }, + agentEndpoint: &endpoint{ + nonResourceEndpoint: &nonResourceEndpoint{ + path: "/loglevel", + params: []flagInfo{ + { + name: "level", + usage: "The integer log verbosity level to set", + arg: true, + }, + }, + outputType: single, + }, + }, + transformedResponse: reflect.TypeOf(0), + }, { use: "networkpolicy", aliases: []string{"networkpolicies", "netpol"}, diff --git a/pkg/antctl/command_definition.go b/pkg/antctl/command_definition.go index 9daf6a69904..d2ba8eaa5df 100644 --- a/pkg/antctl/command_definition.go +++ b/pkg/antctl/command_definition.go @@ -687,8 +687,12 @@ func (cd *commandDefinition) output(resp io.Reader, writer io.Writer, ft formatt if addonTransform == nil { // Decode the data if there is no AddonTransform. obj, err = cd.decode(resp, single) + if err == io.EOF { + // No response returned. + return nil + } if err != nil { - return fmt.Errorf("error when decoding response: %w", err) + return fmt.Errorf("error when decoding response %v: %w", resp, err) } } else { obj, err = addonTransform(resp, single) @@ -721,15 +725,18 @@ func (cd *commandDefinition) output(resp io.Reader, writer io.Writer, ft formatt func (cd *commandDefinition) collectFlags(cmd *cobra.Command, args []string) (map[string]string, error) { argMap := make(map[string]string) - if len(args) > 0 { - argMap["name"] = args[0] - } if endpoint := cd.getEndpoint(); endpoint != nil { for _, f := range endpoint.flags() { - vs, err := cmd.Flags().GetString(f.name) - if err == nil && len(vs) != 0 { - argMap[f.name] = vs - continue + if f.arg { + if len(args) > 0 { + argMap[f.name] = args[0] + } + } else { + vs, err := cmd.Flags().GetString(f.name) + if err == nil && len(vs) != 0 { + argMap[f.name] = vs + continue + } } } } diff --git a/pkg/antctl/command_list.go b/pkg/antctl/command_list.go index 3e07e629b89..e0c8656d88f 100644 --- a/pkg/antctl/command_list.go +++ b/pkg/antctl/command_list.go @@ -112,6 +112,10 @@ func (cl *commandList) GetDebugCommands(mode string) [][]string { if def.commandGroup == query { continue } + if mode == runtime.ModeController && def.use == "log-level" { + // log-level command does not support remote execution. + continue + } if mode == runtime.ModeAgent && def.agentEndpoint != nil || mode == runtime.ModeController && def.controllerEndpoint != nil { var currentCommand []string diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index f762cae8675..0aa3e4f4e6e 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -38,6 +38,7 @@ import ( system "github.com/vmware-tanzu/antrea/pkg/apis/system/v1beta1" "github.com/vmware-tanzu/antrea/pkg/apiserver/certificate" "github.com/vmware-tanzu/antrea/pkg/apiserver/handlers/endpoint" + "github.com/vmware-tanzu/antrea/pkg/apiserver/handlers/loglevel" "github.com/vmware-tanzu/antrea/pkg/apiserver/handlers/webhook" "github.com/vmware-tanzu/antrea/pkg/apiserver/registry/controlplane/nodestatssummary" "github.com/vmware-tanzu/antrea/pkg/apiserver/registry/networkpolicy/addressgroup" @@ -225,6 +226,7 @@ func CleanupDeprecatedAPIServices(aggregatorClient clientset.Interface) error { } func installHandlers(c *ExtraConfig, s *genericapiserver.GenericAPIServer) { + s.Handler.NonGoRestfulMux.HandleFunc("/loglevel", loglevel.HandleFunc()) s.Handler.NonGoRestfulMux.HandleFunc("/endpoint", endpoint.HandleFunc(c.endpointQuerier)) if features.DefaultFeatureGate.Enabled(features.AntreaPolicy) { // Get new NetworkPolicyValidator diff --git a/pkg/apiserver/handlers/loglevel/handler.go b/pkg/apiserver/handlers/loglevel/handler.go new file mode 100644 index 00000000000..ec7cd16d3ae --- /dev/null +++ b/pkg/apiserver/handlers/loglevel/handler.go @@ -0,0 +1,46 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package loglevel + +import ( + "encoding/json" + "net/http" + "strconv" + + "k8s.io/klog" + + "github.com/vmware-tanzu/antrea/pkg/log" +) + +// HandleFunc returns the function which can handle the /log-level API request. +func HandleFunc() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + level := r.URL.Query().Get("level") + if level != "" { + err := log.SetLogLevel(level) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + } else { + levelNum, _ := strconv.Atoi(log.GetCurrentLogLevel()) + err := json.NewEncoder(w).Encode(levelNum) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + klog.Errorf("Error when encoding log level to json: %v", err) + } + } + } +} diff --git a/pkg/log/log_level.go b/pkg/log/log_level.go new file mode 100644 index 00000000000..bfaf22d7375 --- /dev/null +++ b/pkg/log/log_level.go @@ -0,0 +1,46 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package log + +import ( + "flag" + + "k8s.io/klog" +) + +const logVerbosityFlag = "v" + +// GetCurrentLogLevel returns the current log verbosity level. +func GetCurrentLogLevel() string { + return flag.Lookup(logVerbosityFlag).Value.String() +} + +// SetLogLevel sets the log verbosity level. level must be a string +// representation of a decimal integer. +func SetLogLevel(level string) error { + oldLevel := GetCurrentLogLevel() + if oldLevel == level { + return nil + } + + var l klog.Level + err := l.Set(level) + if err != nil { + return err + } + klog.Infof("Changed log level from %s to %s", oldLevel, level) + return nil + +}