From fad5934e2b3c661bf3cdcadb6eb74a799e89ea98 Mon Sep 17 00:00:00 2001 From: Murcherla Date: Mon, 3 Feb 2020 09:14:26 -0600 Subject: [PATCH] Zap logger --- README.md | 14 +- cmd/aws-k8s-agent/main.go | 5 +- cmd/cni-metrics-helper/main.go | 23 ++- cmd/cni-metrics-helper/metrics/metrics.go | 64 ++++---- cmd/grpc-health-probe/main.go | 38 ++--- cmd/routed-eni-cni-plugin/cni.go | 17 +- cmd/routed-eni-cni-plugin/driver/driver.go | 7 +- go.mod | 7 +- go.sum | 35 +++++ pkg/awsutils/awsutils.go | 7 +- pkg/cri/cri.go | 6 +- pkg/ec2wrapper/ec2wrapper.go | 11 +- pkg/eniconfig/eniconfig.go | 6 +- pkg/ipamd/datastore/data_store.go | 13 +- pkg/ipamd/introspect.go | 6 +- pkg/ipamd/ipamd.go | 20 +-- pkg/ipamd/metrics.go | 5 +- pkg/ipamd/rpc_handler.go | 3 +- pkg/k8sapi/discovery.go | 8 +- pkg/networkutils/network.go | 4 +- pkg/publisher/publisher.go | 22 +-- pkg/utils/logger/logger.go | 157 ++++++++++++------- pkg/utils/logger/logger_test.go | 71 +++++---- pkg/utils/logger/zaplogger.go | 174 +++++++++++++++++++++ 24 files changed, 505 insertions(+), 218 deletions(-) create mode 100644 pkg/utils/logger/zaplogger.go diff --git a/README.md b/README.md index be0fb24cbcb..87ed9e88080 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,19 @@ Default: Unset Valid Values: `stdout` or a file path -Specifies where to write the logging output. Either to stdout or to override the default file. +Specifies where to write the logging output of L-IPamD. Either to stdout or to override the default file. + +--- + +`AWS_VPC_K8S_PLUGIN_LOGL_FILE` + +Type: String + +Default: Unset + +Valid Values: `stdout` or a file path + +Specifies where to write the logging output for CNI plugin. Either to stdout or to override the default file. --- diff --git a/cmd/aws-k8s-agent/main.go b/cmd/aws-k8s-agent/main.go index 7e4a84ce936..e83b6035b0d 100644 --- a/cmd/aws-k8s-agent/main.go +++ b/cmd/aws-k8s-agent/main.go @@ -16,8 +16,6 @@ package main import ( "os" - log "github.com/cihub/seelog" - "github.com/aws/amazon-vpc-cni-k8s/pkg/eniconfig" "github.com/aws/amazon-vpc-cni-k8s/pkg/ipamd" "github.com/aws/amazon-vpc-cni-k8s/pkg/k8sapi" @@ -30,6 +28,7 @@ const ( var ( version string + log = logger.InitZapLogger("L-IPamD") ) func main() { @@ -37,8 +36,6 @@ func main() { } func _main() int { - defer log.Flush() - logger.SetupLogger(logger.GetLogFileLocation(defaultLogFilePath)) log.Infof("Starting L-IPAMD %s ...", version) diff --git a/cmd/cni-metrics-helper/main.go b/cmd/cni-metrics-helper/main.go index e97b9208b6d..6eef7dc079e 100644 --- a/cmd/cni-metrics-helper/main.go +++ b/cmd/cni-metrics-helper/main.go @@ -21,7 +21,7 @@ import ( "strings" "time" - "github.com/golang/glog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/spf13/pflag" "github.com/aws/amazon-vpc-cni-k8s/cmd/cni-metrics-helper/metrics" @@ -29,6 +29,8 @@ import ( "github.com/aws/amazon-vpc-cni-k8s/pkg/publisher" ) +var log = logger.InitZapLogger("cni-metrics-helper") + type options struct { kubeconfig string pullInterval int @@ -40,11 +42,8 @@ type options struct { func main() { options := &options{} flags := pflag.NewFlagSet("", pflag.ExitOnError) - // Add glog flags flags.AddGoFlagSet(flag.CommandLine) - _ = flags.Lookup("logtostderr").Value.Set("true") - flags.Lookup("logtostderr").DefValue = "true" - flags.Lookup("logtostderr").NoOptDefVal = "true" + flags.BoolVar(&options.submitCW, "cloudwatch", true, "a bool") flags.Usage = func() { @@ -54,12 +53,12 @@ func main() { err := flags.Parse(os.Args) if err != nil { - glog.Fatalf("Error on parsing parameters: %s", err) + log.Fatalf("Error on parsing parameters: %s", err) } err = flag.CommandLine.Parse([]string{}) if err != nil { - glog.Fatalf("Error on parsing commandline: %s", err) + log.Fatalf("Error on parsing commandline: %s", err) } if options.help { @@ -77,12 +76,11 @@ func main() { } } - glog.Infof("Starting CNIMetricsHelper. Sending metrics to CloudWatch: %v", options.submitCW) + log.Infof("Starting CNIMetricsHelper. Sending metrics to CloudWatch: %v", options.submitCW) kubeClient, err := k8sapi.CreateKubeClient() if err != nil { - glog.Errorf("Failed to create client: %v", err) - os.Exit(1) + log.Fatalf("Failed to create client: %v", err) } discoverController := k8sapi.NewController(kubeClient) @@ -96,8 +94,7 @@ func main() { cw, err = publisher.New(ctx) if err != nil { - glog.Errorf("Failed to create publisher: %v", err) - os.Exit(1) + log.Fatalf("Failed to create publisher: %v", err) } go cw.Start() defer cw.Stop() @@ -109,7 +106,7 @@ func main() { // metric loop var pullInterval = 30 // seconds for range time.Tick(time.Duration(pullInterval) * time.Second) { - glog.Info("Collecting metrics ...") + log.Info("Collecting metrics ...") metrics.Handler(cniMetric) } } diff --git a/cmd/cni-metrics-helper/metrics/metrics.go b/cmd/cni-metrics-helper/metrics/metrics.go index 3fc3d7615c9..d8578bf3bb1 100644 --- a/cmd/cni-metrics-helper/metrics/metrics.go +++ b/cmd/cni-metrics-helper/metrics/metrics.go @@ -19,16 +19,20 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" + "go.uber.org/zap" "github.com/aws/aws-sdk-go/service/cloudwatch" - "github.com/golang/glog" + dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" clientset "k8s.io/client-go/kubernetes" "github.com/aws/amazon-vpc-cni-k8s/pkg/publisher" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" ) +var log = logger.GetZapLogger() + type metricMatcher func(metric *dto.Metric) bool type actionFuncType func(aggregatedValue *float64, sampleValue float64) @@ -98,18 +102,18 @@ func getMetricsFromPod(client clientset.Interface, podName string, namespace str func processGauge(metric *dto.Metric, act *metricsAction) { if act.logToFile { - glog.Infof("Label: %v, Value: %v ", metric.GetLabel(), metric.GetGauge().GetValue()) + log.Infof("Label: %v, Value: %v ", metric.GetLabel(), metric.GetGauge().GetValue()) } else { - glog.V(10).Info("processing GAUGE: ", metric.GetGauge().GetValue()) + log.Infof("processing: ", zap.Float64("GAUGE", metric.GetGauge().GetValue())) } act.actionFunc(&act.data.curSingleDataPoint, metric.GetGauge().GetValue()) } func processCounter(metric *dto.Metric, act *metricsAction) { if act.logToFile { - glog.Infof("Label: %v, Value: %v ", metric.GetLabel(), metric.GetCounter().GetValue()) + log.Infof("Label: %v, Value: %v ", metric.GetLabel(), metric.GetCounter().GetValue()) } else { - glog.V(10).Info("processing COUNTER: ", metric.GetCounter().GetValue()) + log.Infof("processing : ", zap.Float64("COUNTER", metric.GetCounter().GetValue())) } act.actionFunc(&act.data.curSingleDataPoint, metric.GetCounter().GetValue()) } @@ -117,7 +121,7 @@ func processCounter(metric *dto.Metric, act *metricsAction) { func processPercentile(metric *dto.Metric, act *metricsAction) { var p99 float64 - glog.V(10).Info("processing PERCENTILE: ", p99) + log.Infof("processing: ", zap.Float64("PERCENTILE", p99)) summary := metric.GetSummary() quantiles := summary.GetQuantile() @@ -130,19 +134,19 @@ func processPercentile(metric *dto.Metric, act *metricsAction) { } func processHistogram(metric *dto.Metric, act *metricsAction) { - glog.V(5).Info("processing HISTOGRAM:", metric.GetLabel()) - glog.V(5).Info(metric.GetHistogram()) + log.Infof("processing:", zap.Any("HISTOGRAM", metric.GetLabel())) + log.Infof("processing:", zap.Any("GETHISTOGRAM", metric.GetHistogram())) histogram := metric.GetHistogram() for _, bucket := range histogram.GetBucket() { - glog.V(10).Info("processing bucket:", bucket) + log.Infof("processing:", zap.Any("bucket", bucket)) existingBucket := false for _, bucketInAct := range act.bucket.curBucket { if bucket.GetUpperBound() == *bucketInAct.UpperBound { // found the matching bucket - glog.V(10).Infof("Found the matching bucket with UpperBound: %f", *bucketInAct.UpperBound) + log.Infof("Found the matching bucket with UpperBound: %f", *bucketInAct.UpperBound) act.actionFunc(bucketInAct.CumulativeCount, float64(bucket.GetCumulativeCount())) - glog.V(10).Infof("Found: *bucketInAct.CumulativeCount:%f, bucket.GetCumulativeCount():%f", + log.Infof("Found: *bucketInAct.CumulativeCount:%f, bucket.GetCumulativeCount():%f", *bucketInAct.CumulativeCount, float64(bucket.GetCumulativeCount())) existingBucket = true break @@ -150,7 +154,7 @@ func processHistogram(metric *dto.Metric, act *metricsAction) { } if !existingBucket { - glog.V(10).Infof("Create a new bucket with upperBound:%f", bucket.GetUpperBound()) + log.Infof("Create a new bucket with upperBound:%f", bucket.GetUpperBound()) upperBound := new(float64) *upperBound = float64(bucket.GetUpperBound()) cumulativeCount := new(float64) @@ -186,7 +190,7 @@ func postProcessingCounter(convert metricsConvert) bool { } if resetDetected || (noPreviousDataPoint && !noCurrentDataPoint) { - glog.Infof("Reset detected resetDetected: %v, noPreviousDataPoint: %v, noCurrentDataPoint: %v", + log.Infof("Reset detected resetDetected: %v, noPreviousDataPoint: %v, noCurrentDataPoint: %v", resetDetected, noPreviousDataPoint, noCurrentDataPoint) } return resetDetected || (noPreviousDataPoint && !noCurrentDataPoint) @@ -199,28 +203,28 @@ func postProcessingHistogram(convert metricsConvert) bool { for _, action := range convert.actions { numOfBuckets := len(action.bucket.curBucket) if numOfBuckets == 0 { - glog.Info("Post Histogram Processing: no bucket found") + log.Info("Post Histogram Processing: no bucket found") continue } for i := 1; i < numOfBuckets; i++ { - glog.V(10).Infof("Found numOfBuckets-i:=%d, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount=%f", + log.Infof("Found numOfBuckets-i:=%d, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount=%f", numOfBuckets-i, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount) // Delta against the previous bucket value // e.g. diff between bucket LE250000 and previous bucket LE125000 *action.bucket.curBucket[numOfBuckets-i].CumulativeCount -= *action.bucket.curBucket[numOfBuckets-i-1].CumulativeCount - glog.V(10).Infof("Found numOfBuckets-i:=%d, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount=%f, *action.bucket.curBucket[numOfBuckets-i-1].CumulativeCount=%f", + log.Infof("Found numOfBuckets-i:=%d, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount=%f, *action.bucket.curBucket[numOfBuckets-i-1].CumulativeCount=%f", numOfBuckets-i, *action.bucket.curBucket[numOfBuckets-i].CumulativeCount, *action.bucket.curBucket[numOfBuckets-i-1].CumulativeCount) // Delta against the previous value if action.bucket.lastBucket != nil { - glog.V(10).Infof("Found *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f", + log.Infof("Found *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f", *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount) currentTotal := *action.bucket.curBucket[numOfBuckets-i].CumulativeCount // Only do delta if there is no restart for metric target if *action.bucket.curBucket[numOfBuckets-i].CumulativeCount >= *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount { *action.bucket.curBucket[numOfBuckets-i].CumulativeCount -= *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount - glog.V(10).Infof("Found *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f, *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f", + log.Infof("Found *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f, *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount=%f", *action.bucket.curBucket[numOfBuckets-i].CumulativeCount, *action.bucket.lastBucket[numOfBuckets-i].CumulativeCount) } else { resetDetected = true @@ -250,7 +254,7 @@ func postProcessingHistogram(convert metricsConvert) bool { } func processMetric(family *dto.MetricFamily, convert metricsConvert) (bool, error) { - glog.Info("Processing metric: ", family.GetName()) + log.Infof("Processing: ", zap.String("metric", family.GetName())) resetDetected := false mType := family.GetType() @@ -301,7 +305,7 @@ func produceHistogram(act metricsAction, cw publisher.Publisher) { prevUpperBound = *bucket.UpperBound if *bucket.CumulativeCount != 0 { - glog.Infof("Produce HISTOGRAM metrics: %s, max:%f, min:%f, count: %f, sum: %f", + log.Infof("Produce HISTOGRAM metrics: %s, max:%f, min:%f, count: %f, sum: %f", act.cwMetricName, mid, mid, *bucket.CumulativeCount, mid*float64(*bucket.CumulativeCount)) dataPoint := &cloudwatch.MetricDatum{ MetricName: aws.String(act.cwMetricName), @@ -337,7 +341,7 @@ func produceCloudWatchMetrics(t metricsTarget, families map[string]*dto.MetricFa for _, action := range convertMetrics.actions { switch mType { case dto.MetricType_COUNTER: - glog.Infof("Produce COUNTER metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) + log.Infof("Produce COUNTER metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) if t.submitCloudWatch() { dataPoint := &cloudwatch.MetricDatum{ MetricName: aws.String(action.cwMetricName), @@ -347,7 +351,7 @@ func produceCloudWatchMetrics(t metricsTarget, families map[string]*dto.MetricFa cw.Publish(dataPoint) } case dto.MetricType_GAUGE: - glog.Infof("Produce GAUGE metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) + log.Infof("Produce GAUGE metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) if t.submitCloudWatch() { dataPoint := &cloudwatch.MetricDatum{ MetricName: aws.String(action.cwMetricName), @@ -357,7 +361,7 @@ func produceCloudWatchMetrics(t metricsTarget, families map[string]*dto.MetricFa cw.Publish(dataPoint) } case dto.MetricType_SUMMARY: - glog.Infof("Produce PERCENTILE metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) + log.Infof("Produce PERCENTILE metrics: %s, value: %f", action.cwMetricName, action.data.curSingleDataPoint) if t.submitCloudWatch() { dataPoint := &cloudwatch.MetricDatum{ MetricName: aws.String(action.cwMetricName), @@ -397,13 +401,13 @@ func metricsListGrabAggregateConvert(t metricsTarget) (map[string]*dto.MetricFam resetMetrics(interestingMetrics) targetList := t.getTargetList() - glog.Info("targetList: ", targetList) - glog.Info("len(targetList)", len(targetList)) + log.Infof("targetList: %v ", targetList) + log.Infof("len(targetList) %d", len(targetList)) for _, target := range targetList { - glog.Infof("Grab/Aggregate metrics from %v", target) + log.Infof("Grab/Aggregate metrics from %v", target) rawOutput, err := t.grabMetricsFromTarget(target) if err != nil { - glog.Errorf("Failed to getMetricsFromTarget: %v", err) + log.Errorf("Failed to getMetricsFromTarget: %v", err) // it may take times to remove some metric targets continue } @@ -412,13 +416,13 @@ func metricsListGrabAggregateConvert(t metricsTarget) (map[string]*dto.MetricFam origFamilies, err := parser.TextToMetricFamilies(bytes.NewReader(rawOutput)) if err != nil { - glog.Warning("Failed to parse metrics:", err) + log.Warnf("Failed to parse metrics:", zap.Error(err)) return nil, nil, true, err } families, err = filterMetrics(origFamilies, interestingMetrics) if err != nil { - glog.Warning("Failed to filter metrics:", err) + log.Warnf("Failed to filter metrics:", zap.Error(err)) return nil, nil, true, err } @@ -447,7 +451,7 @@ func Handler(t metricsTarget) { families, interestingMetrics, resetDetected, err := metricsListGrabAggregateConvert(t) if err != nil || resetDetected { - glog.Info("Skipping 1st poll after reset, error:", err) + log.Infof("Skipping 1st poll after reset, error: %v", err) } cw := t.getCWMetricsPublisher() diff --git a/cmd/grpc-health-probe/main.go b/cmd/grpc-health-probe/main.go index c0e45ba4398..3401c66bd58 100644 --- a/cmd/grpc-health-probe/main.go +++ b/cmd/grpc-health-probe/main.go @@ -3,11 +3,12 @@ package main import ( "context" "flag" - "log" "os" "os/signal" "time" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" + "google.golang.org/grpc" "google.golang.org/grpc/codes" healthpb "google.golang.org/grpc/health/grpc_health_v1" @@ -23,6 +24,8 @@ var ( verbose bool ) +var log = logger.InitZapLogger("grpc-health-probe") + const ( // StatusInvalidArguments indicates specified invalid arguments. StatusInvalidArguments = 1 @@ -35,10 +38,9 @@ const ( ) func init() { - log.SetFlags(0) flag.StringVar(&remoteURL, "addr", "", "(required) tcp host:port to connect") flag.StringVar(&serviceName, "service", "", "service name to check (default: \"\")") - flag.StringVar(&userAgent, "user-agent", "grpc-health-probe", "user-agent header value of health check requests") + flag.StringVar(&userAgent, "user-agent", "grpc_health_probe", "user-agent header value of health check requests") // timeouts flag.DurationVar(&connTimeoutDur, "connect-timeout", connTimeoutDur, "timeout for establishing connection") flag.DurationVar(&rpcTimeoutDur, "rpc-timeout", rpcTimeoutDur, "timeout for health check rpc") @@ -48,7 +50,7 @@ func init() { flag.Parse() argError := func(s string, v ...interface{}) { - log.Printf("error: "+s, v...) + log.Infof("error: "+s, v...) os.Exit(StatusInvalidArguments) } @@ -63,8 +65,8 @@ func init() { argError("--rpc-timeout must be greater than zero (specified: %v)", rpcTimeoutDur) } if verbose { - log.Printf("parsed options:") - log.Printf("> remoteUrl=%s conn-timeout=%v rpc-timeout=%v", remoteURL, connTimeoutDur, rpcTimeoutDur) + log.Info("parsed options:") + log.Infof("> remoteUrl=%s conn-timeout=%v rpc-timeout=%v", remoteURL, connTimeoutDur, rpcTimeoutDur) } } @@ -76,7 +78,7 @@ func main() { go func() { sig := <-c if sig == os.Interrupt { - log.Printf("cancellation received") + log.Infof("cancellation received") cancel() return } @@ -89,7 +91,7 @@ func main() { opts = append(opts, grpc.WithInsecure()) if verbose { - log.Print("establishing connection") + log.Info("establishing connection") } connStart := time.Now() dialCtx, cancel2 := context.WithTimeout(ctx, connTimeoutDur) @@ -97,41 +99,41 @@ func main() { conn, err := grpc.DialContext(dialCtx, remoteURL, opts...) if err != nil { if err == context.DeadlineExceeded { - log.Printf("timeout: failed to connect service %q within %v", remoteURL, connTimeoutDur) + log.Infof("timeout: failed to connect service %q within %v", remoteURL, connTimeoutDur) } else { - log.Printf("error: failed to connect service at %q: %+v", remoteURL, err) + log.Infof("error: failed to connect service at %q: %+v", remoteURL, err) } os.Exit(StatusConnectionFailure) } connDuration := time.Since(connStart) defer conn.Close() if verbose { - log.Printf("connection establisted (took %v)", connDuration) + log.Infof("connection established (took %v)", connDuration) } rpcStart := time.Now() rpcCtx, rpcCancel := context.WithTimeout(ctx, rpcTimeoutDur) defer rpcCancel() resp, err := healthpb.NewHealthClient(conn).Check(rpcCtx, &healthpb.HealthCheckRequest{Service: serviceName}) - log.Print(resp) + log.Infof("response %q", resp) if err != nil { if stat, ok := status.FromError(err); ok && stat.Code() == codes.Unimplemented { - log.Printf("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)") + log.Infof("error: this server does not implement the grpc health protocol (grpc.health.v1.Health)") } else if stat, ok := status.FromError(err); ok && stat.Code() == codes.DeadlineExceeded { - log.Printf("timeout: health rpc did not complete within %v", rpcTimeoutDur) + log.Infof("timeout: health rpc did not complete within %v", rpcTimeoutDur) } else { - log.Printf("error: health rpc failed: %+v", err) + log.Infof("error: health rpc failed: %+v", err) } os.Exit(StatusRPCFailure) } rpcDuration := time.Since(rpcStart) if resp.GetStatus() != healthpb.HealthCheckResponse_SERVING { - log.Printf("service unhealthy (responded with %q)", resp.GetStatus().String()) + log.Infof("service unhealthy (responded with %q)", resp.GetStatus().String()) os.Exit(StatusUnhealthy) } if verbose { - log.Printf("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration) + log.Infof("time elapsed: connect=%v rpc=%v", connDuration, rpcDuration) } - log.Printf("status: %v", resp.GetStatus().String()) + log.Infof("status: %v", resp.GetStatus().String()) } diff --git a/cmd/routed-eni-cni-plugin/cni.go b/cmd/routed-eni-cni-plugin/cni.go index 6df592236a8..682b2777b5b 100644 --- a/cmd/routed-eni-cni-plugin/cni.go +++ b/cmd/routed-eni-cni-plugin/cni.go @@ -23,7 +23,6 @@ import ( "runtime" "strings" - log "github.com/cihub/seelog" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/types/current" @@ -43,12 +42,12 @@ import ( ) const ( - ipamDAddress = "localhost:50051" - defaultLogFilePath = "/var/log/aws-routed-eni/plugin.log" + ipamDAddress = "localhost:50051" ) var ( version string + log = logger.InitZapLogger("Plugin") ) // NetConf stores the common network config for the CNI plugin @@ -298,10 +297,10 @@ func del(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap return errors.New("del cmd: failed to process delete request") } - deletedPodIp := net.ParseIP(r.IPv4Addr) - if deletedPodIp != nil { + deletedPodIP := net.ParseIP(r.IPv4Addr) + if deletedPodIP != nil { addr := &net.IPNet{ - IP: deletedPodIp, + IP: deletedPodIP, Mask: net.IPv4Mask(255, 255, 255, 255), } err = driverClient.TeardownNS(addr, int(r.DeviceNumber)) @@ -318,19 +317,15 @@ func del(args *skel.CmdArgs, cniTypes typeswrapper.CNITYPES, grpcClient grpcwrap } func main() { - logger.SetupLogger(logger.GetLogFileLocation(defaultLogFilePath)) - log.Infof("Starting CNI Plugin %s ...", version) exitCode := 0 if e := skel.PluginMainWithError(cmdAdd, cmdDel, cniSpecVersion.All); e != nil { exitCode = 1 - log.Error("Failed CNI request: ", e) + log.Errorf("Failed CNI request: %v", e) if err := e.Print(); err != nil { log.Errorf("Error writing error JSON to stdout: %v", err) } } - - log.Flush() os.Exit(exitCode) } diff --git a/cmd/routed-eni-cni-plugin/driver/driver.go b/cmd/routed-eni-cni-plugin/driver/driver.go index 0f811a7d2e2..502d4c0be9c 100644 --- a/cmd/routed-eni-cni-plugin/driver/driver.go +++ b/cmd/routed-eni-cni-plugin/driver/driver.go @@ -23,12 +23,11 @@ import ( "github.com/containernetworking/cni/pkg/ns" "github.com/vishvananda/netlink" - log "github.com/cihub/seelog" - "github.com/aws/amazon-vpc-cni-k8s/pkg/ipwrapper" "github.com/aws/amazon-vpc-cni-k8s/pkg/netlinkwrapper" "github.com/aws/amazon-vpc-cni-k8s/pkg/networkutils" "github.com/aws/amazon-vpc-cni-k8s/pkg/nswrapper" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" ) const ( @@ -40,6 +39,8 @@ const ( mainRouteTable = unix.RT_TABLE_MAIN ) +var log = logger.GetZapLogger() + // NetworkAPIs defines network API calls type NetworkAPIs interface { SetupNS(hostVethName string, contVethName string, netnsPath string, addr *net.IPNet, table int, vpcCIDRs []string, useExternalSNAT bool, mtu int) error @@ -243,7 +244,7 @@ func setupNS(hostVethName string, contVethName string, netnsPath string, addr *n err = netLink.RuleAdd(podRule) if isRuleExistsError(err) { - log.Warn("Rule already exists [%v]", podRule) + log.Warnf("Rule already exists [%v]", podRule) } else { if err != nil { log.Errorf("Failed to add pod IP rule [%v]: %v", podRule, err) diff --git a/go.mod b/go.mod index 51062ed3844..61e0bc19f49 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/aws/amazon-vpc-cni-k8s go 1.13 require ( + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect github.com/aws/aws-sdk-go v1.26.8 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect github.com/cihub/seelog v0.0.0-20151216151435-d2c6e5aa9fbf @@ -33,14 +35,17 @@ require ( github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 // indirect github.com/sirupsen/logrus v1.4.1 // indirect github.com/spf13/pflag v1.0.2 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 github.com/vishvananda/netlink v1.1.0 + go.uber.org/zap v1.13.0 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect google.golang.org/grpc v1.23.1 + gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 k8s.io/api v0.0.0-20180712090710-2d6f90ab1293 k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d k8s.io/client-go v0.0.0-20180806134042-1f13a808da65 diff --git a/go.sum b/go.sum index 887b3bcac87..0fafe815770 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/aws/aws-sdk-go v1.26.8 h1:W+MPuCFLSO/itZkZ5GFOui0YC1j3lZ507/m5DFPtzE4= github.com/aws/aws-sdk-go v1.26.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= @@ -46,6 +50,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -66,6 +71,9 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -99,6 +107,7 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrO github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -111,18 +120,30 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -132,6 +153,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -165,6 +187,10 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= @@ -174,18 +200,27 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.0.0-20180712090710-2d6f90ab1293 h1:hROmpFC7JMobXFXMmD7ZKZLhDKvr1IKfFJoYS/45G/8= k8s.io/api v0.0.0-20180712090710-2d6f90ab1293/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/apimachinery v0.0.0-20180621070125-103fd098999d h1:MZjlsu9igBoVPZkXpIGoxI6EonqNsXXZU7hhvfQLkd4= diff --git a/pkg/awsutils/awsutils.go b/pkg/awsutils/awsutils.go index bd47fc9655c..027bb640ca6 100644 --- a/pkg/awsutils/awsutils.go +++ b/pkg/awsutils/awsutils.go @@ -25,7 +25,7 @@ import ( "github.com/pkg/errors" - log "github.com/cihub/seelog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/prometheus/client_golang/prometheus" "github.com/aws/amazon-vpc-cni-k8s/pkg/ec2metadata" @@ -76,6 +76,8 @@ const ( // ErrENINotFound is an error when ENI is not found. var ErrENINotFound = errors.New("ENI is not found") +var log = logger.GetZapLogger() + var ( awsAPILatency = prometheus.NewSummaryVec( prometheus.SummaryOpts{ @@ -738,7 +740,8 @@ func (cache *EC2InstanceMetadataCache) tagENI(eniID string, maxBackoffDelay time awsAPILatency.WithLabelValues("CreateTags", fmt.Sprint(err != nil)).Observe(msSince(start)) if err != nil { awsAPIErrInc("CreateTags", err) - return log.Warnf("Failed to tag the newly created ENI %s: %v", eniID, err) + log.Warnf("Failed to tag the newly created ENI %s:", eniID) + return err } log.Debugf("Successfully tagged ENI: %s", eniID) return nil diff --git a/pkg/cri/cri.go b/pkg/cri/cri.go index 78546358980..47685822416 100644 --- a/pkg/cri/cri.go +++ b/pkg/cri/cri.go @@ -5,10 +5,9 @@ import ( "errors" "os" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "google.golang.org/grpc" runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" - - log "github.com/cihub/seelog" ) const ( @@ -16,6 +15,8 @@ const ( dockerSocketPath = "unix:///var/run/dockershim.sock" ) +var log = logger.GetZapLogger() + // SandboxInfo provides container information type SandboxInfo struct { ID string @@ -34,6 +35,7 @@ func New() *Client { return &Client{} } +//GetRunningPodSandboxes get running sandboxIDs func (c *Client) GetRunningPodSandboxes() (map[string]*SandboxInfo, error) { socketPath := dockerSocketPath if info, err := os.Stat("/var/run/cri.sock"); err == nil && !info.IsDir() { diff --git a/pkg/ec2wrapper/ec2wrapper.go b/pkg/ec2wrapper/ec2wrapper.go index 684cbfd62fd..bd6eb6b93a8 100644 --- a/pkg/ec2wrapper/ec2wrapper.go +++ b/pkg/ec2wrapper/ec2wrapper.go @@ -1,15 +1,14 @@ -// package ec2wrapper is used to wrap around the ec2 service APIs +//Package ec2wrapper is used to wrap around the ec2 service APIs package ec2wrapper import ( "github.com/aws/amazon-vpc-cni-k8s/pkg/ec2metadatawrapper" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2/ec2iface" - "github.com/golang/glog" - "github.com/pkg/errors" ) @@ -20,6 +19,8 @@ const ( clusterIDTag = "CLUSTER_ID" ) +var log = logger.GetZapLogger() + // EC2Wrapper is used to wrap around EC2 service APIs to obtain ClusterID from // the ec2 instance tags type EC2Wrapper struct { @@ -27,7 +28,7 @@ type EC2Wrapper struct { instanceIdentityDocument ec2metadata.EC2InstanceIdentityDocument } -// New returns an instance of the EC2 wrapper +//NewMetricsClient returns an instance of the EC2 wrapper func NewMetricsClient() (*EC2Wrapper, error) { metricsSession := session.Must(session.NewSession()) ec2MetadataClient := ec2metadatawrapper.New(nil) @@ -63,7 +64,7 @@ func (e *EC2Wrapper) GetClusterTag(tagKey string) (string, error) { }, } - glog.Info("Calling DescribeTags with key ", tagKey) + log.Infof("Calling DescribeTags with key %s", tagKey) results, err := e.ec2ServiceClient.DescribeTags(&input) if err != nil { return "", errors.Wrap(err, "GetClusterTag: Unable to obtain EC2 instance tags") diff --git a/pkg/eniconfig/eniconfig.go b/pkg/eniconfig/eniconfig.go index 4b0a34204aa..dc8c4863b95 100644 --- a/pkg/eniconfig/eniconfig.go +++ b/pkg/eniconfig/eniconfig.go @@ -25,8 +25,7 @@ import ( "github.com/pkg/errors" "github.com/aws/amazon-vpc-cni-k8s/pkg/apis/crd/v1alpha1" - - log "github.com/cihub/seelog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" sdkVersion "github.com/operator-framework/operator-sdk/version" corev1 "k8s.io/api/core/v1" ) @@ -54,6 +53,9 @@ type ENIConfig interface { var ErrNoENIConfig = errors.New("eniconfig: eniconfig is not available") +//log zaplogger +var log = logger.GetZapLogger() + // ENIConfigController defines global context for ENIConfig controller type ENIConfigController struct { eni map[string]*v1alpha1.ENIConfigSpec diff --git a/pkg/ipamd/datastore/data_store.go b/pkg/ipamd/datastore/data_store.go index 008ed29e27b..307b9787438 100644 --- a/pkg/ipamd/datastore/data_store.go +++ b/pkg/ipamd/datastore/data_store.go @@ -18,11 +18,10 @@ import ( "sync" "time" - log "github.com/cihub/seelog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/k8sapi" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" - - "github.com/aws/amazon-vpc-cni-k8s/pkg/k8sapi" ) const ( @@ -60,6 +59,8 @@ var ErrUnknownPod = errors.New("datastore: unknown pod") // ErrUnknownPodIP is an error where pod's IP address is not found in data store var ErrUnknownPodIP = errors.New("datastore: pod using unknown IP address") +var log = logger.GetZapLogger() + var ( enis = prometheus.NewGauge( prometheus.GaugeOpts{ @@ -179,7 +180,7 @@ func (ds *DataStore) AddENI(eniID string, deviceNumber int, isPrimary bool) erro ds.lock.Lock() defer ds.lock.Unlock() - log.Debug("DataStore Add an ENI ", eniID) + log.Debugf("DataStore Add an ENI %s", eniID) _, ok := ds.eniIPPools[eniID] if ok { @@ -200,8 +201,8 @@ func (ds *DataStore) AddIPv4AddressToStore(eniID string, ipv4 string) error { ds.lock.Lock() defer ds.lock.Unlock() - log.Tracef("Adding ENI(%s)'s IPv4 address %s to datastore", eniID, ipv4) - log.Tracef("IP Address Pool stats: total: %d, assigned: %d", ds.total, ds.assigned) + log.Infof("Adding ENI(%s)'s IPv4 address %s to datastore", eniID, ipv4) + log.Infof("IP Address Pool stats: total: %d, assigned: %d", ds.total, ds.assigned) curENI, ok := ds.eniIPPools[eniID] if !ok { diff --git a/pkg/ipamd/introspect.go b/pkg/ipamd/introspect.go index 0571cbf8f9e..d693c8c5668 100644 --- a/pkg/ipamd/introspect.go +++ b/pkg/ipamd/introspect.go @@ -23,8 +23,6 @@ import ( "sync" "time" - log "github.com/cihub/seelog" - "github.com/aws/amazon-vpc-cni-k8s/pkg/networkutils" "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/retry" ) @@ -80,7 +78,7 @@ func (c *IPAMContext) ServeIntrospection() { } once.Do(func() { - log.Error("Error running http API: ", err) + log.Errorf("Error running http API: %v", err) }) return err }) @@ -125,7 +123,7 @@ func (c *IPAMContext) setupIntrospectionServer() *http.Server { addr = defaultIntrospectionBindAddress } - log.Info("Serving introspection endpoints on ", addr) + log.Infof("Serving introspection endpoints on %s", addr) server := &http.Server{ Addr: addr, diff --git a/pkg/ipamd/ipamd.go b/pkg/ipamd/ipamd.go index 1aca12d6c02..2906ffb22f3 100644 --- a/pkg/ipamd/ipamd.go +++ b/pkg/ipamd/ipamd.go @@ -23,9 +23,9 @@ import ( "sync/atomic" "time" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - log "github.com/cihub/seelog" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "k8s.io/apimachinery/pkg/util/sets" @@ -111,6 +111,8 @@ const ( eniNoManageTagKey = "node.k8s.amazonaws.com/no_manage" ) +var log = logger.GetZapLogger() + var ( ipamdErr = prometheus.NewCounterVec( prometheus.CounterOpts{ @@ -302,14 +304,14 @@ func (c *IPAMContext) nodeInit() error { _, vpcCIDR, err := net.ParseCIDR(c.awsClient.GetVPCIPv4CIDR()) if err != nil { - log.Error("Failed to parse VPC IPv4 CIDR", err.Error()) + log.Errorf("Failed to parse VPC IPv4 CIDR %v", err.Error()) return errors.Wrap(err, "ipamd init: failed to retrieve VPC CIDR") } primaryIP := net.ParseIP(c.awsClient.GetLocalIPv4()) err = c.networkClient.SetupHostNetwork(vpcCIDR, vpcCIDRs, c.awsClient.GetPrimaryENImac(), &primaryIP) if err != nil { - log.Error("Failed to set up host network", err) + log.Errorf("Failed to set up host network %v", err) return errors.Wrap(err, "ipamd init: failed to set up host network") } @@ -882,9 +884,9 @@ func (c *IPAMContext) nodeIPPoolTooLow() bool { available := total - used poolTooLow := available < c.maxIPsPerENI*c.warmENITarget || (c.warmENITarget == 0 && available == 0) if poolTooLow { - log.Tracef("IP pool is too low: available (%d) < ENI target (%d) * addrsPerENI (%d)", available, c.warmENITarget, c.maxIPsPerENI) + log.Debugf("IP pool is too low: available (%d) < ENI target (%d) * addrsPerENI (%d)", available, c.warmENITarget, c.maxIPsPerENI) } else { - log.Tracef("IP pool is NOT too low: available (%d) >= ENI target (%d) * addrsPerENI (%d)", available, c.warmENITarget, c.maxIPsPerENI) + log.Debugf("IP pool is NOT too low: available (%d) >= ENI target (%d) * addrsPerENI (%d)", available, c.warmENITarget, c.maxIPsPerENI) } return poolTooLow } @@ -915,9 +917,9 @@ func (c *IPAMContext) shouldRemoveExtraENIs() bool { // We need the +1 to make sure we are not going below the WARM_ENI_TARGET. shouldRemoveExtra := available >= (c.warmENITarget+1)*c.maxIPsPerENI if shouldRemoveExtra { - log.Tracef("It might be possible to remove extra ENIs because available (%d) >= (ENI target (%d) + 1) * addrsPerENI (%d): ", available, c.warmENITarget, c.maxIPsPerENI) + log.Infof("It might be possible to remove extra ENIs because available (%d) >= (ENI target (%d) + 1) * addrsPerENI (%d): ", available, c.warmENITarget, c.maxIPsPerENI) } else { - log.Tracef("Its NOT possible to remove extra ENIs because available (%d) < (ENI target (%d) + 1) * addrsPerENI (%d): ", available, c.warmENITarget, c.maxIPsPerENI) + log.Infof("Its NOT possible to remove extra ENIs because available (%d) < (ENI target (%d) + 1) * addrsPerENI (%d): ", available, c.warmENITarget, c.maxIPsPerENI) } return shouldRemoveExtra } @@ -1074,7 +1076,7 @@ func UseCustomNetworkCfg() bool { if err == nil { return parsedValue } - log.Error("Failed to parse "+envCustomNetworkCfg+"; using default: false", err.Error()) + log.Errorf("Failed to parse %s; using default: false, err: %v", envCustomNetworkCfg, err) } return false } @@ -1148,7 +1150,7 @@ func (c *IPAMContext) ipTargetState() (short int, over int, enabled bool) { // over is less than the warm IP target alone if it would imply reducing total IPs below the minimum target over = max(min(over, total-c.minimumIPTarget), 0) - log.Tracef("Current warm IP stats: target: %d, total: %d, assigned: %d, available: %d, short: %d, over %d", c.warmIPTarget, total, assigned, available, short, over) + log.Infof("Current warm IP stats: target: %d, total: %d, assigned: %d, available: %d, short: %d, over %d", c.warmIPTarget, total, assigned, available, short, over) return short, over, true } diff --git a/pkg/ipamd/metrics.go b/pkg/ipamd/metrics.go index d8b80b6964f..cba9a7b9e69 100644 --- a/pkg/ipamd/metrics.go +++ b/pkg/ipamd/metrics.go @@ -20,7 +20,6 @@ import ( "time" "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/retry" - log "github.com/cihub/seelog" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -39,14 +38,14 @@ func (c *IPAMContext) ServeMetrics() { return } - log.Info("Serving metrics on port ", metricsPort) + log.Infof("Serving metrics on port %d", metricsPort) server := c.setupMetricsServer() for { once := sync.Once{} _ = retry.RetryWithBackoff(retry.NewSimpleBackoff(time.Second, time.Minute, 0.2, 2), func() error { err := server.ListenAndServe() once.Do(func() { - log.Error("Error running http API: ", err) + log.Errorf("Error running http API: %v", err) }) return err }) diff --git a/pkg/ipamd/rpc_handler.go b/pkg/ipamd/rpc_handler.go index 1869148021f..79d86651f0e 100644 --- a/pkg/ipamd/rpc_handler.go +++ b/pkg/ipamd/rpc_handler.go @@ -19,7 +19,6 @@ import ( "os/signal" "syscall" - log "github.com/cihub/seelog" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" @@ -103,7 +102,7 @@ func (s *server) DelNetwork(ctx context.Context, in *pb.DelNetworkRequest) (*pb. // RunRPCHandler handles request from gRPC func (c *IPAMContext) RunRPCHandler() error { - log.Info("Serving RPC Handler on ", ipamdgRPCaddress) + log.Infof("Serving RPC Handler on %s", ipamdgRPCaddress) lis, err := net.Listen("tcp", ipamdgRPCaddress) if err != nil { diff --git a/pkg/k8sapi/discovery.go b/pkg/k8sapi/discovery.go index 9b19a5b5680..82c51746fcd 100644 --- a/pkg/k8sapi/discovery.go +++ b/pkg/k8sapi/discovery.go @@ -10,7 +10,7 @@ import ( "github.com/pkg/errors" - log "github.com/cihub/seelog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" clientset "k8s.io/client-go/kubernetes" @@ -54,6 +54,8 @@ type K8SPodInfo struct { UID string } +var log = logger.GetZapLogger() + // ErrInformerNotSynced indicates that it has not synced with API server yet var ErrInformerNotSynced = errors.New("discovery: informer not synced") @@ -113,7 +115,7 @@ func (d *Controller) GetCNIPods() []string { cniPods = append(cniPods, k) } - log.Info("GetCNIPods discovered", cniPods) + log.Infof("GetCNIPods discovered %v", cniPods) return cniPods } @@ -256,7 +258,7 @@ func (d *Controller) handlePodUpdate(key string) error { d.workerPodsLock.Lock() defer d.workerPodsLock.Unlock() - log.Tracef("Update for pod %s: %+v, %+v", podName, pod.Status, pod.Spec) + log.Debugf("Update for pod %s: %+v, %+v", podName, pod.Status, pod.Spec) // Save pod info d.workerPods[key] = &K8SPodInfo{ diff --git a/pkg/networkutils/network.go b/pkg/networkutils/network.go index 87285b45662..17b4a2338da 100644 --- a/pkg/networkutils/network.go +++ b/pkg/networkutils/network.go @@ -625,11 +625,11 @@ func getConnmark() uint32 { if connmark := os.Getenv(envConnmark); connmark != "" { mark, err := strconv.ParseInt(connmark, 0, 64) if err != nil { - log.Error("Failed to parse "+envConnmark+"; will use ", defaultConnmark, err.Error()) + log.Errorf("Failed to parse %s; will use %d, error: %v", envConnmark, defaultConnmark, err) return defaultConnmark } if mark > math.MaxUint32 || mark <= 0 { - log.Error(""+envConnmark+" out of range; will use ", defaultConnmark) + log.Errorf("%s out of range; will use %s", envConnmark, defaultConnmark) return defaultConnmark } return uint32(mark) diff --git a/pkg/publisher/publisher.go b/pkg/publisher/publisher.go index ac277cdbe49..33e98ecee99 100644 --- a/pkg/publisher/publisher.go +++ b/pkg/publisher/publisher.go @@ -26,7 +26,7 @@ import ( "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface" - "github.com/golang/glog" + "github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger" "github.com/pkg/errors" ) @@ -50,6 +50,8 @@ const ( maxDataPoints = 20 ) +var log = logger.GetZapLogger() + // Publisher defines the interface to publish one or more data points type Publisher interface { // Publish publishes one or more metric data points @@ -86,14 +88,14 @@ func New(ctx context.Context) (Publisher, error) { } clusterID, err := ec2Client.GetClusterTag("CLUSTER_ID") if err != nil || clusterID == "" { - glog.Errorf("Failed to obtain cluster-id, fetching name. %v", err) + log.Errorf("Failed to obtain cluster-id, fetching name. %v", err) clusterID, err = ec2Client.GetClusterTag("Name") if err != nil || clusterID == "" { - glog.Errorf("Failed to obtain cluster-id or name, defaulting to 'k8s-cluster'. %v", err) + log.Errorf("Failed to obtain cluster-id or name, defaulting to 'k8s-cluster'. %v", err) clusterID = "k8s-cluster" } } - glog.Info("Using cluster ID ", clusterID) + log.Infof("Using cluster ID %s", clusterID) // Get CloudWatch client ec2MetadataClient := ec2metadatawrapper.New(nil) @@ -118,20 +120,20 @@ func New(ctx context.Context) (Publisher, error) { // Start is used to setup the monitor loop func (p *cloudWatchPublisher) Start() { - glog.Info("Starting monitor loop for CloudWatch publisher") + log.Info("Starting monitor loop for CloudWatch publisher") p.monitor(defaultInterval) } // Stop is used to cancel the monitor loop func (p *cloudWatchPublisher) Stop() { - glog.Info("Stopping monitor loop for CloudWatch publisher") + log.Info("Stopping monitor loop for CloudWatch publisher") p.cancel() } // Publish is a variadic function to publish one or more metric data points func (p *cloudWatchPublisher) Publish(metricDataPoints ...*cloudwatch.MetricDatum) { // Fetch dimensions for override - glog.V(2).Info("Fetching CloudWatch dimensions") + log.Info("Fetching CloudWatch dimensions") dimensions := p.getCloudWatchMetricDatumDimensions() // Grab lock @@ -155,7 +157,7 @@ func (p *cloudWatchPublisher) pushLocal() { func (p *cloudWatchPublisher) push(metricData []*cloudwatch.MetricDatum) { if len(metricData) == 0 { - glog.Warning("Missing data for publishing CloudWatch metrics") + log.Warn("Missing data for publishing CloudWatch metrics") return } @@ -170,7 +172,7 @@ func (p *cloudWatchPublisher) push(metricData []*cloudwatch.MetricDatum) { // Publish data err := p.send(input) if err != nil { - glog.Errorf("Unable to publish CloudWatch metrics: %v", err) + log.Errorf("Unable to publish CloudWatch metrics: %v", err) } // Mutate slice @@ -184,7 +186,7 @@ func (p *cloudWatchPublisher) push(metricData []*cloudwatch.MetricDatum) { } func (p *cloudWatchPublisher) send(input cloudwatch.PutMetricDataInput) error { - glog.Info("Sending data to CloudWatch metrics") + log.Info("Sending data to CloudWatch metrics") _, err := p.cloudwatchClient.PutMetricData(&input) return err } diff --git a/pkg/utils/logger/logger.go b/pkg/utils/logger/logger.go index 03e1646e0a9..3cb065cd874 100644 --- a/pkg/utils/logger/logger.go +++ b/pkg/utils/logger/logger.go @@ -1,4 +1,4 @@ -// Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). You may // not use this file except in compliance with the License. A copy of the @@ -13,69 +13,114 @@ package logger -import ( - "fmt" - "os" - "strings" - - log "github.com/cihub/seelog" -) - const ( - envLogLevel = "AWS_VPC_K8S_CNI_LOGLEVEL" - envLogFilePath = "AWS_VPC_K8S_CNI_LOG_FILE" - // logConfigFormat defines the seelog format, with a rolling file - // writer. We cannot do this in code and have to resort to using - // LoggerFromConfigAsString as seelog doesn't have a usable public - // implementation of NewRollingFileWriterTime - logConfigFormat = ` - - - %s - - - - - -` + envLogLevel = "AWS_VPC_K8S_CNI_LOGLEVEL" + defaultIPamDLogFilePath = "/host/var/log/aws-routed-eni/ipamd.log" + envIPamDLogFilePath = "AWS_VPC_K8S_CNI_LOG_FILE" + defaultPluginLogFilePath = "/var/log/aws-routed-eni/plugin.log" + envPluginFilePath = "AWS_VPC_K8S_PLUGIN_LOGL_FILE" ) -// GetLogFileLocation returns the log file path -func GetLogFileLocation(defaultLogFilePath string) string { - logFilePath := os.Getenv(envLogFilePath) - if logFilePath == "" { - logFilePath = defaultLogFilePath - } - return logFilePath +//Log is global variable so that log functions can be directly accessed +var log Logger + +//Fields Type to pass when we want to call WithFields for structured logging +type Fields map[string]interface{} + +//Logger is our contract for the logger +type Logger interface { + Debugf(format string, args ...interface{}) + + Debug(format string) + + Infof(format string, args ...interface{}) + + Info(format string) + + Warnf(format string, args ...interface{}) + + Warn(format string) + + Errorf(format string, args ...interface{}) + + Error(format string) + + Fatalf(format string, args ...interface{}) + + Panicf(format string, args ...interface{}) + + WithFields(keyValues Fields) Logger } -// SetupLogger sets up a file logger -func SetupLogger(logFilePath string) { - logger, err := log.LoggerFromConfigAsString(fmt.Sprintf(logConfigFormat, getLogLevel(), getLogOutput(logFilePath))) - if err != nil { - fmt.Println("Error setting up logger: ", err) - return - } - err = log.ReplaceLogger(logger) - if err != nil { - fmt.Println("Error replacing logger: ", err) - return - } +//Debugf formats its arguments according to the format, analogous to fmt.Printf, +// and records the text as a log message at Debug level. +func Debugf(format string, args ...interface{}) { + log.Debugf(format, args...) } -func getLogLevel() string { - seelogLevel, ok := log.LogLevelFromString(strings.ToLower(os.Getenv(envLogLevel))) - if !ok { - seelogLevel = log.DebugLvl - } - return seelogLevel.String() +//Debug formats its arguments according to the format, analogous to fmt.Debug, +func Debug(format string) { + log.Debug(format) } -func getLogOutput(logFilePath string) string { - switch logFilePath { - case "stdout": - return `` - default: - return fmt.Sprintf(``, logFilePath) +// Infof is like Debugf, but at Info level. +func Infof(format string, args ...interface{}) { + log.Infof(format, args...) +} + +// Info is like Debugf, but at Info level. +func Info(format string) { + log.Info(format) +} + +// Warnf is like Debugf, but at Warning level. +func Warnf(format string, args ...interface{}) { + log.Warnf(format, args...) +} + +// Warn is like Debugf, but at Warning level. +func Warn(format string) { + log.Warn(format) +} + +// Errorf is like Debugf, but at Error level. +func Errorf(format string, args ...interface{}) { + log.Errorf(format, args...) +} + +// Error is like Debugf, but at Error level. +func Error(format string) { + log.Error(format) +} + +// Fatalf is like Debugf, but at Critical level and the logger then calls os.Exit(1). +func Fatalf(format string, args ...interface{}) { + log.Fatalf(format, args...) +} + +//Panicf is like Debugf, but at Panic level. +func Panicf(format string, args ...interface{}) { + log.Panicf(format, args...) +} + +//WithFields - If you want multiple fields +func WithFields(keyValues Fields) Logger { + return log.WithFields(keyValues) +} + +// GetZapLogger returns an instance of the logger, initializing a new logger +func GetZapLogger() Logger { + if log == nil { + log := defaultZapLogger() + return &structuredLogger{ + zapLogger: log, + } } + return log +} + +//InitZapLogger log name generated by srvName +func InitZapLogger(srvName string) Logger { + log = newZapLogger(srvName) + return log } diff --git a/pkg/utils/logger/logger_test.go b/pkg/utils/logger/logger_test.go index b01a3e21616..1315906d865 100644 --- a/pkg/utils/logger/logger_test.go +++ b/pkg/utils/logger/logger_test.go @@ -17,57 +17,66 @@ import ( "os" "testing" - log "github.com/cihub/seelog" "github.com/stretchr/testify/assert" + "go.uber.org/zap/zapcore" ) -func TestGetLogFileLocationReturnsOverriddenPath(t *testing.T) { - path := "/tmp/foo" - _ = os.Setenv(envLogFilePath, path) - defer os.Unsetenv(envLogFilePath) +func TestEnvIPamDLogFilePath(t *testing.T) { + srvName := "L-IPamD" + path := "/var/log/test.log" + _ = os.Setenv(envIPamDLogFilePath, path) + defer os.Unsetenv(envIPamDLogFilePath) - assert.Equal(t, path, GetLogFileLocation("/tmp/bar")) + assert.Equal(t, path, getLogFileLocation(srvName)) +} + +func TestEnvPluginFilePath(t *testing.T) { + srvName := "Plugin" + path := "/var/log/test.log" + _ = os.Setenv(envPluginFilePath, path) + defer os.Unsetenv(envIPamDLogFilePath) + + assert.Equal(t, path, getLogFileLocation(srvName)) } func TestGetLogFileLocationReturnsDefaultPath(t *testing.T) { - path := "/tmp/foo" - assert.Equal(t, path, GetLogFileLocation(path)) + srvName := "L-IPamD" + path := "/host/var/log/aws-routed-eni/ipamd.log" + assert.Equal(t, path, getLogFileLocation(srvName)) +} + +func TestGetLogFileLocationReturnsStdoutIfsrvNameDoesnotMatch(t *testing.T) { + srvName := "abcD" + path := "stdout" + assert.Equal(t, path, getLogFileLocation(srvName)) +} + +func TestGetLogFileLocationFailstoReturn(t *testing.T) { + srvName := "L-IPamD" + path := "/tmp/testing.log" + assert.NotEqual(t, path, getLogFileLocation(srvName)) } func TestLogLevelReturnsOverriddenLevel(t *testing.T) { _ = os.Setenv(envLogLevel, "INFO") defer os.Unsetenv(envLogLevel) - var expectedLogLevel log.LogLevel - expectedLogLevel = log.InfoLvl - assert.Equal(t, expectedLogLevel.String(), getLogLevel()) + var expectedLogLevel zapcore.Level + expectedLogLevel = zapcore.InfoLevel + assert.Equal(t, expectedLogLevel, getZapLevel(envLogLevel)) } func TestLogLevelReturnsDefaultLevelWhenEnvNotSet(t *testing.T) { - var expectedLogLevel log.LogLevel - expectedLogLevel = log.DebugLvl - assert.Equal(t, expectedLogLevel.String(), getLogLevel()) + var expectedLogLevel zapcore.Level + expectedLogLevel = zapcore.DebugLevel + assert.Equal(t, expectedLogLevel, getZapLevel(envLogLevel)) } func TestLogLevelReturnsDefaultLevelWhenEnvSetToInvalidValue(t *testing.T) { _ = os.Setenv(envLogLevel, "EVERYTHING") defer os.Unsetenv(envLogLevel) - var expectedLogLevel log.LogLevel - expectedLogLevel = log.DebugLvl - assert.Equal(t, expectedLogLevel.String(), getLogLevel()) -} - -func TestLogOutputReturnsFileWhenValueNotStdout(t *testing.T) { - path := "/tmp/foo" - - var expectedOutput = `` - assert.Equal(t, expectedOutput, getLogOutput(path)) -} - -func TestLogOutputReturnsConsole(t *testing.T) { - path := "stdout" - - var expectedOutput = `` - assert.Equal(t, expectedOutput, getLogOutput(path)) + var expectedLogLevel zapcore.Level + expectedLogLevel = zapcore.DebugLevel + assert.Equal(t, expectedLogLevel, getZapLevel(envLogLevel)) } diff --git a/pkg/utils/logger/zaplogger.go b/pkg/utils/logger/zaplogger.go new file mode 100644 index 00000000000..0c50a242b9d --- /dev/null +++ b/pkg/utils/logger/zaplogger.go @@ -0,0 +1,174 @@ +// Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may +// not use this file except in compliance with the License. A copy of the +// License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file 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 logger + +import ( + "os" + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + lumberjack "gopkg.in/natefinch/lumberjack.v2" +) + +type structuredLogger struct { + zapLogger *zap.SugaredLogger +} + +// getZapLevel converts log level string to zapcore.Level. +func getZapLevel(logLevel string) zapcore.Level { + switch lvl := strings.ToLower(os.Getenv(envLogLevel)); lvl { + case "debug": + return zapcore.DebugLevel + case "info": + return zapcore.InfoLevel + case "warn": + return zapcore.WarnLevel + case "error": + return zapcore.ErrorLevel + case "fatal": + return zapcore.FatalLevel + default: + return zapcore.DebugLevel + } +} + +func (l *structuredLogger) Debugf(format string, args ...interface{}) { + l.zapLogger.Debugf(format, args...) +} + +func (l *structuredLogger) Debug(format string) { + l.zapLogger.Desugar().Debug(format) +} + +func (l *structuredLogger) Infof(format string, args ...interface{}) { + l.zapLogger.Infof(format, args...) +} + +func (l *structuredLogger) Info(format string) { + l.zapLogger.Desugar().Info(format) +} + +func (l *structuredLogger) Warnf(format string, args ...interface{}) { + l.zapLogger.Warnf(format, args...) +} + +func (l *structuredLogger) Warn(format string) { + l.zapLogger.Desugar().Warn(format) +} + +func (l *structuredLogger) Error(format string) { + l.zapLogger.Desugar().Error(format) +} + +func (l *structuredLogger) Errorf(format string, args ...interface{}) { + l.zapLogger.Errorf(format, args...) +} + +func (l *structuredLogger) Fatalf(format string, args ...interface{}) { + l.zapLogger.Fatalf(format, args...) +} + +func (l *structuredLogger) Panicf(format string, args ...interface{}) { + l.zapLogger.Fatalf(format, args...) +} + +func (l *structuredLogger) WithFields(fields Fields) Logger { + var f = make([]interface{}, 0) + for k, v := range fields { + f = append(f, k) + f = append(f, v) + } + newLogger := l.zapLogger.With(f...) + return &structuredLogger{newLogger} +} + +func getEncoder() zapcore.Encoder { + encoderConfig := zap.NewProductionEncoderConfig() + encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + return zapcore.NewJSONEncoder(encoderConfig) +} + +// GetLogFileLocation returns the log file path +func getLogFileLocation(srvName string) string { + switch srvName { + case "L-IPamD": + logFilePath := os.Getenv(envIPamDLogFilePath) + if logFilePath == "" { + logFilePath = defaultIPamDLogFilePath + } + return logFilePath + case "Plugin": + logFilePath := os.Getenv(envPluginFilePath) + if logFilePath == "" { + logFilePath = defaultPluginLogFilePath + } + return logFilePath + default: + return "stdout" + } +} + +func newZapLogger(srvName string) Logger { + var cores []zapcore.Core + + logLevel := getZapLevel(envLogLevel) + + logFileLocation := getLogFileLocation(srvName) + + var writer zapcore.WriteSyncer + + if logFileLocation != "stdout" { + writer = getLogWriter(logFileLocation) + } else { + writer = zapcore.Lock(os.Stdout) + } + + cores = append(cores, zapcore.NewCore(getEncoder(), writer, logLevel)) + + combinedCore := zapcore.NewTee(cores...) + + logger := zap.New(combinedCore, + zap.AddCaller(), + zap.AddCallerSkip(2), + ) + defer logger.Sync() + sugar := logger.Sugar() + + return &structuredLogger{ + zapLogger: sugar, + } +} + +//getLogWriter is for lumberjack +func getLogWriter(logFilePath string) zapcore.WriteSyncer { + lumberJackLogger := &lumberjack.Logger{ + Filename: logFilePath, + MaxSize: 100, + MaxBackups: 5, + MaxAge: 30, + Compress: true, + } + return zapcore.AddSync(lumberJackLogger) +} + +// defaultZapLogger creates and returns a new default logger. +func defaultZapLogger() *zap.SugaredLogger { + productionConfig := zap.NewProductionConfig() + productionConfig.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + logger, _ := productionConfig.Build() + defer logger.Sync() + sugar := logger.Sugar() + return sugar +}