@@ -22,10 +22,14 @@ limitations under the License.
22
22
23
23
falco_formats::falco_formats (std::shared_ptr<const falco_engine> engine,
24
24
bool json_include_output_property,
25
- bool json_include_tags_property)
25
+ bool json_include_tags_property,
26
+ bool json_include_message_property,
27
+ bool time_format_iso_8601)
26
28
: m_falco_engine(engine),
27
29
m_json_include_output_property(json_include_output_property),
28
- m_json_include_tags_property(json_include_tags_property)
30
+ m_json_include_tags_property(json_include_tags_property),
31
+ m_json_include_message_property(json_include_message_property),
32
+ m_time_format_iso_8601(time_format_iso_8601)
29
33
{
30
34
}
31
35
@@ -37,21 +41,53 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule,
37
41
const std::string &level, const std::string &format, const std::set<std::string> &tags,
38
42
const std::string &hostname, const extra_output_field_t &extra_fields) const
39
43
{
40
- std::string line;
44
+ std::string prefix_format;
45
+ std::string message_format = format;
46
+
47
+ if (m_time_format_iso_8601)
48
+ {
49
+ prefix_format = " *%evt.time.iso8601: " ;
50
+ }
51
+ else
52
+ {
53
+ prefix_format = " *%evt.time: " ;
54
+ }
55
+ prefix_format += level;
56
+
57
+ if (message_format[0 ] != ' *' )
58
+ {
59
+ message_format = " *" + message_format;
60
+ }
41
61
42
62
std::shared_ptr<sinsp_evt_formatter> formatter;
43
63
44
- formatter = m_falco_engine->create_formatter (source, format);
64
+ auto prefix_formatter = m_falco_engine->create_formatter (source, prefix_format);
65
+ auto message_formatter = m_falco_engine->create_formatter (source, message_format);
45
66
46
- // Format the original output string, regardless of output format
47
- formatter->tostring_withformat (evt, line, sinsp_evt_formatter::OF_NORMAL);
67
+ // The classic Falco output prefix with time and priority e.g. "13:53:31.726060287: Critical"
68
+ std::string prefix;
69
+ prefix_formatter->tostring_withformat (evt, prefix, sinsp_evt_formatter::OF_NORMAL);
70
+
71
+ // The formatted rule message/output
72
+ std::string message;
73
+ message_formatter->tostring_withformat (evt, message, sinsp_evt_formatter::OF_NORMAL);
74
+
75
+ // The complete Falco output, e.g. "13:53:31.726060287: Critical Some Event Description (proc_exe=bash)..."
76
+ std::string output = prefix + " " + message;
48
77
49
- if (formatter ->get_output_format () == sinsp_evt_formatter::OF_JSON )
78
+ if (message_formatter ->get_output_format () == sinsp_evt_formatter::OF_NORMAL )
50
79
{
51
- std::string json_fields;
80
+ return output;
81
+ }
82
+ else if (message_formatter->get_output_format () == sinsp_evt_formatter::OF_JSON)
83
+ {
84
+ std::string json_fields_message;
85
+ std::string json_fields_prefix;
52
86
53
- // Format the event into a json object with all fields resolved
54
- formatter->tostring (evt, json_fields);
87
+ // Resolve message fields
88
+ message_formatter->tostring (evt, json_fields_message);
89
+ // Resolve prefix (e.g. time) fields
90
+ prefix_formatter->tostring (evt, json_fields_prefix);
55
91
56
92
// For JSON output, the formatter returned a json-as-text
57
93
// object containing all the fields in the original format
@@ -78,16 +114,27 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule,
78
114
79
115
if (m_json_include_output_property)
80
116
{
81
- // This is the filled-in output line.
82
- event[" output" ] = line;
117
+ event[" output" ] = output;
83
118
}
84
119
85
120
if (m_json_include_tags_property)
86
121
{
87
122
event[" tags" ] = tags;
88
123
}
89
124
90
- event[" output_fields" ] = nlohmann::json::parse (json_fields);
125
+ if (m_json_include_message_property)
126
+ {
127
+ event[" message" ] = message;
128
+ }
129
+
130
+ event[" output_fields" ] = nlohmann::json::parse (json_fields_message);
131
+
132
+ auto prefix_fields = nlohmann::json::parse (json_fields_prefix);
133
+ if (prefix_fields.is_object ()) {
134
+ for (auto const & el : prefix_fields.items ()) {
135
+ event[" output_fields" ][el.key ()] = el.value ();
136
+ }
137
+ }
91
138
92
139
for (auto const & ef : extra_fields)
93
140
{
@@ -105,8 +152,8 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule,
105
152
if (ef.second .second ) // raw field
106
153
{
107
154
std::string json_field_map;
108
- formatter = m_falco_engine->create_formatter (source, fformat);
109
- formatter ->tostring_withformat (evt, json_field_map, sinsp_evt_formatter::OF_JSON);
155
+ auto field_formatter = m_falco_engine->create_formatter (source, fformat);
156
+ field_formatter ->tostring_withformat (evt, json_field_map, sinsp_evt_formatter::OF_JSON);
110
157
auto json_obj = nlohmann::json::parse (json_field_map);
111
158
event[" output_fields" ][ef.first ] = json_obj[ef.first ];
112
159
} else
@@ -115,10 +162,11 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule,
115
162
}
116
163
}
117
164
118
- line = event.dump ();
165
+ return event.dump ();
119
166
}
120
167
121
- return line;
168
+ // should never get here until we only have OF_NORMAL and OF_JSON
169
+ return " INVALID_OUTPUT_FORMAT" ;
122
170
}
123
171
124
172
std::string falco_formats::format_string (sinsp_evt *evt, const std::string &format, const std::string &source) const
@@ -137,7 +185,13 @@ std::map<std::string, std::string> falco_formats::get_field_values(sinsp_evt *ev
137
185
{
138
186
std::shared_ptr<sinsp_evt_formatter> formatter;
139
187
140
- formatter = m_falco_engine->create_formatter (source, format);
188
+ std::string fformat = format;
189
+ if (fformat[0 ] != ' *' )
190
+ {
191
+ fformat = " *" + fformat;
192
+ }
193
+
194
+ formatter = m_falco_engine->create_formatter (source, fformat);
141
195
142
196
std::map<std::string, std::string> ret;
143
197
0 commit comments