Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions userspace/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_library(
filter_ruleset.cpp
evttype_index_ruleset.cpp
formats.cpp
field_formatter.cpp
filter_details_resolver.cpp
filter_macro_resolver.cpp
filter_warning_resolver.cpp
Expand Down
21 changes: 10 additions & 11 deletions userspace/engine/falco_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ limitations under the License.
#include "falco_engine_version.h"

#include "formats.h"
#include "field_formatter.h"

#include "evttype_index_ruleset.h"

Expand Down Expand Up @@ -117,7 +118,7 @@ static std::string fieldclass_key(const sinsp_filter_factory::filter_fieldclass_
void falco_engine::list_fields(const std::string &source,
bool verbose,
bool names_only,
bool markdown) const {
output_format format) const {
// Maps from field class name + short desc to list of event
// sources for which this field class can be used.
std::map<std::string, std::set<std::string>> fieldclass_event_sources;
Expand All @@ -138,6 +139,10 @@ void falco_engine::list_fields(const std::string &source,
// printing field classes multiple times for different sources
std::set<std::string> seen_fieldclasses;

// Create the appropriate formatter and use it
auto formatter = FieldFormatter::create(format, verbose);
formatter->begin();

// In the second pass, actually print info, skipping duplicate
// field classes and also printing info on supported sources.
for(const auto &it : m_sources) {
Expand All @@ -160,21 +165,15 @@ void falco_engine::list_fields(const std::string &source,
continue;
}

printf("%s\n", field.name.c_str());
formatter->print_field_name(field.name);
}
} else if(markdown) {
printf("%s\n",
fld_class.as_markdown(fieldclass_event_sources[fieldclass_key(fld_class)])
.c_str());
} else {
printf("%s\n",
fld_class
.as_string(verbose,
fieldclass_event_sources[fieldclass_key(fld_class)])
.c_str());
formatter->print_fieldclass(fld_class, fieldclass_event_sources[key]);
}
}
}

formatter->end();
}

std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_content,
Expand Down
6 changes: 5 additions & 1 deletion userspace/engine/falco_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ limitations under the License.
#include "falco_source.h"
#include "falco_load_result.h"
#include "filter_details_resolver.h"
#include "output_format.h"

