vector_core/event/lua/
event.rs1use mlua::prelude::*;
2
3use super::{
4 super::{Event, LogEvent, Metric},
5 metric::LuaMetric,
6};
7
8pub struct LuaEvent {
9 pub event: Event,
10 pub metric_multi_value_tags: bool,
11}
12
13impl IntoLua for LuaEvent {
14 #![allow(clippy::wrong_self_convention)] fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
16 let table = lua.create_table()?;
17 match self.event {
18 Event::Log(log) => table.raw_set("log", log.into_lua(lua)?)?,
19 Event::Metric(metric) => table.raw_set(
20 "metric",
21 LuaMetric {
22 metric,
23 multi_value_tags: self.metric_multi_value_tags,
24 }
25 .into_lua(lua)?,
26 )?,
27 Event::Trace(_) => {
28 return Err(LuaError::ToLuaConversionError {
29 from: String::from("Event"),
30 to: "table",
31 message: Some("Trace are not supported".to_string()),
32 });
33 }
34 }
35 Ok(LuaValue::Table(table))
36 }
37}
38
39impl FromLua for Event {
40 fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
41 let LuaValue::Table(table) = &value else {
42 return Err(LuaError::FromLuaConversionError {
43 from: value.type_name(),
44 to: String::from("Event"),
45 message: Some("Event should be a Lua table".to_string()),
46 });
47 };
48 match (table.raw_get("log")?, table.raw_get("metric")?) {
49 (LuaValue::Table(log), LuaValue::Nil) => {
50 Ok(Event::Log(LogEvent::from_lua(LuaValue::Table(log), lua)?))
51 }
52 (LuaValue::Nil, LuaValue::Table(metric)) => Ok(Event::Metric(Metric::from_lua(
53 LuaValue::Table(metric),
54 lua,
55 )?)),
56 _ => Err(LuaError::FromLuaConversionError {
57 from: value.type_name(),
58 to: String::from("Event"),
59 message: Some(
60 "Event should contain either \"log\" or \"metric\" key at the top level"
61 .to_string(),
62 ),
63 }),
64 }
65 }
66}
67
68#[cfg(test)]
69mod test {
70 use super::*;
71 use crate::event::{
72 Metric, Value,
73 metric::{MetricKind, MetricValue},
74 };
75
76 fn assert_event(event: Event, assertions: Vec<&'static str>) {
77 let lua = Lua::new();
78 lua.globals()
79 .set(
80 "event",
81 LuaEvent {
82 event,
83 metric_multi_value_tags: false,
84 },
85 )
86 .unwrap();
87 for assertion in assertions {
88 assert!(
89 lua.load(assertion).eval::<bool>().expect(assertion),
90 "{}",
91 assertion
92 );
93 }
94 }
95
96 #[test]
97 fn into_lua_log() {
98 let mut event = LogEvent::default();
99 event.insert("field", "value");
100
101 let assertions = vec![
102 "type(event) == 'table'",
103 "event.metric == nil",
104 "type(event.log) == 'table'",
105 "event.log.field == 'value'",
106 ];
107
108 assert_event(event.into(), assertions);
109 }
110
111 #[test]
112 fn into_lua_metric() {
113 let event = Event::Metric(Metric::new(
114 "example counter",
115 MetricKind::Absolute,
116 MetricValue::Counter {
117 value: 0.577_215_66,
118 },
119 ));
120
121 let assertions = vec![
122 "type(event) == 'table'",
123 "event.log == nil",
124 "type(event.metric) == 'table'",
125 "event.metric.name == 'example counter'",
126 "event.metric.counter.value == 0.57721566",
127 ];
128
129 assert_event(event, assertions);
130 }
131
132 #[test]
133 fn from_lua_log() {
134 let lua_event = r#"
135 {
136 log = {
137 field = "example",
138 nested = {
139 field = "another example"
140 }
141 }
142 }"#;
143
144 let event = Lua::new().load(lua_event).eval::<Event>().unwrap();
145 let log = event.as_log();
146 assert_eq!(log["field"], Value::Bytes("example".into()));
147 assert_eq!(log["nested.field"], Value::Bytes("another example".into()));
148 }
149
150 #[test]
151 fn from_lua_metric() {
152 let lua_event = r#"
153 {
154 metric = {
155 name = "example counter",
156 counter = {
157 value = 0.57721566
158 }
159 }
160 }"#;
161 let expected = Event::Metric(Metric::new(
162 "example counter",
163 MetricKind::Absolute,
164 MetricValue::Counter {
165 value: 0.577_215_66,
166 },
167 ));
168
169 let event = Lua::new().load(lua_event).eval::<Event>().unwrap();
170 vector_common::assert_event_data_eq!(event, expected);
171 }
172
173 #[test]
174 #[allow(clippy::should_panic_without_expect)]
176 #[should_panic]
177 fn from_lua_missing_log_and_metric() {
178 let lua_event = r"{
179 some_field: {}
180 }";
181 Lua::new().load(lua_event).eval::<Event>().unwrap();
182 }
183}