Skip to content

Commit dbe8c44

Browse files
Merge pull request #100 from k-pavlo/lcore-migration
Add independent log level fields for llama-stack and lightspeed-service-api
2 parents 73411c1 + 9f5e97b commit dbe8c44

11 files changed

Lines changed: 261 additions & 13 deletions

api/v1beta1/openstacklightspeed_types.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,28 @@ type OpenStackLightspeedSpec struct {
8686
Database *DatabaseSpec `json:"database,omitempty"`
8787
}
8888

89+
// LoggingConfig defines logging configuration for OpenStackLightspeed components
90+
type LoggingConfig struct {
91+
// +kubebuilder:validation:Optional
92+
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OGX Log Level"
93+
// Log level configuration for the OGX/llama-stack container. Supports standard levels (INFO, DEBUG) or fine-grained control using format "component=level,component=level" (e.g., "core=debug,providers=info"). Defaults to "all=info" if empty.
94+
OGXLogLevel string `json:"ogxLogLevel,omitempty"`
95+
96+
// +kubebuilder:validation:Optional
97+
// +kubebuilder:validation:Enum=DEBUG;INFO;WARNING;ERROR;CRITICAL
98+
// +kubebuilder:default="INFO"
99+
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Lightspeed Stack Log Level"
100+
// Log level for the lightspeed-service-api container. Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
101+
LightspeedStackLogLevel string `json:"lightspeedStackLogLevel,omitempty"`
102+
103+
// +kubebuilder:validation:Optional
104+
// +kubebuilder:validation:Enum=DEBUG;INFO;WARNING;ERROR;CRITICAL
105+
// +kubebuilder:default="INFO"
106+
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Dataverse Exporter Log Level"
107+
// Log level for the dataverse exporter sidecar container. Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
108+
DataverseExporterLogLevel string `json:"dataverseExporterLogLevel,omitempty"`
109+
}
110+
89111
// OpenStackLightspeedCore defines the desired state of OpenStackLightspeed
90112
type OpenStackLightspeedCore struct {
91113
// +kubebuilder:validation:Required
@@ -138,6 +160,10 @@ type OpenStackLightspeedCore struct {
138160
// +kubebuilder:validation:Optional
139161
// Disable conversation transcripts collection
140162
TranscriptsDisabled bool `json:"transcriptsDisabled,omitempty"`
163+
164+
// +kubebuilder:validation:Optional
165+
// Logging configuration for OpenStackLightspeed components
166+
Logging LoggingConfig `json:"logging,omitempty"`
141167
}
142168

143169
// OpenStackLightspeedStatus defines the observed state of OpenStackLightspeed

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,40 @@ spec:
107107
llmProjectID:
108108
description: Project ID for LLM providers that require it (e.g., WatsonX)
109109
type: string
110+
logging:
111+
description: Logging configuration for OpenStackLightspeed components
112+
properties:
113+
dataverseExporterLogLevel:
114+
default: INFO
115+
description: 'Log level for the dataverse exporter sidecar container.
116+
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
117+
CRITICAL.'
118+
enum:
119+
- DEBUG
120+
- INFO
121+
- WARNING
122+
- ERROR
123+
- CRITICAL
124+
type: string
125+
lightspeedStackLogLevel:
126+
default: INFO
127+
description: 'Log level for the lightspeed-service-api container.
128+
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
129+
CRITICAL.'
130+
enum:
131+
- DEBUG
132+
- INFO
133+
- WARNING
134+
- ERROR
135+
- CRITICAL
136+
type: string
137+
ogxLogLevel:
138+
description: Log level configuration for the OGX/llama-stack container.
139+
Supports standard levels (INFO, DEBUG) or fine-grained control
140+
using format "component=level,component=level" (e.g., "core=debug,providers=info").
141+
Defaults to "all=info" if empty.
142+
type: string
143+
type: object
110144
maxTokensForResponse:
111145
description: MaxTokensForResponse defines the maximum number of tokens
112146
to be used for the response generation

bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ metadata:
2525
]
2626
capabilities: Basic Install
2727
categories: AI/Machine Learning
28-
createdAt: "2026-05-27T13:26:52Z"
28+
createdAt: "2026-05-28T16:28:23Z"
2929
description: AI-powered virtual assistant for Red Hat OpenStack Services on OpenShift
3030
features.operators.openshift.io/cnf: "false"
3131
features.operators.openshift.io/cni: "false"
@@ -128,6 +128,19 @@ spec:
128128
- description: Type of the provider serving the LLM
129129
displayName: Provider Type
130130
path: llmEndpointType
131+
- description: 'Log level for the dataverse exporter sidecar container. Supports
132+
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
133+
displayName: Dataverse Exporter Log Level
134+
path: logging.dataverseExporterLogLevel
135+
- description: 'Log level for the lightspeed-service-api container. Supports
136+
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
137+
displayName: Lightspeed Stack Log Level
138+
path: logging.lightspeedStackLogLevel
139+
- description: Log level configuration for the OGX/llama-stack container. Supports
140+
standard levels (INFO, DEBUG) or fine-grained control using format "component=level,component=level"
141+
(e.g., "core=debug,providers=info"). Defaults to "all=info" if empty.
142+
displayName: OGX Log Level
143+
path: logging.ogxLogLevel
131144
- description: Name of the model to use at the API endpoint provided in LLMEndpoint
132145
displayName: Model Name
133146
path: modelName

