This is an automated email from the ASF dual-hosted git repository.

zhangjintao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new fcfa1882 feat: add log rotate (#1200)
fcfa1882 is described below

commit fcfa1882957a1d111c616c1ef646b98a0fb6a70f
Author: xiangtianyu <tjjxi...@gmail.com>
AuthorDate: Thu Aug 11 17:35:49 2022 +0800

    feat: add log rotate (#1200)
---
 CHANGELOG.md                |  2 ++
 cmd/ingress/ingress.go      | 27 ++++++++++++++++++++++----
 cmd/ingress/ingress_test.go | 46 +++++++++++++++++++++++++++++++++++++++++++++
 conf/config-default.yaml    |  5 +++++
 go.mod                      |  1 +
 go.sum                      |  2 ++
 pkg/config/config.go        |  8 ++++++++
 pkg/config/config_test.go   |  8 ++++++++
 8 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 00d3b8f2..9e9fd5e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -363,6 +363,7 @@ https://github.com/apache/apisix-ingress-controller/issues.
 * chen zhuo
 
 ### Changes
+
 <details><summary>24 commits</summary>
 <p>
 
@@ -390,6 +391,7 @@ https://github.com/apache/apisix-ingress-controller/issues.
 * 
[`4a2ebaf`](https://github.com/apache/apisix-ingress-controller/commit/4a2ebaf43ee4cf42212659b412e7ed8a8ab8ee21)
 chore: fix typo in ApidixRoute CRD (#830)
 * 
[`46fcf3f`](https://github.com/apache/apisix-ingress-controller/commit/46fcf3f153a00cef868454b06452065172500dd1)
 fix: consumer name contain "-" (#828)
 * 
[`b7dd90a`](https://github.com/apache/apisix-ingress-controller/commit/b7dd90ad9d6a5102fe67c91c29ab76fc4bad4b1a)
 chore: v1.4 release
+
 </p>
 </details>
 
diff --git a/cmd/ingress/ingress.go b/cmd/ingress/ingress.go
index cf732566..6450449d 100644
--- a/cmd/ingress/ingress.go
+++ b/cmd/ingress/ingress.go
@@ -25,6 +25,8 @@ import (
        "time"
 
        "github.com/spf13/cobra"
+       "go.uber.org/zap/zapcore"
+       "gopkg.in/natefinch/lumberjack.v2"
 
        "github.com/apache/apisix-ingress-controller/pkg/config"
        "github.com/apache/apisix-ingress-controller/pkg/log"
@@ -102,10 +104,23 @@ the apisix cluster and others are created`,
                                dief("bad configuration: %s", err)
                        }
 
-                       logger, err := log.NewLogger(
-                               log.WithLogLevel(cfg.LogLevel),
-                               log.WithOutputFile(cfg.LogOutput),
-                       )
+                       var ws zapcore.WriteSyncer
+
+                       options := []log.Option{log.WithLogLevel(cfg.LogLevel), 
log.WithOutputFile(cfg.LogOutput)}
+
+                       if cfg.LogRotateOutputPath != "" {
+                               ws = zapcore.AddSync(&lumberjack.Logger{
+                                       Filename:   cfg.LogRotateOutputPath,
+                                       MaxSize:    cfg.LogRotationMaxSize,
+                                       MaxBackups: cfg.LogRotationMaxBackups,
+                                       MaxAge:     cfg.LogRotationMaxAge,
+                               })
+
+                               options = append(options, 
log.WithWriteSyncer(ws))
+                       }
+
+                       logger, err := log.NewLogger(options...)
+
                        if err != nil {
                                dief("failed to initialize logging: %s", err)
                        }
@@ -143,6 +158,10 @@ the apisix cluster and others are created`,
        cmd.PersistentFlags().StringVar(&configPath, "config-path", "", 
"configuration file path for apisix-ingress-controller")
        cmd.PersistentFlags().StringVar(&cfg.LogLevel, "log-level", "info", 
"error log level")
        cmd.PersistentFlags().StringVar(&cfg.LogOutput, "log-output", "stderr", 
"error log output file")
+       cmd.PersistentFlags().StringVar(&cfg.LogRotateOutputPath, 
"log-rotate-output-path", "", "rotate log output path")
+       cmd.PersistentFlags().IntVar(&cfg.LogRotationMaxSize, 
"log-rotate-max-size", 100, "rotate log max size")
+       cmd.PersistentFlags().IntVar(&cfg.LogRotationMaxAge, 
"log-rotate-max-age", 0, "old rotate log max age to retain")
+       cmd.PersistentFlags().IntVar(&cfg.LogRotationMaxBackups, 
"log-rotate-max-backups", 0, "old rotate log max numbers to retain")
        cmd.PersistentFlags().StringVar(&cfg.HTTPListen, "http-listen", 
":8080", "the HTTP Server listen address")
        cmd.PersistentFlags().StringVar(&cfg.HTTPSListen, "https-listen", 
":8443", "the HTTPS Server listen address")
        cmd.PersistentFlags().StringVar(&cfg.IngressPublishService, 
"ingress-publish-service", "",
diff --git a/cmd/ingress/ingress_test.go b/cmd/ingress/ingress_test.go
index 35168ef8..a32a00b7 100644
--- a/cmd/ingress/ingress_test.go
+++ b/cmd/ingress/ingress_test.go
@@ -19,6 +19,7 @@ import (
        "bytes"
        "encoding/json"
        "fmt"
+       "io/ioutil"
        "math/rand"
        "os"
        "strings"
@@ -162,3 +163,48 @@ func parseLog(t *testing.T, r *bufio.Reader) *fields {
        assert.Nil(t, err)
        return &f
 }
+
+func TestRotateLog(t *testing.T) {
+       listen := getRandomListen()
+       cmd := NewIngressCommand()
+       cmd.SetArgs([]string{
+               "--log-rotate-output-path", "./testlog/test.log",
+               "--log-rotate-max-size", "1",
+               "--http-listen", listen,
+               "--enable-profiling",
+               "--kubeconfig", "/foo/bar/baz",
+               "--resync-interval", "24h",
+               "--default-apisix-cluster-base-url", 
"http://apisixgw.default.cluster.local/apisix";,
+               "--default-apisix-cluster-admin-key", "0x123",
+       })
+       defer os.RemoveAll("./testlog/")
+
+       stopCh := make(chan struct{})
+       go func() {
+               assert.Nil(t, cmd.Execute())
+               close(stopCh)
+       }()
+
+       // fill logs with data until the size > 1m
+       line := ""
+       for i := 0; i < 256; i++ {
+               line += "0"
+       }
+
+       for i := 0; i < 4096; i++ {
+               log.Info(line)
+       }
+
+       time.Sleep(5 * time.Second)
+       assert.Nil(t, syscall.Kill(os.Getpid(), syscall.SIGINT))
+       <-stopCh
+
+       files, err := ioutil.ReadDir("./testlog")
+
+       if err != nil {
+               t.Fatalf("Unable to read log dir: %v", err)
+       }
+
+       assert.Equal(t, true, len(files) >= 2)
+
+}
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index a91aa3e8..3fe9cf1c 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -27,6 +27,11 @@ log_output: "stderr" # the output file path of error log, 
default is stderr, whe
                      # are marshalled in JSON format, which can be parsed by
                      # programs easily.
 
+log_rotate_output_path: ""  # rotate output path, the logs will be written in 
this file
+log_rotation_max_size: 100  # rotate max size, max size in megabytes of log 
file before it get rotated. It defaults to 100
+log_rotation_max_age: 0     # rotate max age, max age of old log files to 
retain
+log_rotation_max_backups: 0 # rotate max backups, max numbers of old log files 
to retain
+
 cert_file: "/etc/webhook/certs/cert.pem" # the TLS certificate file path.
 key_file: "/etc/webhook/certs/key.pem"   # the TLS key file path.
 
diff --git a/go.mod b/go.mod
index 1a486d1a..83720cb4 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,7 @@ require (
        go.uber.org/multierr v1.8.0
        go.uber.org/zap v1.21.0
        golang.org/x/net v0.0.0-20220725212005-46097bf591d3
+       gopkg.in/natefinch/lumberjack.v2 v2.0.0
        gopkg.in/yaml.v2 v2.4.0
        k8s.io/api v0.24.3
        k8s.io/apimachinery v0.24.3
diff --git a/go.sum b/go.sum
index 5d6e3709..a29610c4 100644
--- a/go.sum
+++ b/go.sum
@@ -48,6 +48,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod 
h1:LTp+uSrOhSkaKrUy935
 github.com/Azure/go-autorest/logger v0.2.0/go.mod 
h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/logger v0.2.1/go.mod 
h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod 
h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/BurntSushi/toml v0.3.1 
h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod 
h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod 
h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod 
h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -999,6 +1000,7 @@ gopkg.in/inf.v0 v0.9.1 
h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+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/resty.v1 v1.12.0/go.mod 
h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod 
h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 4e061b6c..a3997e0f 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -79,6 +79,10 @@ type Config struct {
        KeyFilePath                string             `json:"key_file" 
yaml:"key_file"`
        LogLevel                   string             `json:"log_level" 
yaml:"log_level"`
        LogOutput                  string             `json:"log_output" 
yaml:"log_output"`
+       LogRotateOutputPath        string             
`json:"log_rotate_output_path" yaml:"log_rotate_output_path"`
+       LogRotationMaxSize         int                
`json:"log_rotation_max_size" yaml:"log_rotation_max_size"`
+       LogRotationMaxAge          int                
`json:"log_rotation_max_age" yaml:"log_rotation_max_age"`
+       LogRotationMaxBackups      int                
`json:"log_rotation_max_backups" yaml:"log_rotation_max_backups"`
        HTTPListen                 string             `json:"http_listen" 
yaml:"http_listen"`
        HTTPSListen                string             `json:"https_listen" 
yaml:"https_listen"`
        IngressPublishService      string             
`json:"ingress_publish_service" yaml:"ingress_publish_service"`
@@ -120,6 +124,10 @@ func NewDefaultConfig() *Config {
        return &Config{
                LogLevel:                   "warn",
                LogOutput:                  "stderr",
+               LogRotateOutputPath:        "",
+               LogRotationMaxSize:         100,
+               LogRotationMaxAge:          0,
+               LogRotationMaxBackups:      0,
                HTTPListen:                 ":8080",
                HTTPSListen:                ":8443",
                IngressPublishService:      "",
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index c448d440..55861149 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -30,6 +30,10 @@ func TestNewConfigFromFile(t *testing.T) {
        cfg := &Config{
                LogLevel:                   "warn",
                LogOutput:                  "stdout",
+               LogRotateOutputPath:        "",
+               LogRotationMaxSize:         100,
+               LogRotationMaxAge:          0,
+               LogRotationMaxBackups:      0,
                HTTPListen:                 ":9090",
                HTTPSListen:                ":9443",
                IngressPublishService:      "",
@@ -114,6 +118,10 @@ func TestConfigWithEnvVar(t *testing.T) {
        cfg := &Config{
                LogLevel:                   "warn",
                LogOutput:                  "stdout",
+               LogRotateOutputPath:        "",
+               LogRotationMaxSize:         100,
+               LogRotationMaxAge:          0,
+               LogRotationMaxBackups:      0,
                HTTPListen:                 ":9090",
                HTTPSListen:                ":9443",
                IngressPublishService:      "",

Reply via email to