diff --git a/resources/tests/scripts/field_from_path.lua b/resources/tests/scripts/field_from_path.lua new file mode 100644 index 00000000..1946fac7 --- /dev/null +++ b/resources/tests/scripts/field_from_path.lua @@ -0,0 +1,10 @@ +function process_metric(pyld) +end + +function process_log(pyld) + local path = payload.log_path(pyld, 1) + payload.log_set_field(pyld, 1, "foo", path) +end + +function tick(pyld) +end diff --git a/resources/tests/scripts/set_value.lua b/resources/tests/scripts/set_value.lua new file mode 100644 index 00000000..de5153a9 --- /dev/null +++ b/resources/tests/scripts/set_value.lua @@ -0,0 +1,9 @@ +function process_metric(pyld) +end + +function process_log(pyld) + payload.log_set_value(pyld, 1, "foo") +end + +function tick(pyld) +end diff --git a/src/filter/programmable_filter.rs b/src/filter/programmable_filter.rs index 84b262f0..1be73bce 100644 --- a/src/filter/programmable_filter.rs +++ b/src/filter/programmable_filter.rs @@ -75,6 +75,15 @@ impl<'a> Payload<'a> { 1 } + #[allow(non_snake_case)] + unsafe extern "C" fn lua_log_path(L: *mut lua_State) -> c_int { + let mut state = State::from_ptr(L); + let pyld = state.to_userdata(1) as *mut Payload; + let idx = idx(state.to_integer(2), (*pyld).logs.len()); + state.push_string(&(*pyld).logs[idx].path); + 1 + } + #[allow(non_snake_case)] unsafe extern "C" fn lua_set_metric_name(L: *mut lua_State) -> c_int { let mut state = State::from_ptr(L); @@ -307,6 +316,23 @@ impl<'a> Payload<'a> { 1 } + #[allow(non_snake_case)] + unsafe extern "C" fn lua_log_set_value(L: *mut lua_State) -> c_int { + let mut state = State::from_ptr(L); + let pyld = state.to_userdata(1) as *mut Payload; + let idx = idx(state.to_integer(2), (*pyld).logs.len()); + match state.to_str(3).map(|k| k.to_owned()) { + Some(key) => { + (*pyld).logs[idx].value = key; + }, + None => { + error!("[log_set_value] no val provided"); + } + } + state.push_nil(); + 1 + } + #[allow(non_snake_case)] unsafe extern "C" fn lua_metric_remove_tag(L: *mut lua_State) -> c_int { let mut state = State::from_ptr(L); @@ -369,7 +395,7 @@ impl<'a> Payload<'a> { } } -const PAYLOAD_LIB: [(&str, Function); 16] = [ +const PAYLOAD_LIB: [(&str, Function); 18] = [ ("set_metric_name", Some(Payload::lua_set_metric_name)), ("clear_logs", Some(Payload::lua_clear_logs)), ("clear_metrics", Some(Payload::lua_clear_metrics)), @@ -377,8 +403,10 @@ const PAYLOAD_LIB: [(&str, Function); 16] = [ ("log_set_tag", Some(Payload::lua_log_set_tag)), ("log_tag_value", Some(Payload::lua_log_tag_value)), ("log_set_field", Some(Payload::lua_log_set_field)), + ("log_set_value", Some(Payload::lua_log_set_value)), ("log_field_value", Some(Payload::lua_log_field_value)), ("log_value", Some(Payload::lua_log_value)), + ("log_path", Some(Payload::lua_log_path)), ("metric_query", Some(Payload::lua_metric_query)), ("metric_remove_tag", Some(Payload::lua_metric_remove_tag)), ("metric_set_tag", Some(Payload::lua_metric_set_tag)), diff --git a/tests/programmable_filter.rs b/tests/programmable_filter.rs index e60a0517..783bb653 100644 --- a/tests/programmable_filter.rs +++ b/tests/programmable_filter.rs @@ -141,6 +141,77 @@ mod integration { assert_eq!(events[0], expected_event); } + #[test] + fn test_get_log_path() { + let mut script = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + script.push("resources/tests/scripts"); + let script_dir = script.clone(); + script.push("field_from_path.lua"); + + let config = ProgrammableFilterConfig { + scripts_directory: Some(script_dir), + script: Some(script), + forwards: Vec::new(), + config_path: Some("filters.field_from_path".to_string()), + tags: Default::default(), + }; + let mut cs = ProgrammableFilter::new(config); + + let orig_log = metric::LogLine::new( + "identity", + "i am the very model of the modern major general", + ); + let expected_log = metric::LogLine::new( + "identity", + "i am the very model of the modern major \ + general", + ).insert_field("foo", "identity"); + let orig_event = metric::Event::new_log(orig_log); + let expected_event = metric::Event::new_log(expected_log); + + let mut events = Vec::new(); + let res = cs.process(orig_event.clone(), &mut events); + assert!(res.is_ok()); + assert!(!events.is_empty()); + assert_eq!(events.len(), 1); + assert_eq!(events[0], expected_event); + } + + #[test] + fn test_set_log_value() { + let mut script = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + script.push("resources/tests/scripts"); + let script_dir = script.clone(); + script.push("set_value.lua"); + + let config = ProgrammableFilterConfig { + scripts_directory: Some(script_dir), + script: Some(script), + forwards: Vec::new(), + config_path: Some("filters.set_value".to_string()), + tags: Default::default(), + }; + let mut cs = ProgrammableFilter::new(config); + + let orig_log = metric::LogLine::new( + "identity", + "i am the very model of the modern major general", + ); + let expected_log = metric::LogLine::new( + "identity", + "foo" + ); + let orig_event = metric::Event::new_log(orig_log); + let expected_event = metric::Event::new_log(expected_log); + + let mut events = Vec::new(); + let res = cs.process(orig_event.clone(), &mut events); + assert!(res.is_ok()); + assert!(!events.is_empty()); + assert_eq!(events.len(), 1); + assert_eq!(events[0], expected_event); + } + #[test] fn test_remove_metric_tag_kv() { let mut script = PathBuf::from(env!("CARGO_MANIFEST_DIR"));