From 383a89b948ce123e9cc616cfc4ae213d6b0de90d Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Wed, 17 Jan 2018 09:22:45 +0000 Subject: [PATCH] Add flags and utils for logrus Signed-off-by: Lantao Liu --- cmd/cri-containerd/cri_containerd.go | 57 +++++++++++++++++++++------ cmd/cri-containerd/options/options.go | 6 ++- cri.go | 13 +++--- pkg/log/log.go | 46 +++++++++++++++++++++ 4 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 pkg/log/log.go diff --git a/cmd/cri-containerd/cri_containerd.go b/cmd/cri-containerd/cri_containerd.go index f994a7fa5..b54a5f863 100644 --- a/cmd/cri-containerd/cri_containerd.go +++ b/cmd/cri-containerd/cri_containerd.go @@ -27,12 +27,13 @@ import ( "runtime" "syscall" - "github.com/golang/glog" "github.com/opencontainers/selinux/go-selinux" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/util/interrupt" "github.com/containerd/cri-containerd/cmd/cri-containerd/options" + "github.com/containerd/cri-containerd/pkg/log" "github.com/containerd/cri-containerd/pkg/server" "github.com/containerd/cri-containerd/pkg/version" ) @@ -53,11 +54,6 @@ var cmd = &cobra.Command{ Long: desc, } -// Add golang flags as persistent flags. -func init() { - cmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) -} - func defaultConfigCommand() *cobra.Command { return &cobra.Command{ Use: "default-config", @@ -93,15 +89,19 @@ func main() { } validateConfig(o) - glog.V(0).Infof("Run cri-containerd %+v", o) + if err := setLogLevel(o.LogLevel); err != nil { + return fmt.Errorf("failed to set log level: %v", err) + } + + logrus.Infof("Run cri-containerd %+v", o) // Start profiling server if enable. if o.EnableProfiling { - glog.V(2).Info("Start profiling server") + logrus.Info("Start profiling server") go startProfilingServer(o.ProfilingAddress, o.ProfilingPort) } - glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath) + logrus.Infof("Run cri-containerd grpc server on socket %q", o.SocketPath) s, err := server.NewCRIContainerdService(o.Config) if err != nil { return fmt.Errorf("failed to create CRI containerd service: %v", err) @@ -125,7 +125,7 @@ func main() { func validateConfig(o *options.CRIContainerdOptions) { if o.EnableSelinux { if !selinux.GetEnabled() { - glog.Warning("Selinux is not supported") + logrus.Warn("Selinux is not supported") } } else { selinux.SetDisabled() @@ -152,7 +152,7 @@ func dumpStacks() { } buf = make([]byte, 2*len(buf)) } - glog.V(0).Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) + logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) } // startProfilingServer start http server to profiling via web interface @@ -164,6 +164,39 @@ func startProfilingServer(host string, port string) { mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/trace", pprof.Trace) if err := http.ListenAndServe(endpoint, mux); err != nil { - glog.Errorf("Failed to start profiling server: %v", err) + logrus.WithError(err).Error("Failed to start profiling server") } } + +func setLogLevel(l string) error { + lvl, err := log.ParseLevel(l) + if err != nil { + return err + } + if err := setGLogLevel(lvl); err != nil { + return err + } + logrus.SetLevel(lvl) + return nil +} + +// TODO(random-liu): Set glog level in plugin mode. +func setGLogLevel(l logrus.Level) error { + if err := flag.Set("logtostderr", "true"); err != nil { + return err + } + switch l { + case log.TraceLevel: + return flag.Set("v", "5") + case logrus.DebugLevel: + return flag.Set("v", "4") + case logrus.InfoLevel: + return flag.Set("v", "2") + // glog doesn't support following filters. Defaults to v=0. + case logrus.WarnLevel: + case logrus.ErrorLevel: + case logrus.FatalLevel: + case logrus.PanicLevel: + } + return nil +} diff --git a/cmd/cri-containerd/options/options.go b/cmd/cri-containerd/options/options.go index c7d328e8a..d290a07ad 100644 --- a/cmd/cri-containerd/options/options.go +++ b/cmd/cri-containerd/options/options.go @@ -99,13 +99,15 @@ type Config struct { // SkipImageFSUUID skips retrieving imagefs uuid. // TODO(random-liu): Remove this after we find a generic way to get imagefs uuid. SkipImageFSUUID bool `toml:"skip_imagefs_uuid" json:"skipImageFSUUID,omitempty"` + // LogLevel is the logrus log level. + LogLevel string `toml:"log_level" json:"logLevel,omitempty"` } // CRIContainerdOptions contains cri-containerd command line and toml options. type CRIContainerdOptions struct { // Config contains cri-containerd toml config Config - // Path to the TOML config file. + // ConfigFilePath is the path to the TOML config file. ConfigFilePath string `toml:"-"` } @@ -117,6 +119,8 @@ func NewCRIContainerdOptions() *CRIContainerdOptions { // AddFlags adds cri-containerd command line options to pflag. func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) { defaults := DefaultConfig() + fs.StringVar(&c.LogLevel, "log-level", + "info", "Set the logging level [trace, debug, info, warn, error, fatal, panic].") fs.StringVar(&c.ConfigFilePath, configFilePathArgName, defaultConfigFilePath, "Path to the config file.") fs.StringVar(&c.SocketPath, "socket-path", diff --git a/cri.go b/cri.go index dbe853f55..b61aa3bb1 100644 --- a/cri.go +++ b/cri.go @@ -17,8 +17,8 @@ limitations under the License. package cri import ( + "github.com/containerd/containerd/log" "github.com/containerd/containerd/plugin" - "github.com/golang/glog" "github.com/containerd/cri-containerd/cmd/cri-containerd/options" "github.com/containerd/cri-containerd/pkg/server" @@ -43,27 +43,28 @@ func init() { }) } -func initCRIService(_ *plugin.InitContext) (interface{}, error) { +func initCRIService(ic *plugin.InitContext) (interface{}, error) { + ctx := ic.Context // TODO(random-liu): Support Config through Registration.Config. // TODO(random-liu): Validate the configuration. // TODO(random-liu): Leverage other fields in InitContext, such as Root. // TODO(random-liu): Register GRPC service onto containerd GRPC server. // TODO(random-liu): Separate cri plugin config from cri-containerd server config, // because many options only make sense to cri-containerd server. - // TODO(random-liu): Change all glog to logrus. // TODO(random-liu): Handle graceful stop. + // TODO(random-liu): Make grpc interceptor pluggable, and add and use cri context. c := options.DefaultConfig() - glog.V(0).Infof("Start cri plugin with config %+v", c) + log.G(ctx).Infof("Start cri plugin with config %+v", c) // Use a goroutine to start cri service. The reason is that currently // cri service requires containerd to be running. // TODO(random-liu): Resolve the circular dependency. go func() { s, err := server.NewCRIContainerdService(c) if err != nil { - glog.Exitf("Failed to create CRI service: %v", err) + log.G(ctx).WithError(err).Fatal("Failed to create CRI service") } if err := s.Run(); err != nil { - glog.Exitf("Failed to run CRI grpc server: %v", err) + log.G(ctx).WithError(err).Fatal("Failed to run CRI grpc server") } }() return nil, nil diff --git a/pkg/log/log.go b/pkg/log/log.go new file mode 100644 index 000000000..4035c0f14 --- /dev/null +++ b/pkg/log/log.go @@ -0,0 +1,46 @@ +/* +Copyright 2018 The Containerd 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 "github.com/sirupsen/logrus" + +// TODO(random-liu): Add trace support in containerd. + +// TraceLevel is the log level for trace. +const TraceLevel = logrus.Level(uint32(logrus.DebugLevel + 1)) + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (logrus.Level, error) { + if lvl == "trace" { + return TraceLevel, nil + } + return logrus.ParseLevel(lvl) +} + +// Trace logs a message at level Trace on the standard logger. +func Trace(args ...interface{}) { + if logrus.GetLevel() >= TraceLevel { + logrus.Debug(args...) + } +} + +// Tracef logs a message at level Trace on the standard logger. +func Tracef(format string, args ...interface{}) { + if logrus.GetLevel() >= TraceLevel { + logrus.Debugf(format, args...) + } +}