Repository: feast-dev/feast (language: python)

Issue:
Feast Operator: Support Log Level Configuration in FeatureStore CR for Feature Services
we need to add l og level configuration in FeatureStore CR, followed the requirements from https://github.com/feast-dev/feast/blob/master/sdk/python/feast/cli.py#L85,  only allow  values "debug", "info", "warning", "error", "critical".
```
spec:
  feastProject: test
  services:
    offlineStore:
      logLevel: debug
    onlineStore:
      logLevel: debug
    registry:
      local:
        logLevel: debug
```
optional, would add the following at service startup -

`--log-level DEBUG `

The `--log-level` parameter should be included in the Feast service deployment command only if it is explicitly configured in the  (CR) by the user.
If `logLevel` is not specified in the CR, the deployment command should not include the `--log-level` parameter.




Discussion / hints:

Fix patch:
diff --git a/infra/feast-operator/api/v1alpha1/featurestore_types.go b/infra/feast-operator/api/v1alpha1/featurestore_types.go
index 17a029c02e..0b516630cd 100644
--- a/infra/feast-operator/api/v1alpha1/featurestore_types.go
+++ b/infra/feast-operator/api/v1alpha1/featurestore_types.go
@@ -77,6 +77,10 @@ type OfflineStore struct {
 	ServiceConfigs `json:",inline"`
 	Persistence    *OfflineStorePersistence `json:"persistence,omitempty"`
 	TLS            *OfflineTlsConfigs       `json:"tls,omitempty"`
+	// LogLevel sets the logging level for the offline store service
+	// Allowed values: "debug", "info", "warning", "error", "critical".
+	// +kubebuilder:validation:Enum=debug;info;warning;error;critical
+	LogLevel string `json:"logLevel,omitempty"`
 }
 
 // OfflineTlsConfigs configures server TLS for the offline feast service. in an openshift cluster, this is configured by default using service serving certificates.
@@ -130,6 +134,10 @@ type OnlineStore struct {
 	ServiceConfigs `json:",inline"`
 	Persistence    *OnlineStorePersistence `json:"persistence,omitempty"`
 	TLS            *TlsConfigs             `json:"tls,omitempty"`
+	// LogLevel sets the logging level for the online store service
+	// Allowed values: "debug", "info", "warning", "error", "critical".
+	// +kubebuilder:validation:Enum=debug;info;warning;error;critical
+	LogLevel string `json:"logLevel,omitempty"`
 }
 
 // OnlineStorePersistence configures the persistence settings for the online store service
@@ -177,6 +185,10 @@ type LocalRegistryConfig struct {
 	ServiceConfigs `json:",inline"`
 	Persistence    *RegistryPersistence `json:"persistence,omitempty"`
 	TLS            *TlsConfigs          `json:"tls,omitempty"`
+	// LogLevel sets the logging level for the registry service
+	// Allowed values: "debug", "info", "warning", "error", "critical".
+	// +kubebuilder:validation:Enum=debug;info;warning;error;critical
+	LogLevel string `json:"logLevel,omitempty"`
 }
 
 // RegistryPersistence configures the persistence settings for the registry service
diff --git a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml
index 1402a64056..6929796d34 100644
--- a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml
+++ b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml
@@ -227,6 +227,17 @@ spec:
                         description: PullPolicy describes a policy for if/when to
                           pull a container image
                         type: string
+                      logLevel:
+                        description: |-
+                          LogLevel sets the logging level for the offline store service
+                          Allowed values: "debug", "info", "warning", "error", "critical".
+                        enum:
+                        - debug
+                        - info
+                        - warning
+                        - error
+                        - critical
+                        type: string
                       persistence:
                         description: OfflineStorePersistence configures the persistence
                           settings for the offline store service
@@ -576,6 +587,17 @@ spec:
                         description: PullPolicy describes a policy for if/when to
                           pull a container image
                         type: string
+                      logLevel:
+                        description: |-
+                          LogLevel sets the logging level for the online store service
+                          Allowed values: "debug", "info", "warning", "error", "critical".
+                        enum:
+                        - debug
+                        - info
+                        - warning
+                        - error
+                        - critical
+                        type: string
                       persistence:
                         description: OnlineStorePersistence configures the persistence
                           settings for the online store service
@@ -939,6 +961,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the registry service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: RegistryPersistence configures the persistence
                               settings for the registry service
@@ -1429,6 +1462,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the offline store service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: OfflineStorePersistence configures the persistence
                               settings for the offline store service
@@ -1784,6 +1828,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the online store service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: OnlineStorePersistence configures the persistence
                               settings for the online store service
