Skip to content

Commit 7ac6820

Browse files
committed
refactor: Add ValidatedHbaseConfig, adapt to v2 logging & add vector tests
1 parent 467c3d5 commit 7ac6820

10 files changed

Lines changed: 639 additions & 185 deletions

File tree

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

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//! Renders the logging config files (`log4j2.properties` and the Vector agent config)
2+
//! assembled into the rolegroup `ConfigMap`.
3+
4+
pub use stackable_operator::v2::product_logging::framework::STACKABLE_LOG_DIR;
5+
use stackable_operator::{
6+
memory::{BinaryMultiple, MemoryQuantity},
7+
product_logging::{self, spec::AutomaticContainerLogConfig},
8+
v2::product_logging::framework::ValidatedContainerLogConfigChoice,
9+
};
10+
11+
pub const MAX_HBASE_LOG_FILES_SIZE: MemoryQuantity = MemoryQuantity {
12+
value: 10.0,
13+
unit: BinaryMultiple::Mebi,
14+
};
15+
16+
const CONSOLE_CONVERSION_PATTERN: &str = "%d{ISO8601} %-5p [%t] %c{2}: %.1000m%n";
17+
const HBASE_LOG4J2_FILE: &str = "hbase.log4j2.xml";
18+
19+
/// The Vector agent configuration (`vector.yaml`).
20+
///
21+
/// This is a static, env-var-parameterized file (mirroring the hive- and opensearch-operators).
22+
/// It is validated by the `test-vector.sh` / `vector-test.yaml` harness next to this file.
23+
const VECTOR_CONFIG: &str = include_str!("vector.yaml");
24+
25+
/// Returns the Vector agent config (`vector.yaml`) content.
26+
pub fn vector_config_file_content() -> String {
27+
VECTOR_CONFIG.to_owned()
28+
}
29+
30+
/// Renders `log4j2.properties` for the HBase container.
31+
///
32+
/// Returns `None` when the HBase container uses a custom log ConfigMap instead of the operator's
33+
/// automatic logging configuration, in which case no `log4j2.properties` should be added to the
34+
/// rolegroup `ConfigMap`.
35+
pub fn build_log4j2(hbase_container: &ValidatedContainerLogConfigChoice) -> Option<String> {
36+
match hbase_container {
37+
ValidatedContainerLogConfigChoice::Automatic(log_config) => Some(log4j_config(log_config)),
38+
ValidatedContainerLogConfigChoice::Custom(_) => None,
39+
}
40+
}
41+
42+
fn log4j_config(log_config: &AutomaticContainerLogConfig) -> String {
43+
product_logging::framework::create_log4j2_config(
44+
&format!("{STACKABLE_LOG_DIR}/hbase"),
45+
HBASE_LOG4J2_FILE,
46+
MAX_HBASE_LOG_FILES_SIZE
47+
.scale_to(BinaryMultiple::Mebi)
48+
.floor()
49+
.value as u32,
50+
CONSOLE_CONVERSION_PATTERN,
51+
log_config,
52+
)
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
59+
#[test]
60+
fn test_vector_config_file_content() {
61+
let content = vector_config_file_content();
62+
assert!(!content.is_empty());
63+
// A kept source must be present ...
64+
assert!(content.contains("files_log4j2"));
65+
// ... while a product-specific source we don't emit must not.
66+
assert!(!content.contains("files_tracing_rs"));
67+
}
68+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env sh
2+
3+
DATA_DIR=/stackable/log/_vector-state \
4+
LOG_DIR=/stackable/log \
5+
NAMESPACE=default \
6+
CLUSTER_NAME=hbase \
7+
ROLE_NAME=regionserver \
8+
ROLE_GROUP_NAME=default \
9+
VECTOR_AGGREGATOR_ADDRESS=vector-aggregator \
10+
VECTOR_FILE_LOG_LEVEL=info \
11+
vector test vector.yaml vector-test.yaml
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Run tests with `./test-vector.sh`
2+
#
3+
# A downside of these test cases is that they compare the whole event and that the message can
4+
# contain source code positions in vector.yaml, e.g. "function call error for \"parse_xml\" at
5+
# (584:643)". Please adapt the tests if you change VRL code in vector.yaml.
6+
---
7+
tests:
8+
- name: Test stdout log entry
9+
inputs:
10+
- type: log
11+
insert_at: processed_files_stdout
12+
log_fields:
13+
file: /stackable/log/hbase/hbase.stdout.log
14+
message: Starting HRegionServer
15+
pod: hbase-regionserver-default-0
16+
source_type: file
17+
timestamp: 2025-10-02T09:27:28.582Z
18+
outputs:
19+
- extract_from: extended_logs
20+
conditions:
21+
- type: vrl
22+
source: |
23+
expected_log_event = {
24+
"cluster": "hbase",
25+
"container": "hbase",
26+
"file": "hbase.stdout.log",
27+
"level": "INFO",
28+
"logger": "ROOT",
29+
"message": "Starting HRegionServer",
30+
"namespace": "default",
31+
"pod": "hbase-regionserver-default-0",
32+
"role": "regionserver",
33+
"roleGroup": "default",
34+
"timestamp": "2025-10-02T09:27:28.582Z"
35+
}
36+
37+
assert_eq!(expected_log_event, .)
38+
- name: Test stderr log entry
39+
inputs:
40+
- type: log
41+
insert_at: processed_files_stderr
42+
log_fields:
43+
file: /stackable/log/hbase/hbase.stderr.log
44+
message: "Exception in thread \"main\""
45+
pod: hbase-regionserver-default-0
46+
source_type: file
47+
timestamp: 2025-10-02T09:27:28.582Z
48+
outputs:
49+
- extract_from: extended_logs
50+
conditions:
51+
- type: vrl
52+
source: |
53+
expected_log_event = {
54+
"cluster": "hbase",
55+
"container": "hbase",
56+
"file": "hbase.stderr.log",
57+
"level": "ERROR",
58+
"logger": "ROOT",
59+
"message": "Exception in thread \"main\"",
60+
"namespace": "default",
61+
"pod": "hbase-regionserver-default-0",
62+
"role": "regionserver",
63+
"roleGroup": "default",
64+
"timestamp": "2025-10-02T09:27:28.582Z"
65+
}
66+
67+
assert_eq!(expected_log_event, .)
68+
- name: Test log4j2 XML log entry without stacktrace
69+
inputs:
70+
- type: log
71+
insert_at: processed_files_log4j2
72+
log_fields:
73+
file: /stackable/log/hbase/hbase.log4j2.xml
74+
message: >
75+
<Event xmlns="http://logging.apache.org/log4j/2.0/events"
76+
timeMillis="1759397248582" level="INFO"
77+
loggerName="org.apache.hadoop.hbase.regionserver.HRegionServer"
78+
thread="main"><Message>Serving as
79+
regionserver...</Message></Event>
80+
pod: hbase-regionserver-default-0
81+
source_type: file
82+
timestamp: 2025-10-02T09:27:29.473487331Z
83+
outputs:
84+
- extract_from: extended_logs
85+
conditions:
86+
- type: vrl
87+
source: |
88+
expected_log_event = {
89+
"cluster": "hbase",
90+
"container": "hbase",
91+
"file": "hbase.log4j2.xml",
92+
"level": "INFO",
93+
"logger": "org.apache.hadoop.hbase.regionserver.HRegionServer",
94+
"message": "Serving as regionserver...",
95+
"namespace": "default",
96+
"pod": "hbase-regionserver-default-0",
97+
"role": "regionserver",
98+
"roleGroup": "default",
99+
"timestamp": t'2025-10-02T09:27:28.582Z'
100+
}
101+
102+
assert_eq!(expected_log_event, .)
103+
- name: Test Vector internal logs
104+
inputs:
105+
- type: log
106+
insert_at: filtered_logs_vector
107+
log_fields:
108+
arch: x86_64
109+
message: Vector has started.
110+
metadata:
111+
kind: event
112+
level: INFO
113+
module_path: vector::internal_events::process
114+
target: vector
115+
pid: 14
116+
pod: hbase-regionserver-default-0
117+
source_type: internal_logs
118+
timestamp: 2025-10-02T09:46:14.479381097Z
119+
version: 0.49.0
120+
outputs:
121+
- extract_from: extended_logs
122+
conditions:
123+
- type: vrl
124+
source: |
125+
expected_log_event = {
126+
"arch": "x86_64",
127+
"cluster": "hbase",
128+
"container": "vector",
129+
"level": "INFO",
130+
"logger": "vector::internal_events::process",
131+
"message": "Vector has started.",
132+
"namespace": "default",
133+
"pod": "hbase-regionserver-default-0",
134+
"role": "regionserver",
135+
"roleGroup": "default",
136+
"timestamp": "2025-10-02T09:46:14.479381097Z",
137+
"version": "0.49.0"
138+
}
139+
140+
assert_eq!(expected_log_event, .)
141+
- name: Test Vector internal log level filtering - INFO passes
142+
inputs:
143+
- type: log
144+
insert_at: filtered_logs_vector
145+
log_fields:
146+
metadata:
147+
level: INFO
148+
outputs:
149+
- extract_from: filtered_logs_vector
150+
conditions:
151+
- type: vrl
152+
source: |
153+
assert_eq!("INFO", .metadata.level)
154+
- name: Test Vector internal log level filtering - DEBUG dropped
155+
inputs:
156+
- type: log
157+
insert_at: filtered_logs_vector
158+
log_fields:
159+
metadata:
160+
level: DEBUG
161+
no_outputs_from:
162+
- filtered_logs_vector

0 commit comments

Comments
 (0)