Skip to content

Commit

Permalink
feat(productlogging): add log4j2 config generator (#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
lwpk110 authored Sep 3, 2024
1 parent 22b22f3 commit 400413c
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 0 deletions.
79 changes: 79 additions & 0 deletions pkg/productlogging/log4j2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package productlogging

import (
"fmt"
"strings"

loggingv1alpha1 "github.com/zncdatadev/operator-go/pkg/apis/commons/v1alpha1"
)

const log4j2Template = `appenders = FILE, CONSOLE
appender.CONSOLE.type = Console
appender.CONSOLE.name = CONSOLE
appender.CONSOLE.target = SYSTEM_ERR
appender.CONSOLE.layout.type = PatternLayout
appender.CONSOLE.layout.pattern = {{.ConsoleConversionPattern}}
appender.CONSOLE.filter.threshold.type = ThresholdFilter
appender.CONSOLE.filter.threshold.level = {{.ConsoleLogLevel}}
appender.FILE.type = RollingFile
appender.FILE.name = FILE
appender.FILE.fileName = {{.LogDir}}{{.LogFile}}
appender.FILE.filePattern = {{.LogDir}}{{.LogFile}}.%i
appender.FILE.layout.type = XMLLayout
appender.FILE.policies.type = Policies
appender.FILE.policies.size.type = SizeBasedTriggeringPolicy
appender.FILE.policies.size.size = {{.MaxLogFileSizeInMiB}}MB
appender.FILE.strategy.type = DefaultRolloverStrategy
appender.FILE.strategy.max = {{.NumberOfArchivedLogFiles}}
appender.FILE.filter.threshold.type = ThresholdFilter
appender.FILE.filter.threshold.level = {{.FileLogLevel}}
{{.Loggers}}
rootLogger.level={{.RootLogLevel}}
rootLogger.appenderRefs = CONSOLE, FILE
rootLogger.appenderRef.CONSOLE.ref = CONSOLE
rootLogger.appenderRef.FILE.ref = FILE`

func NewLog4j2ConfigGenerator(
loggingConfigSpec *loggingv1alpha1.LoggingConfigSpec,
containerName string,
consoleConversionPattern string,
maxLogFileSizeInMiB *float64,
logFileName string,
configFileName string) *Log4j2ConfigGenerator {
impl := &Log4j2ConfigGenerator{configFileName: configFileName}
impl.BaseLoggingConfigGenerator = *NewBaseLoggingConfigGenerator(loggingConfigSpec, containerName, consoleConversionPattern, maxLogFileSizeInMiB, logFileName, impl)
return impl
}

var _ LoggingConfigGenerator = &Log4j2ConfigGenerator{}

type Log4j2ConfigGenerator struct {
BaseLoggingConfigGenerator
configFileName string
}

// GenerateLoggersConfig implements LoggingConfigGenerator.
func (l *Log4j2ConfigGenerator) GenerateLoggersConfig(LoggersSpec map[string]*loggingv1alpha1.LogLevelSpec) string {
if len(LoggersSpec) == 0 {
return ""
}

var loggerNames, loggersConfig []string
for name, lvl := range LoggersSpec {
loggerNames = append(loggerNames, name)
loggersConfig = append(loggersConfig, fmt.Sprintf("logger.%s.name = %s", name, name))
loggersConfig = append(loggersConfig, fmt.Sprintf("logger.%s.name = %s", name, lvl.Level))
}
return fmt.Sprintf("loggers = %s\n%s", strings.Join(loggerNames, ","), strings.Join(loggersConfig, "\n"))
}

// ConfigTemplate implements LoggingConfigGenerator.
func (l *Log4j2ConfigGenerator) ConfigTemplate() string {
return log4j2Template
}

func (l *Log4j2ConfigGenerator) FileName() string {
return l.configFileName
}
104 changes: 104 additions & 0 deletions pkg/productlogging/log4j2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package productlogging_test

import (
loggingv1alpha1 "github.com/zncdatadev/operator-go/pkg/apis/commons/v1alpha1"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/zncdatadev/operator-go/pkg/productlogging"
)

var _ = Describe("Log4j2ConfigGenerator", func() {
var (
generator productlogging.Log4j2ConfigGenerator
)

Context("when parsing is successful", func() {
It("should return parsed configuration string", func() {
loggingConfigSpec := &loggingv1alpha1.LoggingConfigSpec{
Loggers: map[string]*loggingv1alpha1.LogLevelSpec{
"a": {
Level: "INFO",
},
"b": {
Level: "DEBUG",
},
},
Console: &loggingv1alpha1.LogLevelSpec{
Level: "INFO",
},
File: &loggingv1alpha1.LogLevelSpec{
Level: "DEBUG",
},
}
generator = *productlogging.NewLog4j2ConfigGenerator(loggingConfigSpec, "zoo_container", productlogging.DefaultLog4j2ConversionPattern, nil, "app.log", "logback.xml")
result := generator.Generate()
Expect(result).Should(ContainSubstring("appenders = FILE, CONSOLE"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.type = Console"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.name = CONSOLE"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.target = SYSTEM_ERR"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.layout.type = PatternLayout"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.layout.pattern = %d{ISO8601} %-5p %m%n"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.filter.threshold.type = ThresholdFilter"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.filter.threshold.level = INFO"))

Expect(result).Should(ContainSubstring("appender.FILE.type = RollingFile"))
Expect(result).Should(ContainSubstring("appender.FILE.name = FILE"))
Expect(result).Should(ContainSubstring("appender.FILE.fileName = /kubedoop/log/zoo_container/app.log"))
Expect(result).Should(ContainSubstring("appender.FILE.filePattern = /kubedoop/log/zoo_container/app.log.%i"))
Expect(result).Should(ContainSubstring("appender.FILE.layout.type = XMLLayout"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.type = Policies"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.size.type = SizeBasedTriggeringPolicy"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.size.size = 5MB"))
Expect(result).Should(ContainSubstring("appender.FILE.strategy.type = DefaultRolloverStrategy"))
Expect(result).Should(ContainSubstring("appender.FILE.strategy.max = 1"))
Expect(result).Should(ContainSubstring("appender.FILE.filter.threshold.type = ThresholdFilter"))
Expect(result).Should(ContainSubstring("appender.FILE.filter.threshold.level = DEBUG"))

Expect(result).Should(ContainSubstring("loggers = a,b"))
Expect(result).Should(ContainSubstring("logger.a.name = a"))
Expect(result).Should(ContainSubstring("logger.a.name = INFO"))
Expect(result).Should(ContainSubstring("logger.b.name = b"))
Expect(result).Should(ContainSubstring("logger.b.name = DEBUG"))
Expect(result).Should(ContainSubstring("rootLogger.level=INFO"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRefs = CONSOLE, FILE"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRef.CONSOLE.ref = CONSOLE"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRef.FILE.ref = FILE"))

})
})

Context("when parsing is successful", func() {
It("should return default string when loggingConfigSpec is nil", func() {
generator = *productlogging.NewLog4j2ConfigGenerator(nil, "zoo_container", productlogging.DefaultLog4j2ConversionPattern, nil, "app.log", "logback.xml")
result := generator.Generate()
Expect(result).Should(ContainSubstring("appenders = FILE, CONSOLE"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.type = Console"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.name = CONSOLE"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.target = SYSTEM_ERR"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.layout.type = PatternLayout"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.layout.pattern = %d{ISO8601} %-5p %m%n"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.filter.threshold.type = ThresholdFilter"))
Expect(result).Should(ContainSubstring("appender.CONSOLE.filter.threshold.level = INFO"))

Expect(result).Should(ContainSubstring("appender.FILE.type = RollingFile"))
Expect(result).Should(ContainSubstring("appender.FILE.name = FILE"))
Expect(result).Should(ContainSubstring("appender.FILE.fileName = /kubedoop/log/zoo_container/app.log"))
Expect(result).Should(ContainSubstring("appender.FILE.filePattern = /kubedoop/log/zoo_container/app.log.%i"))
Expect(result).Should(ContainSubstring("appender.FILE.layout.type = XMLLayout"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.type = Policies"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.size.type = SizeBasedTriggeringPolicy"))
Expect(result).Should(ContainSubstring("appender.FILE.policies.size.size = 10MB"))
Expect(result).Should(ContainSubstring("appender.FILE.strategy.type = DefaultRolloverStrategy"))
Expect(result).Should(ContainSubstring("appender.FILE.strategy.max = 1"))
Expect(result).Should(ContainSubstring("appender.FILE.filter.threshold.type = ThresholdFilter"))
Expect(result).Should(ContainSubstring("appender.FILE.filter.threshold.level = INFO"))

Expect(result).Should(ContainSubstring("rootLogger.level=INFO"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRefs = CONSOLE, FILE"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRef.CONSOLE.ref = CONSOLE"))
Expect(result).Should(ContainSubstring("rootLogger.appenderRef.FILE.ref = FILE"))
})
})

})

0 comments on commit 400413c

Please sign in to comment.