@@ -2155,6 +2210,17 @@ spec:
                                 description: PullPolicy describes a policy for if/when
                                   to pull a container image
                                 type: string
+                              logLevel:
+                                description: |-
+                                  LogLevel sets the logging level for the registry service
+                                  Allowed values: "debug", "info", "warning", "error", "critical".
+                                enum:
+                                - debug
+                                - info
+                                - warning
+                                - error
+                                - critical
+                                type: string
                               persistence:
                                 description: RegistryPersistence configures the persistence
                                   settings for the registry service
diff --git a/infra/feast-operator/config/samples/v1alpha1_featurestore_services_loglevel.yaml b/infra/feast-operator/config/samples/v1alpha1_featurestore_services_loglevel.yaml
new file mode 100644
index 0000000000..7ae96d44f0
--- /dev/null
+++ b/infra/feast-operator/config/samples/v1alpha1_featurestore_services_loglevel.yaml
@@ -0,0 +1,15 @@
+apiVersion: feast.dev/v1alpha1
+kind: FeatureStore
+metadata:
+  name: sample-services-loglevel
+spec:
+  feastProject: my_project
+  services:
+    onlineStore:
+      logLevel: debug
+    offlineStore:
+      logLevel: debug
+    registry:
+      local:
+       logLevel: info
+
diff --git a/infra/feast-operator/dist/install.yaml b/infra/feast-operator/dist/install.yaml
index 18ab82e9ca..9e213994eb 100644
--- a/infra/feast-operator/dist/install.yaml
+++ b/infra/feast-operator/dist/install.yaml
@@ -235,6 +235,17 @@ spec:
                         description: PullPolicy describes a policy for if/when to
                           pull a container image
                         type: string
+                      logLevel:
+                        description: |-
+                          LogLevel sets the logging level for the offline store service
+                          Allowed values: "debug", "info", "warning", "error", "critical".
+                        enum:
+                        - debug
+                        - info
+                        - warning
+                        - error
+                        - critical
+                        type: string
                       persistence:
                         description: OfflineStorePersistence configures the persistence
                           settings for the offline store service
@@ -584,6 +595,17 @@ spec:
                         description: PullPolicy describes a policy for if/when to
                           pull a container image
                         type: string
+                      logLevel:
+                        description: |-
+                          LogLevel sets the logging level for the online store service
+                          Allowed values: "debug", "info", "warning", "error", "critical".
+                        enum:
+                        - debug
+                        - info
+                        - warning
+                        - error
+                        - critical
+                        type: string
                       persistence:
                         description: OnlineStorePersistence configures the persistence
                           settings for the online store service
@@ -947,6 +969,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the registry service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: RegistryPersistence configures the persistence
                               settings for the registry service
@@ -1437,6 +1470,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the offline store service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: OfflineStorePersistence configures the persistence
                               settings for the offline store service
@@ -1792,6 +1836,17 @@ spec:
                             description: PullPolicy describes a policy for if/when
                               to pull a container image
                             type: string
+                          logLevel:
+                            description: |-
+                              LogLevel sets the logging level for the online store service
+                              Allowed values: "debug", "info", "warning", "error", "critical".
+                            enum:
+                            - debug
+                            - info
+                            - warning
+                            - error
+                            - critical
+                            type: string
                           persistence:
                             description: OnlineStorePersistence configures the persistence
                               settings for the online store service
@@ -2163,6 +2218,17 @@ spec:
                                 description: PullPolicy describes a policy for if/when
                                   to pull a container image
                                 type: string
+                              logLevel:
+                                description: |-
+                                  LogLevel sets the logging level for the registry service
+                                  Allowed values: "debug", "info", "warning", "error", "critical".
+                                enum:
+                                - debug
+                                - info
+                                - warning
+                                - error
+                                - critical
+                                type: string
                               persistence:
                                 description: RegistryPersistence configures the persistence
                                   settings for the registry service
@@ -2894,7 +2960,7 @@ spec:
         - --leader-elect
         command:
         - /manager
-        image: feastdev/feast-operator:0.41.0
+        image: feastdev/feast-operator:0.42.0
         livenessProbe:
           httpGet:
             path: /healthz