config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,40 @@ spec:
107107
llmProjectID:
108108
description: Project ID for LLM providers that require it (e.g., WatsonX)
109109
type: string
110+
logging:
111+
description: Logging configuration for OpenStackLightspeed components
112+
properties:
113+
dataverseExporterLogLevel:
114+
default: INFO
115+
description: 'Log level for the dataverse exporter sidecar container.
116+
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
117+
CRITICAL.'
118+
enum:
119+
- DEBUG
120+
- INFO
121+
- WARNING
122+
- ERROR
123+
- CRITICAL
124+
type: string
125+
lightspeedStackLogLevel:
126+
default: INFO
127+
description: 'Log level for the lightspeed-service-api container.
128+
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
129+
CRITICAL.'
130+
enum:
131+
- DEBUG
132+
- INFO
133+
- WARNING
134+
- ERROR
135+
- CRITICAL
136+
type: string
137+
ogxLogLevel:
138+
description: Log level configuration for the OGX/llama-stack container.
139+
Supports standard levels (INFO, DEBUG) or fine-grained control
140+
using format "component=level,component=level" (e.g., "core=debug,providers=info").
141+
Defaults to "all=info" if empty.
142+
type: string
143+
type: object
110144
maxTokensForResponse:
111145
description: MaxTokensForResponse defines the maximum number of tokens
112146
to be used for the response generation

config/manifests/bases/openstack-lightspeed-operator.clusterserviceversion.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ spec:
105105
- description: Type of the provider serving the LLM
106106
displayName: Provider Type
107107
path: llmEndpointType
108+
- description: 'Log level for the dataverse exporter sidecar container. Supports
109+
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
110+
displayName: Dataverse Exporter Log Level
111+
path: logging.dataverseExporterLogLevel
112+
- description: 'Log level for the lightspeed-service-api container. Supports
113+
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
114+
displayName: Lightspeed Stack Log Level
115+
path: logging.lightspeedStackLogLevel
116+
- description: Log level configuration for the OGX/llama-stack container. Supports
117+
standard levels (INFO, DEBUG) or fine-grained control using format "component=level,component=level"
118+
(e.g., "core=debug,providers=info"). Defaults to "all=info" if empty.
119+
displayName: OGX Log Level
120+
path: logging.ogxLogLevel
108121
- description: Name of the model to use at the API endpoint provided in LLMEndpoint
109122
displayName: Model Name
110123
path: modelName

