Skip to content

Commit c48c70e

Browse files
committed
refactor: adapt to v2 logging and add vector test
1 parent 3395c22 commit c48c70e

15 files changed

Lines changed: 709 additions & 144 deletions

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ mod tests {
151151
.values()
152152
.next()
153153
.expect("the default role group should exist");
154-
let rendered = build(&rg.config, &rg.config_overrides).expect("config.json builds");
154+
let rendered =
155+
build(&rg.config.config, &rg.config.config_overrides).expect("config.json builds");
155156
serde_json::from_str(&rendered).expect("config.json should be valid JSON")
156157
}
157158

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

Lines changed: 0 additions & 58 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Per-config-file build steps assembled into the rolegroup `ConfigMap`.
22
33
pub mod config_json;
4-
pub mod logging;
4+
pub mod product_logging;
55
pub mod user_info_fetcher;
66

77
/// The names of the config files assembled into the rolegroup `ConfigMap`.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//! Renders the Vector agent config (`vector.yaml`) assembled into the rolegroup `ConfigMap`, and
2+
//! maps log levels for the Stackable Rust sidecars.
3+
4+
use stackable_operator::product_logging::spec::LogLevel;
5+
6+
/// The Vector agent configuration (`vector.yaml`).
7+
const VECTOR_CONFIG: &str = include_str!("vector.yaml");
8+
9+
/// Returns the Vector agent config (`vector.yaml`) content added to the rolegroup `ConfigMap`.
10+
pub fn vector_config_file_content() -> String {
11+
VECTOR_CONFIG.to_owned()
12+
}
13+
14+
/// The log level passed to the Stackable Rust sidecars (bundle-builder, user-info-fetcher) via the
15+
/// `CONSOLE_LOG_LEVEL`/`FILE_LOG_LEVEL` environment variables.
16+
#[derive(strum::Display)]
17+
#[strum(serialize_all = "UPPERCASE")]
18+
pub enum BundleBuilderLogLevel {
19+
Trace,
20+
Debug,
21+
Info,
22+
Warn,
23+
Error,
24+
}
25+
26+
impl From<LogLevel> for BundleBuilderLogLevel {
27+
fn from(level: LogLevel) -> Self {
28+
match level {
29+
LogLevel::TRACE => Self::Trace,
30+
LogLevel::DEBUG => Self::Debug,
31+
LogLevel::INFO => Self::Info,
32+
LogLevel::WARN => Self::Warn,
33+
LogLevel::ERROR | LogLevel::FATAL | LogLevel::NONE => Self::Error,
34+
}
35+
}
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use super::*;
41+
42+
#[test]
43+
fn vector_config_file_content_has_opa_sources() {
44+
let content = vector_config_file_content();
45+
assert!(!content.is_empty());
46+
// OPA's own JSON logs and the Rust sidecar (tracing-rs) logs must both be handled.
47+
assert!(content.contains("files_opa_json"));
48+
assert!(content.contains("files_tracing_rs"));
49+
}
50+
}
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=opa \
7+
ROLE_NAME=server \
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: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Run tests with `./test-vector.sh` (requires the `vector` binary).
2+
#
3+
# The tests assert individual fields (rather than the whole event) because the `message` field
4+
# embeds `encode_key_value` output whose ordering is an implementation detail. Please adapt the
5+
# tests if you change the VRL code in vector.yaml.
6+
---
7+
tests:
8+
- name: OPA server log (valid)
9+
inputs:
10+
- type: log
11+
insert_at: processed_files_opa_json
12+
log_fields:
13+
file: /stackable/log/opa/test
14+
message: '{"level":"info","msg":"Valid server log event","name":"stackable","plugin":"bundle","time":"2024-01-01T00:00:00Z","logger":"server"}'
15+
pod: test-opa-server-default-0
16+
source_type: file
17+
outputs:
18+
- extract_from: extended_logs
19+
conditions:
20+
- type: vrl
21+
source: |
22+
assert_eq!(.container, "opa")
23+
assert_eq!(.file, "test")
24+
assert_eq!(.level, "INFO")
25+
assert_eq!(.logger, "server")
26+
assert_eq!(.namespace, "default")
27+
assert_eq!(.cluster, "opa")
28+
assert_eq!(.role, "server")
29+
assert_eq!(.roleGroup, "default")
30+
assert!(!exists(.errors), "valid event should not carry errors")
31+
assert!(contains(string!(.message), "Valid server log event"))
32+
33+
- name: OPA decision log (valid)
34+
inputs:
35+
- type: log
36+
insert_at: processed_files_opa_json
37+
log_fields:
38+
file: /stackable/log/opa/test
39+
message: '{"level":"info","msg":"Valid decision log event","decision_id":"5b887ec2","time":"2024-01-01T00:00:00Z","logger":"decision"}'
40+
pod: test-opa-server-default-0
41+
source_type: file
42+
outputs:
43+
- extract_from: extended_logs
44+
conditions:
45+
- type: vrl
46+
source: |
47+
assert_eq!(.container, "opa")
48+
assert_eq!(.logger, "decision")
49+
assert_eq!(.level, "INFO")
50+
assert!(!exists(.errors))
51+
52+
- name: OPA log with unknown level (invalid)
53+
inputs:
54+
- type: log
55+
insert_at: processed_files_opa_json
56+
log_fields:
57+
file: /stackable/log/opa/test
58+
message: '{"level":"critical","msg":"Invalid log event with an unknown level","time":"2024-01-01T00:00:00Z","logger":"server"}'
59+
pod: test-opa-server-default-0
60+
source_type: file
61+
outputs:
62+
- extract_from: extended_logs
63+
conditions:
64+
- type: vrl
65+
source: |
66+
assert!(exists(.errors), "unknown level should be recorded as an error")
67+
assert_eq!(.level, "INFO")
68+
69+
- name: Bundle-builder tracing-rs log (valid)
70+
inputs:
71+
- type: log
72+
insert_at: processed_files_tracing_rs
73+
log_fields:
74+
file: /stackable/log/bundle-builder/bundle-builder.tracing-rs.json
75+
message: '{"timestamp":"2024-01-01T00:00:00.000000Z","level":"INFO","fields":{"message":"Valid log event"},"target":"TestLogger"}'
76+
pod: test-opa-server-default-0
77+
source_type: file
78+
outputs:
79+
- extract_from: extended_logs
80+
conditions:
81+
- type: vrl
82+
source: |
83+
assert_eq!(.container, "bundle-builder")
84+
assert_eq!(.level, "INFO")
85+
assert_eq!(.logger, "TestLogger")
86+
assert!(!exists(.errors))
87+
assert!(contains(string!(.message), "Valid log event"))
88+
89+
- name: Tracing-rs log without timestamp (invalid)
90+
inputs:
91+
- type: log
92+
insert_at: processed_files_tracing_rs
93+
log_fields:
94+
file: /stackable/log/bundle-builder/bundle-builder.tracing-rs.json
95+
message: '{"level":"INFO","fields":{"message":"Invalid log event with an unparsable timestamp"},"target":"TestLogger","timestamp":"unparsable timestamp"}'
96+
pod: test-opa-server-default-0
97+
source_type: file
98+
outputs:
99+
- extract_from: extended_logs
100+
conditions:
101+
- type: vrl
102+
source: |
103+
assert!(exists(.errors), "unparsable timestamp should be recorded as an error")
104+
105+
- name: Prepare stdout log
106+
inputs:
107+
- type: log
108+
insert_at: processed_files_stdout
109+
log_fields:
110+
file: /stackable/log/prepare/prepare.stdout.log
111+
message: Create dir [/bundles/active]
112+
pod: test-opa-server-default-0
113+
source_type: file
114+
outputs:
115+
- extract_from: extended_logs
116+
conditions:
117+
- type: vrl
118+
source: |
119+
assert_eq!(.container, "prepare")
120+
assert_eq!(.logger, "ROOT")
121+
assert_eq!(.level, "INFO")
122+
123+
- name: Prepare stderr log
124+
inputs:
125+
- type: log
126+
insert_at: processed_files_stderr
127+
log_fields:
128+
file: /stackable/log/prepare/prepare.stderr.log
129+
message: something failed
130+
pod: test-opa-server-default-0
131+
source_type: file
132+
outputs:
133+
- extract_from: extended_logs
134+
conditions:
135+
- type: vrl
136+
source: |
137+
assert_eq!(.container, "prepare")
138+
assert_eq!(.logger, "ROOT")
139+
assert_eq!(.level, "ERROR")
140+
141+
- name: Vector internal log
142+
inputs:
143+
- type: log
144+
insert_at: filtered_logs_vector
145+
log_fields:
146+
message: Vector has started.
147+
metadata:
148+
level: INFO
149+
module_path: vector::internal_events::process
150+
pid: 14
151+
pod: test-opa-server-default-0
152+
source_type: internal_logs
153+
outputs:
154+
- extract_from: extended_logs
155+
conditions:
156+
- type: vrl
157+
source: |
158+
assert_eq!(.container, "vector")
159+
assert_eq!(.level, "INFO")
160+
assert_eq!(.logger, "vector::internal_events::process")
161+
assert_eq!(.cluster, "opa")
162+
163+
- name: Vector internal log level filtering - INFO passes
164+
inputs:
165+
- type: log
166+
insert_at: filtered_logs_vector
167+
log_fields:
168+
metadata:
169+
level: INFO
170+
outputs:
171+
- extract_from: filtered_logs_vector
172+
conditions:
173+
- type: vrl
174+
source: |
175+
assert_eq!("INFO", .metadata.level)
176+
177+
- name: Vector internal log level filtering - DEBUG dropped
178+
inputs:
179+
- type: log
180+
insert_at: filtered_logs_vector
181+
log_fields:
182+
metadata:
183+
level: DEBUG
184+
no_outputs_from:
185+
- filtered_logs_vector

0 commit comments

Comments
 (0)