feat: add log rotate (#1200)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 00d3b8f..9e9fd5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -363,6 +363,7 @@
* chen zhuo
### Changes
+
<details><summary>24 commits</summary>
<p>
@@ -390,6 +391,7 @@
* [`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 cf73256..6450449 100644
--- a/cmd/ingress/ingress.go
+++ b/cmd/ingress/ingress.go
@@ -25,6 +25,8 @@
"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 @@
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 @@
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 35168ef..a32a00b 100644
--- a/cmd/ingress/ingress_test.go
+++ b/cmd/ingress/ingress_test.go
@@ -19,6 +19,7 @@
"bytes"
"encoding/json"
"fmt"
+ "io/ioutil"
"math/rand"
"os"
"strings"
@@ -162,3 +163,48 @@
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 a91aa3e..3fe9cf1 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -27,6 +27,11 @@
# 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 1a486d1..83720cb 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,7 @@
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 5d6e370..a29610c 100644
--- a/go.sum
+++ b/go.sum
@@ -48,6 +48,7 @@
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/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 4e061b6..a3997e0 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -79,6 +79,10 @@
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 @@
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 c448d44..5586114 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -30,6 +30,10 @@
cfg := &Config{
LogLevel: "warn",
LogOutput: "stdout",
+ LogRotateOutputPath: "",
+ LogRotationMaxSize: 100,
+ LogRotationMaxAge: 0,
+ LogRotationMaxBackups: 0,
HTTPListen: ":9090",
HTTPSListen: ":9443",
IngressPublishService: "",
@@ -114,6 +118,10 @@
cfg := &Config{
LogLevel: "warn",
LogOutput: "stdout",
+ LogRotateOutputPath: "",
+ LogRotationMaxSize: 100,
+ LogRotationMaxAge: 0,
+ LogRotationMaxBackups: 0,
HTTPListen: ":9090",
HTTPSListen: ":9443",
IngressPublishService: "",