//
// This class acts as the primary interface between a program and the
Expand Down Expand Up @@ -62,7 +63,10 @@ class falco_engine {

// Print to stdout (using printf) a description of each field supported by this engine.
// If source is non-empty, only fields for the provided source are printed.
void list_fields(const std::string &source, bool verbose, bool names_only, bool markdown) const;
void list_fields(const std::string &source,
bool verbose,
bool names_only,
output_format format) const;

// Provide an alternate rule reader, collector, and compiler
// to compile any rules provided via load_rules*
Expand Down
122 changes: 122 additions & 0 deletions userspace/engine/field_formatter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2026 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "field_formatter.h"
#include "formats.h"

using namespace falco;

// Factory method
std::unique_ptr<FieldFormatter> FieldFormatter::create(output_format format, bool verbose) {
switch(format) {
case output_format::JSON:
return std::make_unique<JsonFieldFormatter>(verbose);
case output_format::MARKDOWN:
return std::make_unique<MarkdownFieldFormatter>(verbose);
case output_format::TEXT:
default:
return std::make_unique<TextFieldFormatter>(verbose);
}
}

// ============================================================================
// TextFieldFormatter implementation
// ============================================================================

TextFieldFormatter::TextFieldFormatter(bool verbose): m_verbose(verbose) {}

void TextFieldFormatter::begin() {
// Nothing to do for text format
}

void TextFieldFormatter::print_fieldclass(
const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) {
printf("%s\n", fld_class.as_string(m_verbose, event_sources).c_str());
}

void TextFieldFormatter::print_field_name(const std::string& name) {
printf("%s\n", name.c_str());
}

void TextFieldFormatter::end() {
// Nothing to do for text format
}

// ============================================================================
// MarkdownFieldFormatter implementation
// ============================================================================

MarkdownFieldFormatter::MarkdownFieldFormatter(bool verbose): m_verbose(verbose) {}

void MarkdownFieldFormatter::begin() {
// Nothing to do for markdown format
}

void MarkdownFieldFormatter::print_fieldclass(
const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) {
printf("%s\n", fld_class.as_markdown(event_sources).c_str());
}

void MarkdownFieldFormatter::print_field_name(const std::string& name) {
printf("%s\n", name.c_str());
}

void MarkdownFieldFormatter::end() {
// Nothing to do for markdown format
}

// ============================================================================
// JsonFieldFormatter implementation
// ============================================================================

JsonFieldFormatter::JsonFieldFormatter(bool verbose): m_verbose(verbose) {}

void JsonFieldFormatter::begin() {
m_fieldclasses_array = nlohmann::json::array();
m_fieldnames_array = nlohmann::json::array();
m_has_fieldclasses = false;
m_has_fieldnames = false;
}

void JsonFieldFormatter::print_fieldclass(
const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) {
std::string json_str = fld_class.as_json(event_sources);
if(!json_str.empty()) {
m_fieldclasses_array.push_back(nlohmann::json::parse(json_str));
m_has_fieldclasses = true;
}
}

void JsonFieldFormatter::print_field_name(const std::string& name) {
m_fieldnames_array.push_back(name);
m_has_fieldnames = true;
}

void JsonFieldFormatter::end() {
nlohmann::json root;

if(m_has_fieldclasses) {
root["fieldclasses"] = m_fieldclasses_array;
printf("%s\n", root.dump(2).c_str());
} else if(m_has_fieldnames) {
root["fieldnames"] = m_fieldnames_array;
printf("%s\n", root.dump(2).c_str());
}
}
102 changes: 102 additions & 0 deletions userspace/engine/field_formatter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2026 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

#include <string>
#include <set>
#include <memory>
#include <nlohmann/json.hpp>

#include <libsinsp/sinsp.h>

enum class output_format;

namespace falco {

// Abstract formatter interface for field listing
class FieldFormatter {
public:
virtual ~FieldFormatter() = default;

// Initialize formatter
virtual void begin() = 0;

// Print a field class with its event sources
virtual void print_fieldclass(const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) = 0;

// Print a single field name (for names_only mode)
virtual void print_field_name(const std::string& name) = 0;

// Finalize and output
virtual void end() = 0;

// Factory method
static std::unique_ptr<FieldFormatter> create(output_format format, bool verbose);
};

// Text formatter (default)
class TextFieldFormatter : public FieldFormatter {
public:
explicit TextFieldFormatter(bool verbose);

void begin() override;
void print_fieldclass(const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) override;
void print_field_name(const std::string& name) override;
void end() override;

private:
bool m_verbose;
};

// Markdown formatter
class MarkdownFieldFormatter : public FieldFormatter {
public:
explicit MarkdownFieldFormatter(bool verbose);

void begin() override;
void print_fieldclass(const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) override;
void print_field_name(const std::string& name) override;
void end() override;

private:
bool m_verbose;
};

// JSON formatter
class JsonFieldFormatter : public FieldFormatter {
public:
explicit JsonFieldFormatter(bool verbose);

void begin() override;
void print_fieldclass(const sinsp_filter_factory::filter_fieldclass_info& fld_class,
const std::set<std::string>& event_sources) override;
void print_field_name(const std::string& name) override;
void end() override;

private:
bool m_verbose;
nlohmann::json m_fieldclasses_array;
nlohmann::json m_fieldnames_array;
bool m_has_fieldclasses{false};
bool m_has_fieldnames{false};
};

} // namespace falco
20 changes: 20 additions & 0 deletions userspace/engine/output_format.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: Apache-2.0
/*
Comment thread
legobrick marked this conversation as resolved.
Copyright (C) 2026 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

enum class output_format { TEXT, MARKDOWN, JSON };
1 change: 1 addition & 0 deletions userspace/falco/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ add_library(
app/actions/print_plugin_info.cpp
app/actions/print_support.cpp
app/actions/print_syscall_events.cpp
app/actions/event_formatter.cpp
app/actions/print_version.cpp
app/actions/print_page_size.cpp
app/actions/configure_syscall_buffer_size.cpp
Expand Down
Loading
Loading