diff --git a/cmd/controlplane-operator/main.go b/cmd/controlplane-operator/main.go index f4d7173..7004c7a 100644 --- a/cmd/controlplane-operator/main.go +++ b/cmd/controlplane-operator/main.go @@ -16,27 +16,44 @@ package main import ( "flag" + "log" "os" certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" mcpv1alpha1 "github.com/patrostkowski/controlplane-operator/pkg/apis/controlplane.patrostkowski.dev/v1alpha1" "github.com/patrostkowski/controlplane-operator/pkg/controller" + "github.com/patrostkowski/controlplane-operator/pkg/logger" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) +var ( + appLogger logger.Logger +) + func main() { var metricsAddr string var healthProbeAddr string + var logLevel string flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&healthProbeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.StringVar(&logLevel, "log-level", "info", "Log level for the controller") flag.Parse() - ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + // parse logLevel string to abstraction-compatible log level + parsedLogLevel, err := logger.ParseLogLevel(logLevel) + if err != nil { + log.Panicln("errors setting the log level:", err) + } + + // create zap logger based on logging abstraction + appLogger = logger.NewZapLogger(parsedLogLevel) + + // pass compatible logr.Logger instance for controller runtime components + ctrl.SetLogger(appLogger.GetBaseLogrInstance()) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: nil, diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go new file mode 100644 index 0000000..0f8d583 --- /dev/null +++ b/pkg/logger/logger.go @@ -0,0 +1,54 @@ +// Copyright 2025 Patryk Rostkowski +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logger + +import ( + "fmt" + + "github.com/go-logr/logr" +) + +type Level int + +const ( + DebugLevel Level = iota + InfoLevel + WarnLevel + ErrorLevel + None +) + +type Logger interface { + Debug(msg string, keysAndValues ...any) + Info(msg string, keysAndValues ...any) + Warn(msg string, keysAndValues ...any) + Error(err error, msg string, keysAndValues ...any) + GetBaseLogrInstance() logr.Logger +} + +func ParseLogLevel(parsedLogLevel string) (Level, error) { + switch parsedLogLevel { + case "debug": + return DebugLevel, nil + case "info": + return InfoLevel, nil + case "warn": + return WarnLevel, nil + case "error": + return ErrorLevel, nil + default: + return None, fmt.Errorf("log level %s is not defined", parsedLogLevel) + } +} diff --git a/pkg/logger/zap.go b/pkg/logger/zap.go new file mode 100644 index 0000000..0d64f0c --- /dev/null +++ b/pkg/logger/zap.go @@ -0,0 +1,66 @@ +// Copyright 2025 Patryk Rostkowski +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logger + +import ( + "github.com/go-logr/logr" + "go.uber.org/zap/zapcore" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +type ZapLogger struct { + log logr.Logger +} + +func NewZapLogger(logLevel Level) *ZapLogger { + newZap := zap.New(zap.UseDevMode(true), zap.Level(logLevel.toZapLevel())) + return &ZapLogger{ + log: newZap, + } +} + +func (l Level) toZapLevel() zapcore.Level { + switch l { + case DebugLevel: + return zapcore.DebugLevel + case InfoLevel: + return zapcore.InfoLevel + case WarnLevel: + return zapcore.WarnLevel + case ErrorLevel: + return zapcore.ErrorLevel + default: + return zapcore.InfoLevel + } +} + +func (l *ZapLogger) GetBaseLogrInstance() logr.Logger { + return l.log +} + +func (l *ZapLogger) Debug(msg string, kv ...any) { + l.log.V(int(zapcore.DebugLevel)).Info(msg, kv...) +} + +func (l *ZapLogger) Info(msg string, kv ...any) { + l.log.V(int(zapcore.InfoLevel)).Info(msg, kv...) +} + +func (l *ZapLogger) Warn(msg string, kv ...any) { + l.log.V(int(zapcore.WarnLevel)).Info(msg, kv...) +} +func (l *ZapLogger) Error(err error, msg string, kv ...any) { + l.log.V(int(zapcore.ErrorLevel)).Error(err, msg, kv...) +}