internal/controller/lcore_deployment.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import (
2020
"context"
2121
"fmt"
2222
"path"
23+
"slices"
2324
"strconv"
25+
"strings"
2426

2527
common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
2628
apiv1beta1 "github.com/openstack-lightspeed/operator/api/v1beta1"
@@ -59,7 +61,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins
5961
if err != nil {
6062
return corev1.PodTemplateSpec{}, fmt.Errorf("failed to build llama-stack env vars: %w", err)
6163
}
62-
lsEnvVars := buildLightspeedStackEnvVars()
64+
lsEnvVars := buildLightspeedStackEnvVars(instance)
6365

6466
// Llama Stack container mounts: its config + shared + cache + vector_store_db data
6567
llamaStackMounts := []corev1.VolumeMount{}
@@ -131,7 +133,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins
131133
Args: []string{
132134
"--mode", "openshift",
133135
"--config", path.Join(ExporterConfigMountPath, ExporterConfigFilename),
134-
"--log-level", "INFO",
136+
"--log-level", instance.Spec.Logging.DataverseExporterLogLevel,
135137
"--data-dir", LCoreUserDataMountPath,
136138
},
137139
VolumeMounts: []corev1.VolumeMount{
@@ -586,10 +588,15 @@ func buildLlamaStackEnvVars(h *common_helper.Helper, ctx context.Context, instan
586588
// Postgres password for ${env.POSTGRES_PASSWORD} substitution in llama-stack config
587589
envVars = append(envVars, buildPostgresPasswordEnvVar())
588590

589-
// Logging configuration
591+
// Logging configuration - set both for compatibility with llama-stack and OGX
592+
ogxLogLevel := getOGXLogLevel(instance)
590593
envVars = append(envVars, corev1.EnvVar{
591594
Name: "LLAMA_STACK_LOGGING",
592-
Value: "all=info",
595+
Value: ogxLogLevel,
596+
})
597+
envVars = append(envVars, corev1.EnvVar{
598+
Name: "OGX_LOGGING",
599+
Value: ogxLogLevel,
593600
})
594601

595602
envVars = append(envVars, corev1.EnvVar{
@@ -619,11 +626,11 @@ func buildPostgresPasswordEnvVar() corev1.EnvVar {
619626
}
620627

621628
// buildLightspeedStackEnvVars builds environment variables for the lightspeed-stack container.
622-
func buildLightspeedStackEnvVars() []corev1.EnvVar {
629+
func buildLightspeedStackEnvVars(instance *apiv1beta1.OpenStackLightspeed) []corev1.EnvVar {
623630
return []corev1.EnvVar{
624631
{
625-
Name: "LOG_LEVEL",
626-
Value: "INFO",
632+
Name: "LIGHTSPEED_STACK_LOG_LEVEL",
633+
Value: instance.Spec.Logging.LightspeedStackLogLevel,
627634
},
628635
buildPostgresPasswordEnvVar(),
629636
}
@@ -659,6 +666,28 @@ func buildLightspeedStackReadinessProbe() *corev1.Probe {
659666
}
660667
}
661668

669+
// getOGXLogLevel returns the log level for OGX/llama-stack container.
670+
// Supports either standard levels (INFO, DEBUG, WARNING, ERROR, CRITICAL) or fine-grained control.
671+
// Examples: "INFO" -> "all=info", "DEBUG" -> "all=debug", "core=debug,providers=info" -> "core=debug,providers=info"
672+
// Defaults to "all=info" if not specified.
673+
func getOGXLogLevel(instance *apiv1beta1.OpenStackLightspeed) string {
674+
logLevel := instance.Spec.Logging.OGXLogLevel
675+
if logLevel == "" {
676+
return "all=info"
677+
}
678+
679+
// If it's a simple level (INFO, DEBUG, etc.), convert to "all=<level>" format
680+
// Otherwise, pass through for fine-grained control (e.g., "core=debug,providers=info")
681+
upperLogLevel := strings.ToUpper(logLevel)
682+
allowedLogLevels := []string{"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
683+
if slices.Contains(allowedLogLevels, upperLogLevel) {
684+
return fmt.Sprintf("all=%s", strings.ToLower(logLevel))
685+
}
686+
687+
// Pass through as-is for fine-grained control
688+
return logLevel
689+
}
690+
662691
// buildConfigMapAnnotations builds annotations with configmap resource versions
663692
// so that changes to the configmaps trigger a deployment rollout.
664693
func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (map[string]string, error) {

test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,47 @@ spec:
149149
template:
150150
spec:
151151
containers:
152-
- name: llama-stack
153-
- name: lightspeed-service-api
154-
- name: lightspeed-to-dataverse-exporter
152+
- name: llama-stack
153+
env:
154+
- name: OPENSTACK_LIGHTSPEED_PROVIDER_API_KEY
155+
valueFrom:
156+
secretKeyRef:
157+
key: apitoken
158+
name: openstack-lightspeed-apitoken
159+
- name: POSTGRES_PASSWORD
160+
valueFrom:
161+
secretKeyRef:
162+
key: password
163+
name: lightspeed-postgres-secret
164+
- name: LLAMA_STACK_LOGGING
165+
value: all=debug
166+
- name: OGX_LOGGING
167+
value: all=debug
168+
- name: VECTOR_DB_DATA_PATH
169+
value: /vector-db-discovered-values
170+
- name: REQUESTS_CA_BUNDLE
171+
value: /etc/certs/additional-ca/cert.crt
172+
- name: SSL_CERT_FILE
173+
value: /etc/certs/additional-ca/cert.crt
174+
- name: lightspeed-service-api
175+
env:
176+
- name: LIGHTSPEED_STACK_LOG_LEVEL
177+
value: WARNING
178+
- name: POSTGRES_PASSWORD
179+
valueFrom:
180+
secretKeyRef:
181+
key: password
182+
name: lightspeed-postgres-secret
183+
- name: lightspeed-to-dataverse-exporter
184+
args:
185+
- --mode
186+
- openshift
187+
- --config
188+
- /etc/config/config.yaml
189+
- --log-level
190+
- DEBUG
191+
- --data-dir
192+
- /tmp/data
155193
status:
156194
replicas: 1
157195
readyReplicas: 1
@@ -241,6 +279,9 @@ spec:
241279
llmProjectID: test-project-id
242280
llmDeploymentName: test-deployment-name
243281
llmAPIVersion: v1
282+
logging:
283+
ogxLogLevel: DEBUG
284+
lightspeedStackLogLevel: WARNING
244285
status:
245286
conditions:
246287
- type: Ready

test/kuttl/common/openstack-lightspeed-instance/create-openstack-lightspeed-instance.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ spec:
1414
llmDeploymentName: test-deployment-name
1515
llmAPIVersion: v1
1616
enableOCPRAG: false
17+
logging:
18+
ogxLogLevel: DEBUG
19+
lightspeedStackLogLevel: WARNING
20+
dataverseExporterLogLevel: DEBUG

test/kuttl/tests/update-openstacklightspeed/07-update-openstack-lightspeed-instance.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ spec:
3535
# We can set it to `true` once the OCP contant is present in the image.
3636
enableOCPRAG: false
3737
ocpVersionOverride: "4.16"
38+
logging:
39+
ogxLogLevel: "core=debug,providers=info"
40+
lightspeedStackLogLevel: ERROR
41+
dataverseExporterLogLevel: ERROR

0 commit comments

Comments
 (0)