diff --git a/falco.yaml b/falco.yaml index 6dd8339d726..92d5e4dad1e 100644 --- a/falco.yaml +++ b/falco.yaml @@ -518,6 +518,15 @@ json_output: false # case. json_include_output_property: true +# [Incubating] `json_include_message_property` +# +# When using JSON output in Falco, you have the option to include the formatted +# rule output without timestamp or priority. For instance, if a rule specifies +# an "output" property like "Opened process %proc.name" the "message" field will +# only contain "Opened process bash" whereas the "output" field will contain more +# information. +json_include_message_property: false + # [Stable] `json_include_tags_property` # # When using JSON output in Falco, you have the option to include the "tags" diff --git a/userspace/engine/formats.cpp b/userspace/engine/formats.cpp index 4f4ff41b1ba..ada5746329b 100644 --- a/userspace/engine/formats.cpp +++ b/userspace/engine/formats.cpp @@ -22,10 +22,14 @@ limitations under the License. falco_formats::falco_formats(std::shared_ptr engine, bool json_include_output_property, - bool json_include_tags_property) + bool json_include_tags_property, + bool json_include_message_property, + bool time_format_iso_8601) : m_falco_engine(engine), m_json_include_output_property(json_include_output_property), - m_json_include_tags_property(json_include_tags_property) + m_json_include_tags_property(json_include_tags_property), + m_json_include_message_property(json_include_message_property), + m_time_format_iso_8601(time_format_iso_8601) { } @@ -37,21 +41,53 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule, const std::string &level, const std::string &format, const std::set &tags, const std::string &hostname, const extra_output_field_t &extra_fields) const { - std::string line; + std::string prefix_format; + std::string message_format = format; + + if(m_time_format_iso_8601) + { + prefix_format = "*%evt.time.iso8601: "; + } + else + { + prefix_format = "*%evt.time: "; + } + prefix_format += level; + + if(message_format[0] != '*') + { + message_format = "*" + message_format; + } std::shared_ptr formatter; - formatter = m_falco_engine->create_formatter(source, format); + auto prefix_formatter = m_falco_engine->create_formatter(source, prefix_format); + auto message_formatter = m_falco_engine->create_formatter(source, message_format); - // Format the original output string, regardless of output format - formatter->tostring_withformat(evt, line, sinsp_evt_formatter::OF_NORMAL); + // The classic Falco output prefix with time and priority e.g. "13:53:31.726060287: Critical" + std::string prefix; + prefix_formatter->tostring_withformat(evt, prefix, sinsp_evt_formatter::OF_NORMAL); + + // The formatted rule message/output + std::string message; + message_formatter->tostring_withformat(evt, message, sinsp_evt_formatter::OF_NORMAL); + + // The complete Falco output, e.g. "13:53:31.726060287: Critical Some Event Description (proc_exe=bash)..." + std::string output = prefix + " " + message; - if(formatter->get_output_format() == sinsp_evt_formatter::OF_JSON) + if(message_formatter->get_output_format() == sinsp_evt_formatter::OF_NORMAL) { - std::string json_fields; + return output; + } + else if(message_formatter->get_output_format() == sinsp_evt_formatter::OF_JSON) + { + std::string json_fields_message; + std::string json_fields_prefix; - // Format the event into a json object with all fields resolved - formatter->tostring(evt, json_fields); + // Resolve message fields + message_formatter->tostring(evt, json_fields_message); + // Resolve prefix (e.g. time) fields + prefix_formatter->tostring(evt, json_fields_prefix); // For JSON output, the formatter returned a json-as-text // object containing all the fields in the original format @@ -78,8 +114,7 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule, if(m_json_include_output_property) { - // This is the filled-in output line. - event["output"] = line; + event["output"] = output; } if(m_json_include_tags_property) @@ -87,7 +122,19 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule, event["tags"] = tags; } - event["output_fields"] = nlohmann::json::parse(json_fields); + if(m_json_include_message_property) + { + event["message"] = message; + } + + event["output_fields"] = nlohmann::json::parse(json_fields_message); + + auto prefix_fields = nlohmann::json::parse(json_fields_prefix); + if (prefix_fields.is_object()) { + for (auto const& el : prefix_fields.items()) { + event["output_fields"][el.key()] = el.value(); + } + } for (auto const& ef : extra_fields) { @@ -105,8 +152,8 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule, if(ef.second.second) // raw field { std::string json_field_map; - formatter = m_falco_engine->create_formatter(source, fformat); - formatter->tostring_withformat(evt, json_field_map, sinsp_evt_formatter::OF_JSON); + auto field_formatter = m_falco_engine->create_formatter(source, fformat); + field_formatter->tostring_withformat(evt, json_field_map, sinsp_evt_formatter::OF_JSON); auto json_obj = nlohmann::json::parse(json_field_map); event["output_fields"][ef.first] = json_obj[ef.first]; } else @@ -115,10 +162,11 @@ std::string falco_formats::format_event(sinsp_evt *evt, const std::string &rule, } } - line = event.dump(); + return event.dump(); } - return line; + // should never get here until we only have OF_NORMAL and OF_JSON + return "INVALID_OUTPUT_FORMAT"; } std::string falco_formats::format_string(sinsp_evt *evt, const std::string &format, const std::string &source) const @@ -137,7 +185,13 @@ std::map falco_formats::get_field_values(sinsp_evt *ev { std::shared_ptr formatter; - formatter = m_falco_engine->create_formatter(source, format); + std::string fformat = format; + if(fformat[0] != '*') + { + fformat = "*" + fformat; + } + + formatter = m_falco_engine->create_formatter(source, fformat); std::map ret; diff --git a/userspace/engine/formats.h b/userspace/engine/formats.h index e2d732580d3..797d6718e2a 100644 --- a/userspace/engine/formats.h +++ b/userspace/engine/formats.h @@ -26,7 +26,9 @@ class falco_formats public: falco_formats(std::shared_ptr engine, bool json_include_output_property, - bool json_include_tags_property); + bool json_include_tags_property, + bool json_include_message_property, + bool time_format_iso_8601); virtual ~falco_formats(); std::string format_event(sinsp_evt *evt, const std::string &rule, const std::string &source, @@ -42,4 +44,6 @@ class falco_formats std::shared_ptr m_falco_engine; bool m_json_include_output_property; bool m_json_include_tags_property; + bool m_json_include_message_property; + bool m_time_format_iso_8601; }; diff --git a/userspace/falco/app/actions/init_outputs.cpp b/userspace/falco/app/actions/init_outputs.cpp index d7288c74adc..fb5f30b36c3 100644 --- a/userspace/falco/app/actions/init_outputs.cpp +++ b/userspace/falco/app/actions/init_outputs.cpp @@ -66,6 +66,7 @@ falco::app::run_result falco::app::actions::init_outputs(falco::app::state& s) s.config->m_json_output, s.config->m_json_include_output_property, s.config->m_json_include_tags_property, + s.config->m_json_include_message_property, s.config->m_output_timeout, s.config->m_buffered_outputs, s.config->m_outputs_queue_capacity, diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index a9c886442ad..74c98417ef6 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -53,12 +53,13 @@ static re2::RE2 ip_address_re("((^\\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]| // https://learn.microsoft.com/en-us/cpp/cpp/string-and-character-literals-cpp?view=msvc-170#size-of-string-literals // Just use any available online tool, eg: https://jsonformatter.org/json-minify // to format the json, add the new fields, and then minify it again. -static const std::string config_schema_string = R"({"$schema":"http://json-schema.org/draft-06/schema#","$ref":"#/definitions/FalcoConfig","definitions":{"FalcoConfig":{"type":"object","additionalProperties":false,"properties":{"append_output":{"type":"array","items":{"$ref":"#/definitions/AppendOutput"}},"config_files":{"type":"array","items":{"type":"string"}},"watch_config_files":{"type":"boolean"},"rules_files":{"type":"array","items":{"type":"string"}},"rule_files":{"type":"array","items":{"type":"string"}},"rules":{"type":"array","items":{"$ref":"#/definitions/Rule"}},"engine":{"$ref":"#/definitions/Engine"},"load_plugins":{"type":"array","items":{"type":"string"}},"plugins":{"type":"array","items":{"$ref":"#/definitions/Plugin"}},"time_format_iso_8601":{"type":"boolean"},"priority":{"type":"string"},"json_output":{"type":"boolean"},"json_include_output_property":{"type":"boolean"},"json_include_tags_property":{"type":"boolean"},"buffered_outputs":{"type":"boolean"},"rule_matching":{"type":"string"},"outputs_queue":{"$ref":"#/definitions/OutputsQueue"},"stdout_output":{"$ref":"#/definitions/Output"},"syslog_output":{"$ref":"#/definitions/Output"},"file_output":{"$ref":"#/definitions/FileOutput"},"http_output":{"$ref":"#/definitions/HTTPOutput"},"program_output":{"$ref":"#/definitions/ProgramOutput"},"grpc_output":{"$ref":"#/definitions/Output"},"grpc":{"$ref":"#/definitions/Grpc"},"webserver":{"$ref":"#/definitions/Webserver"},"log_stderr":{"type":"boolean"},"log_syslog":{"type":"boolean"},"log_level":{"type":"string"},"libs_logger":{"$ref":"#/definitions/LibsLogger"},"output_timeout":{"type":"integer"},"syscall_event_timeouts":{"$ref":"#/definitions/SyscallEventTimeouts"},"syscall_event_drops":{"$ref":"#/definitions/SyscallEventDrops"},"metrics":{"$ref":"#/definitions/Metrics"},"base_syscalls":{"$ref":"#/definitions/BaseSyscalls"},"falco_libs":{"$ref":"#/definitions/FalcoLibs"},"container_engines":{"type":"object","additionalProperties":false,"properties":{"docker":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"cri":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"sockets":{"type":"array","items":{"type":"string"}},"disable_async":{"type":"boolean"}}},"podman":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"lxc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"libvirt_lxc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"bpm":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}}}}},"title":"FalcoConfig"},"AppendOutput":{"type":"object","additionalProperties":false,"properties":{"source":{"type":"string"},"tag":{"type":"string"},"rule":{"type":"string"},"format":{"type":"string"},"fields":{"type":"array","items":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"string"}]}}}},"BaseSyscalls":{"type":"object","additionalProperties":false,"properties":{"custom_set":{"type":"array","items":{"type":"string"}},"repair":{"type":"boolean"}},"minProperties":1,"title":"BaseSyscalls"},"Engine":{"type":"object","additionalProperties":false,"properties":{"kind":{"type":"string"},"kmod":{"$ref":"#/definitions/Kmod"},"ebpf":{"$ref":"#/definitions/Ebpf"},"modern_ebpf":{"$ref":"#/definitions/ModernEbpf"},"replay":{"$ref":"#/definitions/Replay"},"gvisor":{"$ref":"#/definitions/Gvisor"}},"required":["kind"],"title":"Engine"},"Ebpf":{"type":"object","additionalProperties":false,"properties":{"probe":{"type":"string"},"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"required":["probe"],"title":"Ebpf"},"Gvisor":{"type":"object","additionalProperties":false,"properties":{"config":{"type":"string"},"root":{"type":"string"}},"required":["config","root"],"title":"Gvisor"},"Kmod":{"type":"object","additionalProperties":false,"properties":{"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"minProperties":1,"title":"Kmod"},"ModernEbpf":{"type":"object","additionalProperties":false,"properties":{"cpus_for_each_buffer":{"type":"integer"},"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"title":"ModernEbpf"},"Replay":{"type":"object","additionalProperties":false,"properties":{"capture_file":{"type":"string"}},"required":["capture_file"],"title":"Replay"},"FalcoLibs":{"type":"object","additionalProperties":false,"properties":{"thread_table_size":{"type":"integer"}},"minProperties":1,"title":"FalcoLibs"},"FileOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"keep_alive":{"type":"boolean"},"filename":{"type":"string"}},"minProperties":1,"title":"FileOutput"},"Grpc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"bind_address":{"type":"string"},"threadiness":{"type":"integer"}},"minProperties":1,"title":"Grpc"},"Output":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}},"minProperties":1,"title":"Output"},"HTTPOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"url":{"type":"string","format":"uri","qt-uri-protocols":["http"]},"user_agent":{"type":"string"},"insecure":{"type":"boolean"},"ca_cert":{"type":"string"},"ca_bundle":{"type":"string"},"ca_path":{"type":"string"},"mtls":{"type":"boolean"},"client_cert":{"type":"string"},"client_key":{"type":"string"},"echo":{"type":"boolean"},"compress_uploads":{"type":"boolean"},"keep_alive":{"type":"boolean"}},"minProperties":1,"title":"HTTPOutput"},"LibsLogger":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"severity":{"type":"string"}},"minProperties":1,"title":"LibsLogger"},"Metrics":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"interval":{"type":"string"},"output_rule":{"type":"boolean"},"output_file":{"type":"string"},"rules_counters_enabled":{"type":"boolean"},"resource_utilization_enabled":{"type":"boolean"},"state_counters_enabled":{"type":"boolean"},"kernel_event_counters_enabled":{"type":"boolean"},"libbpf_stats_enabled":{"type":"boolean"},"plugins_metrics_enabled":{"type":"boolean"},"convert_memory_to_mb":{"type":"boolean"},"include_empty_values":{"type":"boolean"}},"minProperties":1,"title":"Metrics"},"OutputsQueue":{"type":"object","additionalProperties":false,"properties":{"capacity":{"type":"integer"}},"minProperties":1,"title":"OutputsQueue"},"Plugin":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"library_path":{"type":"string"},"init_config":{"type":"string"},"open_params":{"type":"string"}},"required":["library_path","name"],"title":"Plugin"},"ProgramOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"keep_alive":{"type":"boolean"},"program":{"type":"string"}},"required":["program"],"title":"ProgramOutput"},"Rule":{"type":"object","additionalProperties":false,"properties":{"disable":{"$ref":"#/definitions/Able"},"enable":{"$ref":"#/definitions/Able"}},"minProperties":1,"title":"Rule"},"Able":{"type":"object","additionalProperties":false,"properties":{"rule":{"type":"string"},"tag":{"type":"string"}},"minProperties":1,"title":"Able"},"SyscallEventDrops":{"type":"object","additionalProperties":false,"properties":{"threshold":{"type":"number"},"actions":{"type":"array","items":{"type":"string"}},"rate":{"type":"number"},"max_burst":{"type":"integer"},"simulate_drops":{"type":"boolean"}},"minProperties":1,"title":"SyscallEventDrops"},"SyscallEventTimeouts":{"type":"object","additionalProperties":false,"properties":{"max_consecutives":{"type":"integer"}},"minProperties":1,"title":"SyscallEventTimeouts"},"Webserver":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"threadiness":{"type":"integer"},"listen_port":{"type":"integer"},"listen_address":{"type":"string"},"k8s_healthz_endpoint":{"type":"string"},"prometheus_metrics_enabled":{"type":"boolean"},"ssl_enabled":{"type":"boolean"},"ssl_certificate":{"type":"string"}},"minProperties":1,"title":"Webserver"}}})"; +static const std::string config_schema_string = R"({"$schema":"http://json-schema.org/draft-06/schema#","$ref":"#/definitions/FalcoConfig","definitions":{"FalcoConfig":{"type":"object","additionalProperties":false,"properties":{"append_output":{"type":"array","items":{"$ref":"#/definitions/AppendOutput"}},"config_files":{"type":"array","items":{"type":"string"}},"watch_config_files":{"type":"boolean"},"rules_files":{"type":"array","items":{"type":"string"}},"rule_files":{"type":"array","items":{"type":"string"}},"rules":{"type":"array","items":{"$ref":"#/definitions/Rule"}},"engine":{"$ref":"#/definitions/Engine"},"load_plugins":{"type":"array","items":{"type":"string"}},"plugins":{"type":"array","items":{"$ref":"#/definitions/Plugin"}},"time_format_iso_8601":{"type":"boolean"},"priority":{"type":"string"},"json_output":{"type":"boolean"},"json_include_output_property":{"type":"boolean"},"json_include_message_property":{"type":"boolean"},"json_include_tags_property":{"type":"boolean"},"buffered_outputs":{"type":"boolean"},"rule_matching":{"type":"string"},"outputs_queue":{"$ref":"#/definitions/OutputsQueue"},"stdout_output":{"$ref":"#/definitions/Output"},"syslog_output":{"$ref":"#/definitions/Output"},"file_output":{"$ref":"#/definitions/FileOutput"},"http_output":{"$ref":"#/definitions/HTTPOutput"},"program_output":{"$ref":"#/definitions/ProgramOutput"},"grpc_output":{"$ref":"#/definitions/Output"},"grpc":{"$ref":"#/definitions/Grpc"},"webserver":{"$ref":"#/definitions/Webserver"},"log_stderr":{"type":"boolean"},"log_syslog":{"type":"boolean"},"log_level":{"type":"string"},"libs_logger":{"$ref":"#/definitions/LibsLogger"},"output_timeout":{"type":"integer"},"syscall_event_timeouts":{"$ref":"#/definitions/SyscallEventTimeouts"},"syscall_event_drops":{"$ref":"#/definitions/SyscallEventDrops"},"metrics":{"$ref":"#/definitions/Metrics"},"base_syscalls":{"$ref":"#/definitions/BaseSyscalls"},"falco_libs":{"$ref":"#/definitions/FalcoLibs"},"container_engines":{"type":"object","additionalProperties":false,"properties":{"docker":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"cri":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"sockets":{"type":"array","items":{"type":"string"}},"disable_async":{"type":"boolean"}}},"podman":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"lxc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"libvirt_lxc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}},"bpm":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}}}}}},"title":"FalcoConfig"},"AppendOutput":{"type":"object","additionalProperties":false,"properties":{"source":{"type":"string"},"tag":{"type":"string"},"rule":{"type":"string"},"format":{"type":"string"},"fields":{"type":"array","items":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"string"}]}}}},"BaseSyscalls":{"type":"object","additionalProperties":false,"properties":{"custom_set":{"type":"array","items":{"type":"string"}},"repair":{"type":"boolean"}},"minProperties":1,"title":"BaseSyscalls"},"Engine":{"type":"object","additionalProperties":false,"properties":{"kind":{"type":"string"},"kmod":{"$ref":"#/definitions/Kmod"},"ebpf":{"$ref":"#/definitions/Ebpf"},"modern_ebpf":{"$ref":"#/definitions/ModernEbpf"},"replay":{"$ref":"#/definitions/Replay"},"gvisor":{"$ref":"#/definitions/Gvisor"}},"required":["kind"],"title":"Engine"},"Ebpf":{"type":"object","additionalProperties":false,"properties":{"probe":{"type":"string"},"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"required":["probe"],"title":"Ebpf"},"Gvisor":{"type":"object","additionalProperties":false,"properties":{"config":{"type":"string"},"root":{"type":"string"}},"required":["config","root"],"title":"Gvisor"},"Kmod":{"type":"object","additionalProperties":false,"properties":{"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"minProperties":1,"title":"Kmod"},"ModernEbpf":{"type":"object","additionalProperties":false,"properties":{"cpus_for_each_buffer":{"type":"integer"},"buf_size_preset":{"type":"integer"},"drop_failed_exit":{"type":"boolean"}},"title":"ModernEbpf"},"Replay":{"type":"object","additionalProperties":false,"properties":{"capture_file":{"type":"string"}},"required":["capture_file"],"title":"Replay"},"FalcoLibs":{"type":"object","additionalProperties":false,"properties":{"thread_table_size":{"type":"integer"}},"minProperties":1,"title":"FalcoLibs"},"FileOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"keep_alive":{"type":"boolean"},"filename":{"type":"string"}},"minProperties":1,"title":"FileOutput"},"Grpc":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"bind_address":{"type":"string"},"threadiness":{"type":"integer"}},"minProperties":1,"title":"Grpc"},"Output":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"}},"minProperties":1,"title":"Output"},"HTTPOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"url":{"type":"string","format":"uri","qt-uri-protocols":["http"]},"user_agent":{"type":"string"},"insecure":{"type":"boolean"},"ca_cert":{"type":"string"},"ca_bundle":{"type":"string"},"ca_path":{"type":"string"},"mtls":{"type":"boolean"},"client_cert":{"type":"string"},"client_key":{"type":"string"},"echo":{"type":"boolean"},"compress_uploads":{"type":"boolean"},"keep_alive":{"type":"boolean"}},"minProperties":1,"title":"HTTPOutput"},"LibsLogger":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"severity":{"type":"string"}},"minProperties":1,"title":"LibsLogger"},"Metrics":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"interval":{"type":"string"},"output_rule":{"type":"boolean"},"output_file":{"type":"string"},"rules_counters_enabled":{"type":"boolean"},"resource_utilization_enabled":{"type":"boolean"},"state_counters_enabled":{"type":"boolean"},"kernel_event_counters_enabled":{"type":"boolean"},"libbpf_stats_enabled":{"type":"boolean"},"plugins_metrics_enabled":{"type":"boolean"},"convert_memory_to_mb":{"type":"boolean"},"include_empty_values":{"type":"boolean"}},"minProperties":1,"title":"Metrics"},"OutputsQueue":{"type":"object","additionalProperties":false,"properties":{"capacity":{"type":"integer"}},"minProperties":1,"title":"OutputsQueue"},"Plugin":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"library_path":{"type":"string"},"init_config":{"type":"string"},"open_params":{"type":"string"}},"required":["library_path","name"],"title":"Plugin"},"ProgramOutput":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"keep_alive":{"type":"boolean"},"program":{"type":"string"}},"required":["program"],"title":"ProgramOutput"},"Rule":{"type":"object","additionalProperties":false,"properties":{"disable":{"$ref":"#/definitions/Able"},"enable":{"$ref":"#/definitions/Able"}},"minProperties":1,"title":"Rule"},"Able":{"type":"object","additionalProperties":false,"properties":{"rule":{"type":"string"},"tag":{"type":"string"}},"minProperties":1,"title":"Able"},"SyscallEventDrops":{"type":"object","additionalProperties":false,"properties":{"threshold":{"type":"number"},"actions":{"type":"array","items":{"type":"string"}},"rate":{"type":"number"},"max_burst":{"type":"integer"},"simulate_drops":{"type":"boolean"}},"minProperties":1,"title":"SyscallEventDrops"},"SyscallEventTimeouts":{"type":"object","additionalProperties":false,"properties":{"max_consecutives":{"type":"integer"}},"minProperties":1,"title":"SyscallEventTimeouts"},"Webserver":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"threadiness":{"type":"integer"},"listen_port":{"type":"integer"},"listen_address":{"type":"string"},"k8s_healthz_endpoint":{"type":"string"},"prometheus_metrics_enabled":{"type":"boolean"},"ssl_enabled":{"type":"boolean"},"ssl_certificate":{"type":"string"}},"minProperties":1,"title":"Webserver"}}})"; falco_configuration::falco_configuration(): m_json_output(false), m_json_include_output_property(true), m_json_include_tags_property(true), + m_json_include_message_property(false), m_rule_matching(falco_common::rule_matching::FIRST), m_watch_config_files(true), m_buffered_outputs(false), @@ -320,6 +321,7 @@ void falco_configuration::load_yaml(const std::string& config_name) m_json_output = m_config.get_scalar("json_output", false); m_json_include_output_property = m_config.get_scalar("json_include_output_property", true); m_json_include_tags_property = m_config.get_scalar("json_include_tags_property", true); + m_json_include_message_property = m_config.get_scalar("json_include_message_property", false); m_outputs.clear(); falco::outputs::config file_output; diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 33d0addd6ab..55110c609c9 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -149,6 +149,7 @@ class falco_configuration bool m_json_output; bool m_json_include_output_property; bool m_json_include_tags_property; + bool m_json_include_message_property; std::string m_log_level; std::vector m_outputs; diff --git a/userspace/falco/falco_outputs.cpp b/userspace/falco/falco_outputs.cpp index 8585d462cfa..2ccddf00874 100644 --- a/userspace/falco/falco_outputs.cpp +++ b/userspace/falco/falco_outputs.cpp @@ -45,12 +45,16 @@ falco_outputs::falco_outputs( bool json_output, bool json_include_output_property, bool json_include_tags_property, + bool json_include_message_property, uint32_t timeout, bool buffered, size_t outputs_queue_capacity, bool time_format_iso_8601, const std::string& hostname) - : m_formats(std::make_unique(engine, json_include_output_property, json_include_tags_property)), + : m_formats(std::make_unique( + engine, + json_include_output_property, json_include_tags_property, json_include_message_property, + time_format_iso_8601)), m_buffered(buffered), m_json_output(json_output), m_time_format_iso_8601(time_format_iso_8601), @@ -136,32 +140,11 @@ void falco_outputs::handle_event(sinsp_evt *evt, const std::string &rule, const cmsg.source = source; cmsg.rule = rule; - std::string sformat; - if(m_time_format_iso_8601) - { - sformat = "*%evt.time.iso8601: "; - } - else - { - sformat = "*%evt.time: "; - } - sformat += falco_common::format_priority(priority); - - // if format starts with a *, remove it, as we added our own prefix - if(format[0] == '*') - { - sformat += " " + format.substr(1, format.length() - 1); - } - else - { - sformat += " " + format; - } - cmsg.msg = m_formats->format_event( - evt, rule, source, falco_common::format_priority(priority), sformat, tags, m_hostname, extra_fields + evt, rule, source, falco_common::format_priority(priority), format, tags, m_hostname, extra_fields ); - auto fields = m_formats->get_field_values(evt, source, sformat); + auto fields = m_formats->get_field_values(evt, source, format); for (auto const& ef : extra_fields) { // when formatting for the control message we always want strings, diff --git a/userspace/falco/falco_outputs.h b/userspace/falco/falco_outputs.h index c3c2cdbed9e..dc678ec32e4 100644 --- a/userspace/falco/falco_outputs.h +++ b/userspace/falco/falco_outputs.h @@ -46,6 +46,7 @@ class falco_outputs bool json_output, bool json_include_output_property, bool json_include_tags_property, + bool json_include_message_property, uint32_t timeout, bool buffered, size_t outputs_queue_capacity,