Skip to content

Commit ec0eb73

Browse files
authored
dynamic_modules: add numeric and bool access logger metadata getters (#45628)
1 parent aa42e83 commit ec0eb73

9 files changed

Lines changed: 342 additions & 18 deletions

File tree

source/extensions/access_loggers/dynamic_modules/abi_impl.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,23 @@ bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata(
741741
return ContextAccessor::getDynamicMetadata(*logger->stream_info_, filter_name, path, result);
742742
}
743743

744+
bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_number(
745+
envoy_dynamic_module_type_access_logger_envoy_ptr logger_envoy_ptr,
746+
envoy_dynamic_module_type_module_buffer filter_name,
747+
envoy_dynamic_module_type_module_buffer path, double* result) {
748+
auto* logger = static_cast<ThreadLocalLogger*>(logger_envoy_ptr);
749+
return ContextAccessor::getDynamicMetadataNumber(*logger->stream_info_, filter_name, path,
750+
result);
751+
}
752+
753+
bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_bool(
754+
envoy_dynamic_module_type_access_logger_envoy_ptr logger_envoy_ptr,
755+
envoy_dynamic_module_type_module_buffer filter_name,
756+
envoy_dynamic_module_type_module_buffer path, bool* result) {
757+
auto* logger = static_cast<ThreadLocalLogger*>(logger_envoy_ptr);
758+
return ContextAccessor::getDynamicMetadataBool(*logger->stream_info_, filter_name, path, result);
759+
}
760+
744761
bool envoy_dynamic_module_callback_access_logger_get_filter_state(
745762
envoy_dynamic_module_type_access_logger_envoy_ptr logger_envoy_ptr,
746763
envoy_dynamic_module_type_module_buffer key, envoy_dynamic_module_type_envoy_buffer* result) {

source/extensions/dynamic_modules/abi/abi.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7000,6 +7000,34 @@ bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata(
70007000
envoy_dynamic_module_type_module_buffer filter_name,
70017001
envoy_dynamic_module_type_module_buffer path, envoy_dynamic_module_type_envoy_buffer* result);
70027002

7003+
/**
7004+
* Get a number value from dynamic metadata by filter name and key path.
7005+
*
7006+
* @param logger_envoy_ptr is the pointer to the log context.
7007+
* @param filter_name is the filter namespace in dynamic metadata.
7008+
* @param path is the key path within the filter namespace (can be nested with dots).
7009+
* @param result receives the number value. Only number-typed metadata is returned.
7010+
* @return true if a number value exists at the path, false otherwise.
7011+
*/
7012+
bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_number(
7013+
envoy_dynamic_module_type_access_logger_envoy_ptr logger_envoy_ptr,
7014+
envoy_dynamic_module_type_module_buffer filter_name,
7015+
envoy_dynamic_module_type_module_buffer path, double* result);
7016+
7017+
/**
7018+
* Get a bool value from dynamic metadata by filter name and key path.
7019+
*
7020+
* @param logger_envoy_ptr is the pointer to the log context.
7021+
* @param filter_name is the filter namespace in dynamic metadata.
7022+
* @param path is the key path within the filter namespace (can be nested with dots).
7023+
* @param result receives the bool value. Only bool-typed metadata is returned.
7024+
* @return true if a bool value exists at the path, false otherwise.
7025+
*/
7026+
bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_bool(
7027+
envoy_dynamic_module_type_access_logger_envoy_ptr logger_envoy_ptr,
7028+
envoy_dynamic_module_type_module_buffer filter_name,
7029+
envoy_dynamic_module_type_module_buffer path, bool* result);
7030+
70037031
/**
70047032
* Get a value from filter state by key.
70057033
*

source/extensions/dynamic_modules/abi_context_accessors.cc

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ bool getUpstreamSslAttribute(
5555
return true;
5656
}
5757

58+
// Resolve a dynamic metadata value by filter name and dotted key path. Returns an unset value
59+
// when the path is absent.
60+
const Protobuf::Value& dynamicMetadataValue(const StreamInfo::StreamInfo& stream_info,
61+
envoy_dynamic_module_type_module_buffer filter_name,
62+
envoy_dynamic_module_type_module_buffer path) {
63+
std::string filter_name_str(filter_name.ptr, filter_name.length);
64+
std::string path_str(path.ptr, path.length);
65+
std::vector<std::string> path_parts = absl::StrSplit(path_str, '.');
66+
const auto& metadata = stream_info.dynamicMetadata();
67+
return Envoy::Config::Metadata::metadataValue(&metadata, filter_name_str, path_parts);
68+
}
69+
5870
} // namespace
5971

6072
HeadersMapOptConstRef
@@ -474,26 +486,37 @@ bool ContextAccessor::getDynamicMetadata(const StreamInfo::StreamInfo& stream_in
474486
envoy_dynamic_module_type_module_buffer filter_name,
475487
envoy_dynamic_module_type_module_buffer path,
476488
envoy_dynamic_module_type_envoy_buffer* result) {
477-
std::string filter_name_str(filter_name.ptr, filter_name.length);
478-
std::string path_str(path.ptr, path.length);
479-
std::vector<std::string> path_parts = absl::StrSplit(path_str, '.');
480-
481-
const auto& metadata = stream_info.dynamicMetadata();
482-
const auto& value =
483-
Envoy::Config::Metadata::metadataValue(&metadata, filter_name_str, path_parts);
484-
485-
if (value.kind_case() == Protobuf::Value::KIND_NOT_SET) {
486-
return false;
487-
}
488-
489-
// Note: Currently only string values are supported. Complex types would require serialization
490-
// to a buffer, but the ABI uses zero-copy pointers to Envoy memory.
489+
// String values are returned zero-copy here. Numbers and bools have dedicated typed accessors.
490+
const auto& value = dynamicMetadataValue(stream_info, filter_name, path);
491491
if (value.kind_case() == Protobuf::Value::kStringValue) {
492492
const auto& str = value.string_value();
493493
*result = {const_cast<char*>(str.data()), str.size()};
494494
return true;
495495
}
496+
return false;
497+
}
498+
499+
bool ContextAccessor::getDynamicMetadataNumber(const StreamInfo::StreamInfo& stream_info,
500+
envoy_dynamic_module_type_module_buffer filter_name,
501+
envoy_dynamic_module_type_module_buffer path,
502+
double* result) {
503+
const auto& value = dynamicMetadataValue(stream_info, filter_name, path);
504+
if (value.kind_case() == Protobuf::Value::kNumberValue) {
505+
*result = value.number_value();
506+
return true;
507+
}
508+
return false;
509+
}
496510

511+
bool ContextAccessor::getDynamicMetadataBool(const StreamInfo::StreamInfo& stream_info,
512+
envoy_dynamic_module_type_module_buffer filter_name,
513+
envoy_dynamic_module_type_module_buffer path,
514+
bool* result) {
515+
const auto& value = dynamicMetadataValue(stream_info, filter_name, path);
516+
if (value.kind_case() == Protobuf::Value::kBoolValue) {
517+
*result = value.bool_value();
518+
return true;
519+
}
497520
return false;
498521
}
499522

source/extensions/dynamic_modules/abi_context_accessors.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,26 @@ class ContextAccessor {
5757
static bool getAttributeBool(const StreamInfo::StreamInfo& stream_info,
5858
envoy_dynamic_module_type_attribute_id attribute_id, bool* result);
5959

60-
// Get a value from dynamic metadata by filter name and dotted key path. Only string values are
61-
// returned, matching the zero-copy ABI contract.
60+
// Get a string value from dynamic metadata by filter name and dotted key path. Returns false
61+
// when the path is absent or the value is not a string.
6262
static bool getDynamicMetadata(const StreamInfo::StreamInfo& stream_info,
6363
envoy_dynamic_module_type_module_buffer filter_name,
6464
envoy_dynamic_module_type_module_buffer path,
6565
envoy_dynamic_module_type_envoy_buffer* result);
6666

67+
// Get a number value from dynamic metadata by filter name and dotted key path. Returns false
68+
// when the path is absent or the value is not a number.
69+
static bool getDynamicMetadataNumber(const StreamInfo::StreamInfo& stream_info,
70+
envoy_dynamic_module_type_module_buffer filter_name,
71+
envoy_dynamic_module_type_module_buffer path,
72+
double* result);
73+
74+
// Get a bool value from dynamic metadata by filter name and dotted key path. Returns false when
75+
// the path is absent or the value is not a bool.
76+
static bool getDynamicMetadataBool(const StreamInfo::StreamInfo& stream_info,
77+
envoy_dynamic_module_type_module_buffer filter_name,
78+
envoy_dynamic_module_type_module_buffer path, bool* result);
79+
6780
// Get the local reply body from the formatting context. Returns false when there is no body.
6881
static bool getLocalReplyBody(const Formatter::Context& context,
6982
envoy_dynamic_module_type_envoy_buffer* result);

source/extensions/dynamic_modules/abi_impl.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,22 @@ __attribute__((weak)) bool envoy_dynamic_module_callback_access_logger_get_dynam
22372237
return false;
22382238
}
22392239

2240+
__attribute__((weak)) bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_number(
2241+
envoy_dynamic_module_type_access_logger_envoy_ptr, envoy_dynamic_module_type_module_buffer,
2242+
envoy_dynamic_module_type_module_buffer, double*) {
2243+
IS_ENVOY_BUG("envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_number: not "
2244+
"implemented in this context");
2245+
return false;
2246+
}
2247+
2248+
__attribute__((weak)) bool envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_bool(
2249+
envoy_dynamic_module_type_access_logger_envoy_ptr, envoy_dynamic_module_type_module_buffer,
2250+
envoy_dynamic_module_type_module_buffer, bool*) {
2251+
IS_ENVOY_BUG("envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_bool: not "
2252+
"implemented in this context");
2253+
return false;
2254+
}
2255+
22402256
__attribute__((weak)) bool envoy_dynamic_module_callback_access_logger_get_filter_state(
22412257
envoy_dynamic_module_type_access_logger_envoy_ptr, envoy_dynamic_module_type_module_buffer,
22422258
envoy_dynamic_module_type_envoy_buffer*) {

source/extensions/dynamic_modules/sdk/rust/src/access_log.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,10 @@ impl LogContext {
636636
/// * `key` - The key within the filter namespace (e.g., "rbac_policy").
637637
///
638638
/// # Returns
639-
/// The string value if it exists, None otherwise.
640-
/// Note: Only string values are currently supported.
639+
/// The string value if it exists and is string-typed, None otherwise. Use
640+
/// [`get_dynamic_metadata_number`](Self::get_dynamic_metadata_number) or
641+
/// [`get_dynamic_metadata_bool`](Self::get_dynamic_metadata_bool) for number- and bool-typed
642+
/// values.
641643
pub fn get_dynamic_metadata(&self, filter_name: &str, key: &str) -> Option<EnvoyBuffer<'_>> {
642644
let filter_buf = abi::envoy_dynamic_module_type_module_buffer {
643645
ptr: filter_name.as_ptr() as *const _,
@@ -665,6 +667,70 @@ impl LogContext {
665667
}
666668
}
667669

670+
/// Get a number value from dynamic metadata.
671+
///
672+
/// # Arguments
673+
/// * `filter_name` - The filter namespace (e.g., "envoy.filters.http.dynamic_module").
674+
/// * `key` - The key within the filter namespace (e.g., "handshake_state").
675+
///
676+
/// # Returns
677+
/// The number value if it exists and is number-typed, None otherwise.
678+
pub fn get_dynamic_metadata_number(&self, filter_name: &str, key: &str) -> Option<f64> {
679+
let filter_buf = abi::envoy_dynamic_module_type_module_buffer {
680+
ptr: filter_name.as_ptr() as *const _,
681+
length: filter_name.len(),
682+
};
683+
let key_buf = abi::envoy_dynamic_module_type_module_buffer {
684+
ptr: key.as_ptr() as *const _,
685+
length: key.len(),
686+
};
687+
let mut result: f64 = 0.0;
688+
if unsafe {
689+
abi::envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_number(
690+
self.envoy_ptr,
691+
filter_buf,
692+
key_buf,
693+
&mut result,
694+
)
695+
} {
696+
Some(result)
697+
} else {
698+
None
699+
}
700+
}
701+
702+
/// Get a bool value from dynamic metadata.
703+
///
704+
/// # Arguments
705+
/// * `filter_name` - The filter namespace (e.g., "envoy.filters.http.dynamic_module").
706+
/// * `key` - The key within the filter namespace (e.g., "tls_enabled").
707+
///
708+
/// # Returns
709+
/// The bool value if it exists and is bool-typed, None otherwise.
710+
pub fn get_dynamic_metadata_bool(&self, filter_name: &str, key: &str) -> Option<bool> {
711+
let filter_buf = abi::envoy_dynamic_module_type_module_buffer {
712+
ptr: filter_name.as_ptr() as *const _,
713+
length: filter_name.len(),
714+
};
715+
let key_buf = abi::envoy_dynamic_module_type_module_buffer {
716+
ptr: key.as_ptr() as *const _,
717+
length: key.len(),
718+
};
719+
let mut result: bool = false;
720+
if unsafe {
721+
abi::envoy_dynamic_module_callback_access_logger_get_dynamic_metadata_bool(
722+
self.envoy_ptr,
723+
filter_buf,
724+
key_buf,
725+
&mut result,
726+
)
727+
} {
728+
Some(result)
729+
} else {
730+
None
731+
}
732+
}
733+
668734
/// Get the local reply body (if this was a local response).
669735
pub fn local_reply_body(&self) -> Option<EnvoyBuffer<'_>> {
670736
self.get_envoy_buffer(abi::envoy_dynamic_module_callback_access_logger_get_local_reply_body)

0 commit comments

Comments
 (0)