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