Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions api/v1beta1/openstacklightspeed_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ type OpenStackLightspeedSpec struct {
Database *DatabaseSpec `json:"database,omitempty"`
}

// LoggingConfig defines logging configuration for OpenStackLightspeed components
type LoggingConfig struct {
Comment thread
lpiwowar marked this conversation as resolved.
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="OGX Log Level"
// 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.
OGXLogLevel string `json:"ogxLogLevel,omitempty"`

// +kubebuilder:validation:Optional
// +kubebuilder:validation:Enum=DEBUG;INFO;WARNING;ERROR;CRITICAL
// +kubebuilder:default="INFO"
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Lightspeed Stack Log Level"
// Log level for the lightspeed-service-api container. Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
LightspeedStackLogLevel string `json:"lightspeedStackLogLevel,omitempty"`

// +kubebuilder:validation:Optional
// +kubebuilder:validation:Enum=DEBUG;INFO;WARNING;ERROR;CRITICAL
// +kubebuilder:default="INFO"
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Dataverse Exporter Log Level"
// Log level for the dataverse exporter sidecar container. Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.
DataverseExporterLogLevel string `json:"dataverseExporterLogLevel,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this!

}

// OpenStackLightspeedCore defines the desired state of OpenStackLightspeed
type OpenStackLightspeedCore struct {
// +kubebuilder:validation:Required
Expand Down Expand Up @@ -138,6 +160,10 @@ type OpenStackLightspeedCore struct {
// +kubebuilder:validation:Optional
// Disable conversation transcripts collection
TranscriptsDisabled bool `json:"transcriptsDisabled,omitempty"`

// +kubebuilder:validation:Optional
// Logging configuration for OpenStackLightspeed components
Logging LoggingConfig `json:"logging,omitempty"`
}

// OpenStackLightspeedStatus defines the observed state of OpenStackLightspeed
Expand Down
16 changes: 16 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,40 @@ spec:
llmProjectID:
description: Project ID for LLM providers that require it (e.g., WatsonX)
type: string
logging:
description: Logging configuration for OpenStackLightspeed components
properties:
dataverseExporterLogLevel:
default: INFO
description: 'Log level for the dataverse exporter sidecar container.
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
CRITICAL.'
enum:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
type: string
lightspeedStackLogLevel:
default: INFO
description: 'Log level for the lightspeed-service-api container.
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
CRITICAL.'
enum:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
type: string
ogxLogLevel:
description: 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.
type: string
type: object
maxTokensForResponse:
description: MaxTokensForResponse defines the maximum number of tokens
to be used for the response generation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ metadata:
]
capabilities: Basic Install
categories: AI/Machine Learning
createdAt: "2026-05-27T13:26:52Z"
createdAt: "2026-05-28T16:28:23Z"
description: AI-powered virtual assistant for Red Hat OpenStack Services on OpenShift
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
Expand Down Expand Up @@ -128,6 +128,19 @@ spec:
- description: Type of the provider serving the LLM
displayName: Provider Type
path: llmEndpointType
- description: 'Log level for the dataverse exporter sidecar container. Supports
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
displayName: Dataverse Exporter Log Level
path: logging.dataverseExporterLogLevel
- description: 'Log level for the lightspeed-service-api container. Supports
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
displayName: Lightspeed Stack Log Level
path: logging.lightspeedStackLogLevel
- description: 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.
displayName: OGX Log Level
path: logging.ogxLogLevel
- description: Name of the model to use at the API endpoint provided in LLMEndpoint
displayName: Model Name
path: modelName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,40 @@ spec:
llmProjectID:
description: Project ID for LLM providers that require it (e.g., WatsonX)
type: string
logging:
description: Logging configuration for OpenStackLightspeed components
properties:
dataverseExporterLogLevel:
default: INFO
description: 'Log level for the dataverse exporter sidecar container.
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
CRITICAL.'
enum:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
type: string
lightspeedStackLogLevel:
default: INFO
description: 'Log level for the lightspeed-service-api container.
Supports standard Python log levels: DEBUG, INFO, WARNING, ERROR,
CRITICAL.'
enum:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
type: string
ogxLogLevel:
description: 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.
type: string
type: object
maxTokensForResponse:
description: MaxTokensForResponse defines the maximum number of tokens
to be used for the response generation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ spec:
- description: Type of the provider serving the LLM
displayName: Provider Type
path: llmEndpointType
- description: 'Log level for the dataverse exporter sidecar container. Supports
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
displayName: Dataverse Exporter Log Level
path: logging.dataverseExporterLogLevel
- description: 'Log level for the lightspeed-service-api container. Supports
standard Python log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL.'
displayName: Lightspeed Stack Log Level
path: logging.lightspeedStackLogLevel
- description: 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.
displayName: OGX Log Level
path: logging.ogxLogLevel
- description: Name of the model to use at the API endpoint provided in LLMEndpoint
displayName: Model Name
path: modelName
Expand Down
43 changes: 36 additions & 7 deletions internal/controller/lcore_deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import (
"context"
"fmt"
"path"
"slices"
"strconv"
"strings"

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

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

// Logging configuration
// Logging configuration - set both for compatibility with llama-stack and OGX
ogxLogLevel := getOGXLogLevel(instance)
envVars = append(envVars, corev1.EnvVar{
Name: "LLAMA_STACK_LOGGING",
Comment thread
k-pavlo marked this conversation as resolved.
Value: "all=info",
Value: ogxLogLevel,
})
envVars = append(envVars, corev1.EnvVar{
Name: "OGX_LOGGING",
Value: ogxLogLevel,
})

envVars = append(envVars, corev1.EnvVar{
Expand Down Expand Up @@ -619,11 +626,11 @@ func buildPostgresPasswordEnvVar() corev1.EnvVar {
}

// buildLightspeedStackEnvVars builds environment variables for the lightspeed-stack container.
func buildLightspeedStackEnvVars() []corev1.EnvVar {
func buildLightspeedStackEnvVars(instance *apiv1beta1.OpenStackLightspeed) []corev1.EnvVar {
return []corev1.EnvVar{
{
Name: "LOG_LEVEL",
Value: "INFO",
Name: "LIGHTSPEED_STACK_LOG_LEVEL",
Value: instance.Spec.Logging.LightspeedStackLogLevel,
},
buildPostgresPasswordEnvVar(),
}
Expand Down Expand Up @@ -659,6 +666,28 @@ func buildLightspeedStackReadinessProbe() *corev1.Probe {
}
}

// getOGXLogLevel returns the log level for OGX/llama-stack container.
// Supports either standard levels (INFO, DEBUG, WARNING, ERROR, CRITICAL) or fine-grained control.
// Examples: "INFO" -> "all=info", "DEBUG" -> "all=debug", "core=debug,providers=info" -> "core=debug,providers=info"
// Defaults to "all=info" if not specified.
func getOGXLogLevel(instance *apiv1beta1.OpenStackLightspeed) string {
logLevel := instance.Spec.Logging.OGXLogLevel
if logLevel == "" {
return "all=info"
}

// If it's a simple level (INFO, DEBUG, etc.), convert to "all=<level>" format
// Otherwise, pass through for fine-grained control (e.g., "core=debug,providers=info")
upperLogLevel := strings.ToUpper(logLevel)
allowedLogLevels := []string{"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
if slices.Contains(allowedLogLevels, upperLogLevel) {
return fmt.Sprintf("all=%s", strings.ToLower(logLevel))
}

// Pass through as-is for fine-grained control
return logLevel
}

// buildConfigMapAnnotations builds annotations with configmap resource versions
// so that changes to the configmaps trigger a deployment rollout.
func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (map[string]string, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,47 @@ spec:
template:
spec:
containers:
- name: llama-stack
- name: lightspeed-service-api
- name: lightspeed-to-dataverse-exporter
- name: llama-stack
env:
- name: OPENSTACK_LIGHTSPEED_PROVIDER_API_KEY
valueFrom:
secretKeyRef:
key: apitoken
name: openstack-lightspeed-apitoken
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: lightspeed-postgres-secret
- name: LLAMA_STACK_LOGGING
value: all=debug
- name: OGX_LOGGING
value: all=debug
- name: VECTOR_DB_DATA_PATH
value: /vector-db-discovered-values
- name: REQUESTS_CA_BUNDLE
value: /etc/certs/additional-ca/cert.crt
- name: SSL_CERT_FILE
value: /etc/certs/additional-ca/cert.crt
- name: lightspeed-service-api
env:
- name: LIGHTSPEED_STACK_LOG_LEVEL
value: WARNING
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: lightspeed-postgres-secret
- name: lightspeed-to-dataverse-exporter
args:
- --mode
- openshift
- --config
- /etc/config/config.yaml
- --log-level
- DEBUG
- --data-dir
- /tmp/data
status:
replicas: 1
readyReplicas: 1
Expand Down Expand Up @@ -241,6 +279,9 @@ spec:
llmProjectID: test-project-id
llmDeploymentName: test-deployment-name
llmAPIVersion: v1
logging:
Comment thread
lpiwowar marked this conversation as resolved.
ogxLogLevel: DEBUG
lightspeedStackLogLevel: WARNING
status:
conditions:
- type: Ready
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ spec:
llmDeploymentName: test-deployment-name
llmAPIVersion: v1
enableOCPRAG: false
logging:
ogxLogLevel: DEBUG
lightspeedStackLogLevel: WARNING
dataverseExporterLogLevel: DEBUG
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ spec:
# We can set it to `true` once the OCP contant is present in the image.
enableOCPRAG: false
ocpVersionOverride: "4.16"
logging:
ogxLogLevel: "core=debug,providers=info"
lightspeedStackLogLevel: ERROR
dataverseExporterLogLevel: ERROR
Loading
Loading