Skip to content

Commit 910ba94

Browse files
committed
refactor: consolidatev2 logging
1 parent 4859215 commit 910ba94

11 files changed

Lines changed: 269 additions & 1103 deletions

File tree

rust/operator-binary/src/command.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use stackable_operator::{
2-
product_logging::{
3-
framework::{create_vector_shutdown_file_command, remove_vector_shutdown_file_command},
4-
spec::{ContainerLogConfig, ContainerLogConfigChoice},
2+
product_logging::framework::{
3+
create_vector_shutdown_file_command, remove_vector_shutdown_file_command,
54
},
65
utils::COMMON_BASH_TRAP_FUNCTIONS,
6+
v2::product_logging::framework::ValidatedContainerLogConfigChoice,
77
};
88

99
use crate::{
@@ -36,10 +36,7 @@ pub fn container_prepare_args(
3636
let mut args = vec![];
3737

3838
// Copy custom logging provided `log.properties` to rw config
39-
if let Some(ContainerLogConfig {
40-
choice: Some(ContainerLogConfigChoice::Custom(_)),
41-
}) = merged_config.logging.containers.get(&Container::Trino)
42-
{
39+
if let ValidatedContainerLogConfigChoice::Custom(_) = merged_config.logging.trino_container {
4340
// copy config files to a writeable empty folder
4441
args.push(format!(
4542
"echo copying {STACKABLE_LOG_CONFIG_DIR}/{LOG_PROPERTIES} {rw_conf}/{LOG_PROPERTIES}",

rust/operator-binary/src/controller/build/properties/log_properties.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ pub fn build(rg: &TrinoRoleGroupConfig) -> BTreeMap<String, String> {
1313

1414
// 1. No defaults
1515
// 2. Automatic per-container logger levels
16-
if let Some(per_container) = super::logging::get_log_property_map(&rg.config.logging) {
16+
if let Some(per_container) =
17+
super::logging::get_log_property_map(&rg.config.logging.trino_container)
18+
{
1719
props.extend(per_container);
1820
}
1921

Lines changed: 29 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
1+
use std::collections::BTreeMap;
2+
13
use stackable_operator::{
2-
kube::runtime::reflector::ObjectRef,
3-
product_logging::{
4-
framework::create_vector_config,
5-
spec::{
6-
AutomaticContainerLogConfig, ContainerLogConfig, ContainerLogConfigChoice, LogLevel,
7-
Logging,
8-
},
9-
},
10-
role_utils::RoleGroupRef,
4+
product_logging::spec::{AutomaticContainerLogConfig, LogLevel},
5+
v2::product_logging::framework::ValidatedContainerLogConfigChoice,
116
};
127
use strum::Display;
138

14-
use crate::{
15-
controller::ValidatedCluster,
16-
crd::{Container, TrinoRole},
17-
};
18-
199
#[derive(Display)]
2010
#[strum(serialize_all = "lowercase")]
2111
pub enum TrinoLogLevel {
@@ -38,63 +28,31 @@ impl From<LogLevel> for TrinoLogLevel {
3828
}
3929
}
4030

41-
/// Return the `log.properties` content as a typed `BTreeMap`.
31+
/// Return the `log.properties` content as a typed `BTreeMap` for the (validated) Trino container.
32+
///
33+
/// Returns `None` when the Trino container uses a custom log ConfigMap (in which case the operator
34+
/// does not generate `log.properties`).
4235
pub fn get_log_property_map(
43-
logging: &Logging<Container>,
44-
) -> Option<std::collections::BTreeMap<String, String>> {
45-
if let Some(ContainerLogConfig {
46-
choice: Some(ContainerLogConfigChoice::Automatic(log_config)),
47-
}) = logging.containers.get(&Container::Trino)
48-
{
49-
let map = log_config
50-
.loggers
51-
.iter()
52-
.map(|(logger, config)| {
53-
let log_level = TrinoLogLevel::from(config.level);
54-
let key = if logger == AutomaticContainerLogConfig::ROOT_LOGGER {
55-
// ROOT logger maps to an empty key in log.properties (=LEVEL).
56-
String::new()
57-
} else {
58-
logger.clone()
59-
};
60-
(key, log_level.to_string())
61-
})
62-
.collect();
63-
Some(map)
64-
} else {
65-
None
66-
}
67-
}
68-
69-
/// Return the vector toml configuration
70-
pub fn get_vector_toml(
71-
cluster: &ValidatedCluster,
72-
role: &TrinoRole,
73-
role_group_name: &str,
74-
logging: &Logging<Container>,
75-
) -> Option<String> {
76-
let vector_log_config = if let Some(ContainerLogConfig {
77-
choice: Some(ContainerLogConfigChoice::Automatic(log_config)),
78-
}) = logging.containers.get(&Container::Vector)
79-
{
80-
Some(log_config)
81-
} else {
82-
None
83-
};
84-
85-
if logging.enable_vector_agent {
86-
// The legacy `create_vector_config` still requires a `RoleGroupRef`, but ignores it
87-
// entirely when rendering the config. We construct a throwaway one here so the rest of the
88-
// operator no longer has to thread `RoleGroupRef` around.
89-
// TODO(step-5): drop this once logging moves to the `v2` framework (`include_str!`-based
90-
// `vector.yaml`), which does not need a `RoleGroupRef`.
91-
let rolegroup_ref = RoleGroupRef {
92-
cluster: ObjectRef::from_obj(cluster),
93-
role: role.to_string(),
94-
role_group: role_group_name.to_owned(),
95-
};
96-
Some(create_vector_config(&rolegroup_ref, vector_log_config))
97-
} else {
98-
None
36+
trino_container: &ValidatedContainerLogConfigChoice,
37+
) -> Option<BTreeMap<String, String>> {
38+
match trino_container {
39+
ValidatedContainerLogConfigChoice::Automatic(log_config) => {
40+
let map = log_config
41+
.loggers
42+
.iter()
43+
.map(|(logger, config)| {
44+
let log_level = TrinoLogLevel::from(config.level);
45+
let key = if logger == AutomaticContainerLogConfig::ROOT_LOGGER {
46+
// ROOT logger maps to an empty key in log.properties (=LEVEL).
47+
String::new()
48+
} else {
49+
logger.clone()
50+
};
51+
(key, log_level.to_string())
52+
})
53+
.collect();
54+
Some(map)
55+
}
56+
ValidatedContainerLogConfigChoice::Custom(_) => None,
9957
}
10058
}

rust/operator-binary/src/controller/build/properties/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub mod exchange_manager_properties;
1111
pub mod log_properties;
1212
pub mod logging;
1313
pub mod node_properties;
14+
pub mod product_logging;
1415
pub mod security_properties;
1516
pub mod spooling_manager_properties;
1617

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! The Vector agent configuration (`vector.yaml`) assembled into the rolegroup `ConfigMap`.
2+
3+
/// The Vector agent configuration (`vector.yaml`).
4+
///
5+
/// It is templated with environment variables (`${LOG_DIR}`, `${NAMESPACE}`, …) that the
6+
/// `v2` Vector container injects at runtime, so the same file content is used for every
7+
/// rolegroup.
8+
const VECTOR_CONFIG: &str = include_str!("vector.yaml");
9+
10+
/// Returns the Vector agent config (`vector.yaml`) content.
11+
pub fn vector_config_file_content() -> String {
12+
VECTOR_CONFIG.to_owned()
13+
}
14+
15+
#[cfg(test)]
16+
mod tests {
17+
use super::*;
18+
19+
#[test]
20+
fn test_vector_config_file_content() {
21+
let content = vector_config_file_content();
22+
assert!(!content.is_empty());
23+
// The airlift source must be present (Trino's main log format) ...
24+
assert!(content.contains("files_airlift"));
25+
// ... while the aggregator sink must reference the injected address.
26+
assert!(content.contains("${VECTOR_AGGREGATOR_ADDRESS}"));
27+
}
28+
}

rust/operator-binary/src/controller/build/resource/config_map.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use stackable_operator::{
77
builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder},
88
k8s_openapi::api::core::v1::ConfigMap,
99
kvp::ObjectLabels,
10-
product_logging,
10+
product_logging::framework::VECTOR_CONFIG_FILE,
1111
utils::cluster_info::KubernetesClusterInfo,
1212
v2::config_file_writer::to_java_properties_string,
1313
};
@@ -18,7 +18,7 @@ use crate::{
1818
ValidatedCluster,
1919
build::properties::{
2020
ConfigFileName, access_control_properties, config_properties,
21-
exchange_manager_properties, log_properties, logging::get_vector_toml, node_properties,
21+
exchange_manager_properties, log_properties, node_properties, product_logging,
2222
security_properties, spooling_manager_properties,
2323
},
2424
},
@@ -180,11 +180,12 @@ pub fn build_rolegroup_config_map(
180180
.context(BuildJvmConfigSnafu)?;
181181
data.insert(JVM_CONFIG.to_string(), jvm_config);
182182

183-
// 9. Vector sidecar toml if enabled.
184-
if let Some(vector_toml) = get_vector_toml(cluster, role, role_group_name, &rg.config.logging) {
183+
// 9. Vector agent config (`vector.yaml`) if the Vector agent is enabled. The file is templated
184+
// with environment variables injected by the v2 Vector container at runtime.
185+
if rg.config.logging.enable_vector_agent {
185186
data.insert(
186-
product_logging::framework::VECTOR_CONFIG_FILE.to_string(),
187-
vector_toml,
187+
VECTOR_CONFIG_FILE.to_string(),
188+
product_logging::vector_config_file_content(),
188189
);
189190
}
190191

rust/operator-binary/src/controller/build/resource/statefulset.rs

Lines changed: 45 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Builds the per-rolegroup [`StatefulSet`] that runs a Trino role group.
22
3-
use std::{collections::BTreeMap, convert::Infallible};
3+
use std::{collections::BTreeMap, convert::Infallible, str::FromStr};
44

55
use snafu::{OptionExt, ResultExt, Snafu};
66
use stackable_operator::{
@@ -31,16 +31,13 @@ use stackable_operator::{
3131
apimachinery::pkg::{apis::meta::v1::LabelSelector, util::intstr::IntOrString},
3232
},
3333
kvp::{Annotation, Annotations, Labels},
34-
product_logging::{
35-
self,
36-
framework::LoggingError,
37-
spec::{
38-
ConfigMapLogConfig, ContainerLogConfig, ContainerLogConfigChoice,
39-
CustomContainerLogConfig,
40-
},
41-
},
34+
product_logging,
4235
shared::time::Duration,
43-
v2::builder::pod::container::EnvVarSet,
36+
v2::{
37+
builder::pod::container::EnvVarSet,
38+
product_logging::framework::{ValidatedContainerLogConfigChoice, vector_container},
39+
types::kubernetes::{ContainerName, VolumeName},
40+
},
4441
};
4542

4643
use crate::{
@@ -59,16 +56,23 @@ use crate::{
5956
crd::{
6057
APP_NAME, CONFIG_DIR_NAME, Container, ENV_INTERNAL_SECRET, ENV_SPOOLING_SECRET, HTTP_PORT,
6158
HTTP_PORT_NAME, HTTPS_PORT, HTTPS_PORT_NAME, MAX_TRINO_LOG_FILES_SIZE, METRICS_PORT,
62-
METRICS_PORT_NAME, RW_CONFIG_DIR_NAME, STACKABLE_CLIENT_TLS_DIR, STACKABLE_INTERNAL_TLS_DIR,
63-
STACKABLE_MOUNT_INTERNAL_TLS_DIR, STACKABLE_MOUNT_SERVER_TLS_DIR, STACKABLE_SERVER_TLS_DIR,
64-
STACKABLE_TLS_STORE_PASSWORD, TrinoRole, v1alpha1,
59+
METRICS_PORT_NAME, RW_CONFIG_DIR_NAME, STACKABLE_CLIENT_TLS_DIR,
60+
STACKABLE_INTERNAL_TLS_DIR, STACKABLE_MOUNT_INTERNAL_TLS_DIR,
61+
STACKABLE_MOUNT_SERVER_TLS_DIR, STACKABLE_SERVER_TLS_DIR, STACKABLE_TLS_STORE_PASSWORD,
62+
TrinoRole, v1alpha1,
6563
},
6664
trino_controller::{
6765
MAX_PREPARE_LOG_FILE_SIZE, STACKABLE_LOG_CONFIG_DIR, STACKABLE_LOG_DIR,
6866
build_recommended_labels, shared_internal_secret_name, shared_spooling_secret_name,
6967
},
7068
};
7169

70+
stackable_operator::constant!(VECTOR_CONTAINER_NAME: ContainerName = "vector");
71+
// The Vector agent reads its `vector.yaml` from the rolegroup ConfigMap (mounted as the "config"
72+
// volume) and writes its state under the shared "log" volume.
73+
stackable_operator::constant!(VECTOR_LOG_CONFIG_VOLUME_NAME: VolumeName = "config");
74+
stackable_operator::constant!(VECTOR_LOG_VOLUME_NAME: VolumeName = "log");
75+
7276
#[derive(Snafu, Debug)]
7377
pub enum Error {
7478
#[snafu(display("missing secret lifetime"))]
@@ -88,12 +92,6 @@ pub enum Error {
8892
container_name: String,
8993
},
9094

91-
#[snafu(display("vector agent is enabled but vector aggregator ConfigMap is missing"))]
92-
VectorAggregatorConfigMapMissing,
93-
94-
#[snafu(display("failed to build vector container"))]
95-
BuildVectorContainer { source: LoggingError },
96-
9795
#[snafu(display("failed to configure graceful shutdown"))]
9896
GracefulShutdown {
9997
source: build::graceful_shutdown::Error,
@@ -263,9 +261,8 @@ pub fn build_rolegroup_statefulset(
263261
)?;
264262

265263
let mut prepare_args = vec![];
266-
if let Some(ContainerLogConfig {
267-
choice: Some(ContainerLogConfigChoice::Automatic(log_config)),
268-
}) = merged_config.logging.containers.get(&Container::Prepare)
264+
if let ValidatedContainerLogConfigChoice::Automatic(log_config) =
265+
&merged_config.logging.prepare_container
269266
{
270267
prepare_args.push(product_logging::framework::capture_shell_output(
271268
STACKABLE_LOG_DIR,
@@ -380,60 +377,33 @@ pub fn build_rolegroup_statefulset(
380377
// add password-update container if required
381378
trino_authentication_config.add_authentication_containers(trino_role, &mut pod_builder);
382379

383-
if let Some(ContainerLogConfig {
384-
choice:
385-
Some(ContainerLogConfigChoice::Custom(CustomContainerLogConfig {
386-
custom: ConfigMapLogConfig { config_map },
387-
})),
388-
}) = merged_config.logging.containers.get(&Container::Trino)
389-
{
390-
pod_builder
391-
.add_volume(Volume {
392-
name: "log-config".to_string(),
393-
config_map: Some(ConfigMapVolumeSource {
394-
name: config_map.into(),
395-
..ConfigMapVolumeSource::default()
396-
}),
397-
..Volume::default()
398-
})
399-
.context(AddVolumeSnafu)?;
400-
} else {
401-
pod_builder
402-
.add_volume(Volume {
403-
name: "log-config".to_string(),
404-
config_map: Some(ConfigMapVolumeSource {
405-
name: config_map_name.clone(),
406-
..ConfigMapVolumeSource::default()
407-
}),
408-
..Volume::default()
409-
})
410-
.context(AddVolumeSnafu)?;
411-
}
380+
// The log-config volume mounts either the rolegroup ConfigMap (which carries the automatic
381+
// `log.properties`) or a user-provided custom ConfigMap, depending on the validated choice.
382+
let log_config_volume_config_map = match &merged_config.logging.trino_container {
383+
ValidatedContainerLogConfigChoice::Custom(config_map) => config_map.to_string(),
384+
ValidatedContainerLogConfigChoice::Automatic(_) => config_map_name.clone(),
385+
};
386+
pod_builder
387+
.add_volume(Volume {
388+
name: "log-config".to_string(),
389+
config_map: Some(ConfigMapVolumeSource {
390+
name: log_config_volume_config_map,
391+
..ConfigMapVolumeSource::default()
392+
}),
393+
..Volume::default()
394+
})
395+
.context(AddVolumeSnafu)?;
412396

413-
if merged_config.logging.enable_vector_agent {
414-
match &trino.spec.cluster_config.vector_aggregator_config_map_name {
415-
Some(vector_aggregator_config_map_name) => {
416-
pod_builder.add_container(
417-
product_logging::framework::vector_container(
418-
resolved_product_image,
419-
"config",
420-
"log",
421-
merged_config.logging.containers.get(&Container::Vector),
422-
ResourceRequirementsBuilder::new()
423-
.with_cpu_request("250m")
424-
.with_cpu_limit("500m")
425-
.with_memory_request("128Mi")
426-
.with_memory_limit("128Mi")
427-
.build(),
428-
vector_aggregator_config_map_name,
429-
)
430-
.context(BuildVectorContainerSnafu)?,
431-
);
432-
}
433-
None => {
434-
VectorAggregatorConfigMapMissingSnafu.fail()?;
435-
}
436-
}
397+
if let Some(vector_log_config) = &merged_config.logging.vector_container {
398+
pod_builder.add_container(vector_container(
399+
&VECTOR_CONTAINER_NAME,
400+
resolved_product_image,
401+
vector_log_config,
402+
&resource_names,
403+
&VECTOR_LOG_CONFIG_VOLUME_NAME,
404+
&VECTOR_LOG_VOLUME_NAME,
405+
EnvVarSet::new(),
406+
));
437407
}
438408

439409
let metadata = ObjectMetaBuilder::new()

0 commit comments

Comments
 (0)