Skip to content

Commit bede768

Browse files
committed
Add slog structured logging to various controllers and utility functions
- Integrated `slog` logging into the `MirrorPeerSecretReconciler`, `MirrorPeerReconciler`, and `DRPolicyReconciler` controllers. - Improved error handling and logging for better observability and debugging. - Replaced klog with slog for consistency across the codebase. Changes include: - Added `Logger` field to controller structs to pass and use `slog.Logger`. - Enhanced logging messages to provide more context, including function names, object names, namespaces, and error details. - Ensured logs capture both normal operation (e.g., successful updates) and error conditions. Signed-off-by: vbadrina <vbadrina@redhat.com>
1 parent acfbd5a commit bede768

11 files changed

+538
-323
lines changed

controllers/common_controller_utils.go

Lines changed: 157 additions & 127 deletions
Large diffs are not rendered by default.

controllers/common_controller_utils_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"context"
2424
"encoding/json"
2525
"fmt"
26+
"log/slog"
2627
"os"
2728
"reflect"
2829
"testing"
@@ -262,12 +263,13 @@ func TestMirrorPeerSecretReconcile(t *testing.T) {
262263
}
263264

264265
fakeClient := getFakeClient(t, mgrScheme)
266+
fakeLogger := slog.New(slog.NewTextHandler(os.Stdout, nil))
265267
for _, c := range cases {
266268
os.Setenv("POD_NAMESPACE", c.ramenNamespace)
267269
ctx := context.TODO()
268-
err := createOrUpdateSecretsFromInternalSecret(ctx, fakeClient, fakeS3InternalSecret(t, TestSourceManagedClusterEast), fakeMirrorPeers(c.manageS3))
270+
err := createOrUpdateSecretsFromInternalSecret(ctx, fakeClient, fakeS3InternalSecret(t, TestSourceManagedClusterEast), fakeMirrorPeers(c.manageS3), fakeLogger)
269271
assert.NoError(t, err)
270-
err = createOrUpdateSecretsFromInternalSecret(ctx, fakeClient, fakeS3InternalSecret(t, TestDestinationManagedClusterWest), fakeMirrorPeers(c.manageS3))
272+
err = createOrUpdateSecretsFromInternalSecret(ctx, fakeClient, fakeS3InternalSecret(t, TestDestinationManagedClusterWest), fakeMirrorPeers(c.manageS3), fakeLogger)
271273
assert.NoError(t, err)
272274

273275
if c.ignoreS3Profile {

controllers/drpolicy_controller.go

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"log/slog"
78
"time"
89

910
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -12,13 +13,11 @@ import (
1213
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
1314
multiclusterv1alpha1 "github.com/red-hat-storage/odf-multicluster-orchestrator/api/v1alpha1"
1415
"github.com/red-hat-storage/odf-multicluster-orchestrator/controllers/utils"
15-
"k8s.io/apimachinery/pkg/api/errors"
1616
k8serrors "k8s.io/apimachinery/pkg/api/errors"
1717
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1818
"k8s.io/apimachinery/pkg/runtime"
1919
"k8s.io/apimachinery/pkg/runtime/schema"
2020
"k8s.io/apimachinery/pkg/types"
21-
"k8s.io/klog/v2"
2221
workv1 "open-cluster-management.io/api/work/v1"
2322
ctrl "sigs.k8s.io/controller-runtime"
2423
"sigs.k8s.io/controller-runtime/pkg/builder"
@@ -46,87 +45,110 @@ const (
4645
type DRPolicyReconciler struct {
4746
HubClient client.Client
4847
Scheme *runtime.Scheme
48+
Logger *slog.Logger
4949
}
5050

5151
// SetupWithManager sets up the controller with the Manager.
5252
func (r *DRPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
53+
r.Logger.Info("Setting up DRPolicyReconciler with manager")
54+
5355
dpPredicate := utils.ComposePredicates(predicate.GenerationChangedPredicate{})
54-
return ctrl.NewControllerManagedBy(mgr).
56+
err := ctrl.NewControllerManagedBy(mgr).
5557
For(&ramenv1alpha1.DRPolicy{}, builder.WithPredicates(dpPredicate)).
5658
Complete(r)
59+
60+
if err != nil {
61+
r.Logger.Error("Failed to set up DRPolicyReconciler with manager", "error", err)
62+
return err
63+
}
64+
65+
r.Logger.Info("Successfully set up DRPolicyReconciler with manager")
66+
return nil
5767
}
5868

5969
func (r *DRPolicyReconciler) getMirrorPeerForClusterSet(ctx context.Context, clusterSet []string) (*multiclusterv1alpha1.MirrorPeer, error) {
70+
logger := r.Logger.With("method", "getMirrorPeerForClusterSet", "ClusterSet", clusterSet)
71+
6072
var mpList multiclusterv1alpha1.MirrorPeerList
6173
err := r.HubClient.List(ctx, &mpList)
6274
if err != nil {
63-
klog.Error("could not list mirrorpeers on hub")
75+
logger.Error("Could not list MirrorPeers on hub", "error", err)
6476
return nil, err
6577
}
6678

6779
if len(mpList.Items) == 0 {
68-
klog.Info("no mirrorpeers found on hub yet")
80+
logger.Info("No MirrorPeers found on hub yet")
6981
return nil, k8serrors.NewNotFound(schema.GroupResource{Group: multiclusterv1alpha1.GroupVersion.Group, Resource: "MirrorPeer"}, "MirrorPeerList")
7082
}
83+
7184
for _, mp := range mpList.Items {
7285
if (mp.Spec.Items[0].ClusterName == clusterSet[0] && mp.Spec.Items[1].ClusterName == clusterSet[1]) ||
7386
(mp.Spec.Items[1].ClusterName == clusterSet[0] && mp.Spec.Items[0].ClusterName == clusterSet[1]) {
74-
klog.Infof("found mirrorpeer %q for drpolicy", mp.Name)
87+
logger.Info("Found MirrorPeer for DRPolicy", "MirrorPeerName", mp.Name)
7588
return &mp, nil
7689
}
7790
}
7891

79-
klog.Info("could not find any mirrorpeer for drpolicy")
92+
logger.Info("Could not find any MirrorPeer for DRPolicy")
8093
return nil, k8serrors.NewNotFound(schema.GroupResource{Group: multiclusterv1alpha1.GroupVersion.Group, Resource: "MirrorPeer"}, fmt.Sprintf("ClusterSet-%s-%s", clusterSet[0], clusterSet[1]))
8194
}
95+
8296
func (r *DRPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
83-
klog.Infof("running DRPolicy reconciler on hub cluster")
84-
// Fetch DRPolicy for given Request
97+
r.Logger.Info("Running DRPolicy reconciler on hub cluster", "RequestNamespace", req.Namespace, "RequestName", req.Name)
98+
99+
// Fetch DRPolicy for the given request
85100
var drpolicy ramenv1alpha1.DRPolicy
86101
err := r.HubClient.Get(ctx, req.NamespacedName, &drpolicy)
87102
if err != nil {
88-
if errors.IsNotFound(err) {
89-
klog.Info("Could not find DRPolicy. Ignoring since object must have been deleted")
103+
if k8serrors.IsNotFound(err) {
104+
r.Logger.Info("DRPolicy not found. Ignoring since the object must have been deleted", "RequestNamespace", req.Namespace, "RequestName", req.Name)
90105
return ctrl.Result{}, nil
91106
}
92-
klog.Error(err, "Failed to get DRPolicy")
107+
r.Logger.Error("Failed to get DRPolicy", "error", err, "RequestNamespace", req.Namespace, "RequestName", req.Name)
93108
return ctrl.Result{}, err
94109
}
95110

96-
// find mirrorpeer for clusterset for the storagecluster namespaces
111+
// Find MirrorPeer for clusterset for the storagecluster namespaces
97112
mirrorPeer, err := r.getMirrorPeerForClusterSet(ctx, drpolicy.Spec.DRClusters)
98113
if err != nil {
99114
if k8serrors.IsNotFound(err) {
115+
r.Logger.Info("MirrorPeer not found. Requeuing", "DRClusters", drpolicy.Spec.DRClusters)
100116
return ctrl.Result{RequeueAfter: time.Second * 10}, nil
101117
}
102-
klog.Error("error occurred while trying to fetch MirrorPeer for given DRPolicy")
118+
r.Logger.Error("Error occurred while trying to fetch MirrorPeer for given DRPolicy", "error", err)
103119
return ctrl.Result{}, err
104120
}
105121

106122
if mirrorPeer.Spec.Type == multiclusterv1alpha1.Async {
107123
clusterFSIDs := make(map[string]string)
108-
klog.Infof("Fetching clusterFSIDs")
124+
r.Logger.Info("Fetching cluster FSIDs")
109125
err = r.fetchClusterFSIDs(ctx, mirrorPeer, clusterFSIDs)
110126
if err != nil {
111-
if errors.IsNotFound(err) {
127+
if k8serrors.IsNotFound(err) {
128+
r.Logger.Info("Cluster FSIDs not found, requeuing")
112129
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
113130
}
114-
return ctrl.Result{}, fmt.Errorf("an unknown error occured while fetching the cluster fsids, retrying again: %v", err)
131+
r.Logger.Error("An unknown error occurred while fetching the cluster FSIDs, retrying", "error", err)
132+
return ctrl.Result{}, fmt.Errorf("an unknown error occurred while fetching the cluster FSIDs, retrying: %v", err)
115133
}
116134

117135
err = r.createOrUpdateManifestWorkForVRC(ctx, mirrorPeer, &drpolicy, clusterFSIDs)
118136
if err != nil {
137+
r.Logger.Error("Failed to create VolumeReplicationClass via ManifestWork", "error", err)
119138
return ctrl.Result{}, fmt.Errorf("failed to create VolumeReplicationClass via ManifestWork: %v", err)
120139
}
121140
}
122141

142+
r.Logger.Info("Successfully reconciled DRPolicy", "RequestNamespace", req.Namespace, "RequestName", req.Name)
123143
return ctrl.Result{}, nil
124144
}
125145

126146
func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Context, mp *multiclusterv1alpha1.MirrorPeer, dp *ramenv1alpha1.DRPolicy, clusterFSIDs map[string]string) error {
147+
logger := r.Logger.With("method", "createOrUpdateManifestWorkForVRC", "DRPolicy", dp.Name, "MirrorPeer", mp.Name)
127148

128149
replicationId, err := utils.CreateUniqueReplicationId(clusterFSIDs)
129150
if err != nil {
151+
logger.Error("Failed to create unique replication ID", "error", err)
130152
return err
131153
}
132154

@@ -144,25 +166,30 @@ func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Contex
144166

145167
switch {
146168
case err == nil:
147-
klog.Infof("%s already exists. updating...", manifestWorkName)
148-
case !errors.IsNotFound(err):
149-
klog.Error(err, "failed to get ManifestWork: %s", manifestWorkName)
169+
logger.Info("ManifestWork already exists, updating", "ManifestWorkName", manifestWorkName)
170+
case !k8serrors.IsNotFound(err):
171+
logger.Error("Failed to get ManifestWork", "ManifestWorkName", manifestWorkName, "error", err)
150172
return err
151173
}
152174

153175
interval := dp.Spec.SchedulingInterval
154-
params := make(map[string]string)
155-
params[MirroringModeKey] = DefaultMirroringMode
156-
params[SchedulingIntervalKey] = interval
157-
params[ReplicationSecretNameKey] = RBDReplicationSecretName
158-
params[ReplicationSecretNamespaceKey] = pr.StorageClusterRef.Namespace
176+
params := map[string]string{
177+
MirroringModeKey: DefaultMirroringMode,
178+
SchedulingIntervalKey: interval,
179+
ReplicationSecretNameKey: RBDReplicationSecretName,
180+
ReplicationSecretNamespaceKey: pr.StorageClusterRef.Namespace,
181+
}
182+
159183
vrcName := fmt.Sprintf(RBDVolumeReplicationClassNameTemplate, utils.FnvHash(interval))
160-
labels := make(map[string]string)
161-
labels[fmt.Sprintf(RamenLabelTemplate, ReplicationIDKey)] = replicationId
162-
labels[fmt.Sprintf(RamenLabelTemplate, "maintenancemodes")] = "Failover"
184+
labels := map[string]string{
185+
fmt.Sprintf(RamenLabelTemplate, ReplicationIDKey): replicationId,
186+
fmt.Sprintf(RamenLabelTemplate, "maintenancemodes"): "Failover",
187+
}
188+
163189
vrc := replicationv1alpha1.VolumeReplicationClass{
164190
TypeMeta: metav1.TypeMeta{
165-
Kind: "VolumeReplicationClass", APIVersion: "replication.storage.openshift.io/v1alpha1",
191+
Kind: "VolumeReplicationClass",
192+
APIVersion: "replication.storage.openshift.io/v1alpha1",
166193
},
167194
ObjectMeta: metav1.ObjectMeta{
168195
Name: vrcName,
@@ -179,6 +206,7 @@ func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Contex
179206

180207
objJson, err := json.Marshal(vrc)
181208
if err != nil {
209+
logger.Error("Failed to marshal VolumeReplicationClass to JSON", "VolumeReplicationClass", vrcName, "error", err)
182210
return fmt.Errorf("failed to marshal %v to JSON, error %w", vrc, err)
183211
}
184212

@@ -210,7 +238,7 @@ func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Contex
210238
mw := workv1.ManifestWork{
211239
ObjectMeta: metav1.ObjectMeta{
212240
Name: manifestWorkName,
213-
Namespace: pr.ClusterName, //target cluster
241+
Namespace: pr.ClusterName,
214242
OwnerReferences: []metav1.OwnerReference{
215243
{
216244
Kind: dp.Kind,
@@ -221,6 +249,7 @@ func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Contex
221249
},
222250
},
223251
}
252+
224253
_, err = controllerutil.CreateOrUpdate(ctx, r.HubClient, &mw, func() error {
225254
mw.Spec = workv1.ManifestWorkSpec{
226255
Workload: workv1.ManifestsTemplate{
@@ -231,35 +260,44 @@ func (r *DRPolicyReconciler) createOrUpdateManifestWorkForVRC(ctx context.Contex
231260
})
232261

233262
if err != nil {
234-
klog.Error(err, "failed to create/update ManifestWork: %s", manifestWorkName)
263+
logger.Error("Failed to create/update ManifestWork", "ManifestWorkName", manifestWorkName, "error", err)
235264
return err
236265
}
237266

238-
klog.Infof("ManifestWork created for %s", vrcName)
267+
logger.Info("ManifestWork created/updated successfully", "ManifestWorkName", manifestWorkName, "VolumeReplicationClassName", vrcName)
239268
}
240269

241270
return nil
242271
}
243272

244273
func (r *DRPolicyReconciler) fetchClusterFSIDs(ctx context.Context, peer *multiclusterv1alpha1.MirrorPeer, clusterFSIDs map[string]string) error {
274+
logger := r.Logger.With("method", "fetchClusterFSIDs", "MirrorPeer", peer.Name)
275+
245276
for _, pr := range peer.Spec.Items {
246277
rookSecretName := utils.GetSecretNameByPeerRef(pr)
247-
klog.Info("Fetching rook secret ", "Secret Name:", rookSecretName)
278+
logger.Info("Fetching rook secret", "SecretName", rookSecretName, "ClusterName", pr.ClusterName)
279+
248280
hs, err := utils.FetchSecretWithName(ctx, r.HubClient, types.NamespacedName{Name: rookSecretName, Namespace: pr.ClusterName})
249281
if err != nil {
250-
if errors.IsNotFound(err) {
251-
klog.Infof("could not find secret %q. will attempt to fetch it again after a delay", rookSecretName)
282+
if k8serrors.IsNotFound(err) {
283+
logger.Info("Secret not found, will attempt to fetch again after a delay", "SecretName", rookSecretName, "ClusterName", pr.ClusterName)
284+
return err
252285
}
286+
logger.Error("Failed to fetch rook secret", "SecretName", rookSecretName, "ClusterName", pr.ClusterName, "error", err)
253287
return err
254288
}
255-
klog.Info("Unmarshalling rook secret ", "Secret Name:", rookSecretName)
289+
290+
logger.Info("Unmarshalling rook secret", "SecretName", rookSecretName, "ClusterName", pr.ClusterName)
256291
rt, err := utils.UnmarshalHubSecret(hs)
257292
if err != nil {
258-
klog.Error(err, "Failed to unmarshal rook secret", "Secret", rookSecretName)
293+
logger.Error("Failed to unmarshal rook secret", "SecretName", rookSecretName, "ClusterName", pr.ClusterName, "error", err)
259294
return err
260295
}
296+
261297
clusterFSIDs[pr.ClusterName] = rt.FSID
298+
logger.Info("Successfully fetched FSID for cluster", "ClusterName", pr.ClusterName, "FSID", rt.FSID)
262299
}
263300

301+
logger.Info("Successfully fetched all cluster FSIDs", "MirrorPeer", peer.Name)
264302
return nil
265303
}

controllers/drpolicy_controller_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package controllers
33
import (
44
"context"
55
"fmt"
6+
"log/slog"
7+
"os"
68
"testing"
79

810
ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1"
@@ -146,6 +148,7 @@ func getFakeDRPolicyReconciler(drpolicy *ramenv1alpha1.DRPolicy, mp *multicluste
146148
r := DRPolicyReconciler{
147149
HubClient: fakeClient,
148150
Scheme: scheme,
151+
Logger: slog.New(slog.NewTextHandler(os.Stdout, nil)),
149152
}
150153

151154
return r

controllers/manager.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package controllers
33
import (
44
"context"
55
"flag"
6+
"log/slog"
67
"os"
78

89
consolev1alpha1 "github.com/openshift/api/console/v1alpha1"
@@ -120,9 +121,11 @@ func (o *ManagerOptions) runManager() {
120121

121122
namespace := os.Getenv("POD_NAMESPACE")
122123

124+
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
123125
if err = (&MirrorPeerReconciler{
124126
Client: mgr.GetClient(),
125127
Scheme: mgr.GetScheme(),
128+
Logger: logger,
126129
}).SetupWithManager(mgr); err != nil {
127130
setupLog.Error(err, "unable to create controller", "controller", "MirrorPeer")
128131
os.Exit(1)
@@ -132,6 +135,7 @@ func (o *ManagerOptions) runManager() {
132135
if err = (&MirrorPeerSecretReconciler{
133136
Client: mgr.GetClient(),
134137
Scheme: mgr.GetScheme(),
138+
Logger: logger,
135139
}).SetupWithManager(mgr); err != nil {
136140
setupLog.Error(err, "unable to create controller", "controller", "MirrorPeer")
137141
os.Exit(1)
@@ -224,6 +228,7 @@ func (o *ManagerOptions) runManager() {
224228
if err = (&DRPolicyReconciler{
225229
HubClient: mgr.GetClient(),
226230
Scheme: mgr.GetScheme(),
231+
Logger: logger,
227232
}).SetupWithManager(mgr); err != nil {
228233
setupLog.Error(err, "unable to create controller", "controller", "DRPolicy")
229234
os.Exit(1)

0 commit comments

Comments
 (0)