diff --git a/infra/feast-operator/internal/controller/services/services.go b/infra/feast-operator/internal/controller/services/services.go
index b1878ee00a..60aabebe02 100644
--- a/infra/feast-operator/internal/controller/services/services.go
+++ b/infra/feast-operator/internal/controller/services/services.go
@@ -355,25 +355,36 @@ func (feast *FeastServices) setDeployment(deploy *appsv1.Deployment, feastType F
 }
 
 func (feast *FeastServices) getContainerCommand(feastType FeastServiceType) []string {
+	baseCommand := "feast"
+	options := []string{}
+	logLevel := feast.getLogLevelForType(feastType)
+	if logLevel != nil {
+		options = append(options, "--log-level", strings.ToUpper(*logLevel))
+	}
+
 	deploySettings := FeastServiceConstants[feastType]
 	targetPort := deploySettings.TargetHttpPort
 	tls := feast.getTlsConfigs(feastType)
 	if tls.IsTLS() {
 		targetPort = deploySettings.TargetHttpsPort
 		feastTlsPath := GetTlsPath(feastType)
-		deploySettings.Command = append(deploySettings.Command, []string{"--key", feastTlsPath + tls.SecretKeyNames.TlsKey,
+		deploySettings.Args = append(deploySettings.Args, []string{"--key", feastTlsPath + tls.SecretKeyNames.TlsKey,
 			"--cert", feastTlsPath + tls.SecretKeyNames.TlsCrt}...)
 	}
-	deploySettings.Command = append(deploySettings.Command, []string{"-p", strconv.Itoa(int(targetPort))}...)
+	deploySettings.Args = append(deploySettings.Args, []string{"-p", strconv.Itoa(int(targetPort))}...)
 
 	if feastType == OfflineFeastType {
 		if tls.IsTLS() && feast.Handler.FeatureStore.Status.Applied.Services.OfflineStore.TLS.VerifyClient != nil {
-			deploySettings.Command = append(deploySettings.Command,
+			deploySettings.Args = append(deploySettings.Args,
 				[]string{"--verify_client", strconv.FormatBool(*feast.Handler.FeatureStore.Status.Applied.Services.OfflineStore.TLS.VerifyClient)}...)
 		}
 	}
 
-	return deploySettings.Command
+	// Combine base command, options, and arguments
+	feastCommand := append([]string{baseCommand}, options...)
+	feastCommand = append(feastCommand, deploySettings.Args...)
+
+	return feastCommand
 }
 
 func (feast *FeastServices) offlineClientPodConfigs(podSpec *corev1.PodSpec) {
@@ -474,6 +485,25 @@ func (feast *FeastServices) getServiceConfigs(feastType FeastServiceType) feastd
 	return feastdevv1alpha1.ServiceConfigs{}
 }
 
+func (feast *FeastServices) getLogLevelForType(feastType FeastServiceType) *string {
+	services := feast.Handler.FeatureStore.Status.Applied.Services
+	switch feastType {
+	case OfflineFeastType:
+		if services.OfflineStore != nil && services.OfflineStore.LogLevel != "" {
+			return &services.OfflineStore.LogLevel
+		}
+	case OnlineFeastType:
+		if services.OnlineStore != nil && services.OnlineStore.LogLevel != "" {
+			return &services.OnlineStore.LogLevel
+		}
+	case RegistryFeastType:
+		if services.Registry != nil && services.Registry.Local.LogLevel != "" {
+			return &services.Registry.Local.LogLevel
+		}
+	}
+	return nil
+}
+
 // GetObjectMeta returns the feast k8s object metadata
 func (feast *FeastServices) GetObjectMeta(feastType FeastServiceType) metav1.ObjectMeta {
 	return metav1.ObjectMeta{Name: feast.GetFeastServiceName(feastType), Namespace: feast.Handler.FeatureStore.Namespace}
diff --git a/infra/feast-operator/internal/controller/services/services_types.go b/infra/feast-operator/internal/controller/services/services_types.go
index 2c454459d8..b7c0f5f048 100644
--- a/infra/feast-operator/internal/controller/services/services_types.go
+++ b/infra/feast-operator/internal/controller/services/services_types.go
@@ -87,17 +87,17 @@ var (
 
 	FeastServiceConstants = map[FeastServiceType]deploymentSettings{
 		OfflineFeastType: {
-			Command:         []string{"feast", "serve_offline", "-h", "0.0.0.0"},
+			Args:            []string{"serve_offline", "-h", "0.0.0.0"},
 			TargetHttpPort:  8815,
 			TargetHttpsPort: 8816,
 		},
 		OnlineFeastType: {
-			Command:         []string{"feast", "serve", "-h", "0.0.0.0"},
+			Args:            []string{"serve", "-h", "0.0.0.0"},
 			TargetHttpPort:  6566,
 			TargetHttpsPort: 6567,
 		},
 		RegistryFeastType: {
-			Command:         []string{"feast", "serve_registry"},
+			Args:            []string{"serve_registry"},
 			TargetHttpPort:  6570,
 			TargetHttpsPort: 6571,
 		},
@@ -234,7 +234,7 @@ type AuthzConfig struct {
 }
 
 type deploymentSettings struct {
-	Command         []string
+	Args            []string
 	TargetHttpPort  int32
 	TargetHttpsPort int32
 }


Test patch:
diff --git a/infra/feast-operator/internal/controller/featurestore_controller_loglevel_test.go b/infra/feast-operator/internal/controller/featurestore_controller_loglevel_test.go
new file mode 100644
index 0000000000..70f33486fc
--- /dev/null
+++ b/infra/feast-operator/internal/controller/featurestore_controller_loglevel_test.go
@@ -0,0 +1,262 @@
+/*
+Copyright 2024 Feast Community.
+
+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 controller
+
+import (
+	"context"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	appsv1 "k8s.io/api/apps/v1"
+	"k8s.io/apimachinery/pkg/api/errors"
+	apimeta "k8s.io/apimachinery/pkg/api/meta"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+	"sigs.k8s.io/controller-runtime/pkg/reconcile"
+
+	"github.com/feast-dev/feast/infra/feast-operator/api/feastversion"
+	feastdevv1alpha1 "github.com/feast-dev/feast/infra/feast-operator/api/v1alpha1"
+	"github.com/feast-dev/feast/infra/feast-operator/internal/controller/handler"
+	"github.com/feast-dev/feast/infra/feast-operator/internal/controller/services"
+)
+
+var _ = Describe("FeatureStore Controller - Feast service LogLevel", func() {
+	Context("When reconciling a FeatureStore resource", func() {
+		const resourceName = "test-loglevel"
+
+		ctx := context.Background()
+
+		typeNamespacedName := types.NamespacedName{
+			Name:      resourceName,
+			Namespace: "default",
+		}
+		featurestore := &feastdevv1alpha1.FeatureStore{}
+
+		BeforeEach(func() {
+			By("creating the custom resource for the Kind FeatureStore")
+			err := k8sClient.Get(ctx, typeNamespacedName, featurestore)
+			if err != nil && errors.IsNotFound(err) {
+				resource := &feastdevv1alpha1.FeatureStore{
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      resourceName,
+						Namespace: "default",
+					},
+					Spec: feastdevv1alpha1.FeatureStoreSpec{
+						FeastProject: feastProject,
+						Services: &feastdevv1alpha1.FeatureStoreServices{
+							Registry: &feastdevv1alpha1.Registry{
+								Local: &feastdevv1alpha1.LocalRegistryConfig{
+									LogLevel: "error",
+								},
+							},
+							OnlineStore: &feastdevv1alpha1.OnlineStore{
+								LogLevel: "debug",
+							},
+							OfflineStore: &feastdevv1alpha1.OfflineStore{
+								LogLevel: "info",
+							},
+						},
+					},
+				}
+				Expect(k8sClient.Create(ctx, resource)).To(Succeed())
+			}
+		})
+		AfterEach(func() {
+			resource := &feastdevv1alpha1.FeatureStore{}
+			err := k8sClient.Get(ctx, typeNamespacedName, resource)
+			Expect(err).NotTo(HaveOccurred())
+
+			By("Cleanup the specific resource instance FeatureStore")
+			Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
+		})
+
+		It("should successfully reconcile the resource with logLevel", func() {
+			By("Reconciling the created resource")
+			controllerReconciler := &FeatureStoreReconciler{
+				Client: k8sClient,
+				Scheme: k8sClient.Scheme(),
+			}
+
+			_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
+				NamespacedName: typeNamespacedName,
+			})
+			Expect(err).NotTo(HaveOccurred())
+
+			resource := &feastdevv1alpha1.FeatureStore{}
+			err = k8sClient.Get(ctx, typeNamespacedName, resource)
+			Expect(err).NotTo(HaveOccurred())
+			feast := services.FeastServices{
+				Handler: handler.FeastHandler{
+					Client:       controllerReconciler.Client,
+					Context:      ctx,
+					Scheme:       controllerReconciler.Scheme,
+					FeatureStore: resource,
+				},
+			}
+
+			Expect(resource.Status).NotTo(BeNil())
+			Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
+			Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
+			Expect(resource.Status.Applied.Services).NotTo(BeNil())
+			Expect(resource.Status.Applied.Services.OfflineStore).NotTo(BeNil())
+			Expect(resource.Status.Applied.Services.OnlineStore).NotTo(BeNil())
+			Expect(resource.Status.Applied.Services.Registry).NotTo(BeNil())
+
+			Expect(resource.Status.Conditions).NotTo(BeEmpty())
+			cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
+			Expect(cond).ToNot(BeNil())
+			Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+			Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
+			Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
+			Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
+
+			cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.RegistryReadyType)
+			Expect(cond).ToNot(BeNil())
+			Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+			Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
+			Expect(cond.Type).To(Equal(feastdevv1alpha1.RegistryReadyType))
+			Expect(cond.Message).To(Equal(feastdevv1alpha1.RegistryReadyMessage))
+
+			cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ClientReadyType)
+			Expect(cond).ToNot(BeNil())
+			Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+			Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
+			Expect(cond.Type).To(Equal(feastdevv1alpha1.ClientReadyType))
+			Expect(cond.Message).To(Equal(feastdevv1alpha1.ClientReadyMessage))
+
+			cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.OfflineStoreReadyType)
+			Expect(cond).ToNot(BeNil())
+			Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+			Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
+			Expect(cond.Type).To(Equal(feastdevv1alpha1.OfflineStoreReadyType))
+			Expect(cond.Message).To(Equal(feastdevv1alpha1.OfflineStoreReadyMessage))
+
+			cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.OnlineStoreReadyType)
+			Expect(cond).ToNot(BeNil())
+			Expect(cond.Status).To(Equal(metav1.ConditionTrue))
+			Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
+			Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
+			Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))
+			Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
+
+			deploy := &appsv1.Deployment{}
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.RegistryFeastType),
+				Namespace: resource.Namespace,
+			},
+				deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Replicas).To(Equal(&services.DefaultReplicas))
+			Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command := deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).To(ContainElement("--log-level"))
+			Expect(command).To(ContainElement("ERROR"))
+
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.OfflineFeastType),
+				Namespace: resource.Namespace,
+			},
+				deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Replicas).To(Equal(&services.DefaultReplicas))
+			Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command = deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).To(ContainElement("--log-level"))
+			Expect(command).To(ContainElement("INFO"))
+
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.OnlineFeastType),
+				Namespace: resource.Namespace,
+			},
+				deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Replicas).To(Equal(&services.DefaultReplicas))
+			Expect(controllerutil.HasControllerReference(deploy)).To(BeTrue())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command = deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).To(ContainElement("--log-level"))
+			Expect(command).To(ContainElement("DEBUG"))
+		})
+
+		It("should not include --log-level parameter when logLevel is not specified for any service", func() {
+			By("Updating the FeatureStore resource without specifying logLevel for any service")
+			resource := &feastdevv1alpha1.FeatureStore{}
+			err := k8sClient.Get(ctx, typeNamespacedName, resource)
+			Expect(err).NotTo(HaveOccurred())
+
+			resource.Spec.Services = &feastdevv1alpha1.FeatureStoreServices{
+				Registry: &feastdevv1alpha1.Registry{
+					Local: &feastdevv1alpha1.LocalRegistryConfig{},
+				},
+				OnlineStore:  &feastdevv1alpha1.OnlineStore{},
+				OfflineStore: &feastdevv1alpha1.OfflineStore{},
+			}
+			Expect(k8sClient.Update(ctx, resource)).To(Succeed())
+
+			controllerReconciler := &FeatureStoreReconciler{
+				Client: k8sClient,
+				Scheme: k8sClient.Scheme(),
+			}
+
+			_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
+				NamespacedName: typeNamespacedName,
+			})
+			Expect(err).NotTo(HaveOccurred())
+
+			feast := services.FeastServices{
+				Handler: handler.FeastHandler{
+					Client:       controllerReconciler.Client,
+					Context:      ctx,
+					Scheme:       controllerReconciler.Scheme,
+					FeatureStore: resource,
+				},
+			}
+
+			deploy := &appsv1.Deployment{}
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.RegistryFeastType),
+				Namespace: resource.Namespace,
+			}, deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command := deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).NotTo(ContainElement("--log-level"))
+
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.OfflineFeastType),
+				Namespace: resource.Namespace,
+			}, deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command = deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).NotTo(ContainElement("--log-level"))
+
+			err = k8sClient.Get(ctx, types.NamespacedName{
+				Name:      feast.GetFeastServiceName(services.OnlineFeastType),
+				Namespace: resource.Namespace,
+			}, deploy)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(deploy.Spec.Template.Spec.Containers).To(HaveLen(1))
+			command = deploy.Spec.Template.Spec.Containers[0].Command
+			Expect(command).NotTo(ContainElement("--log-level"))
+		})
+
+	})
+})