pub trait ExtractPlugin:
Plugin
+ ExtractPluginExported
+ Sizedwhere
Self: 'static,{
type ExtractContext: Default + 'static;
const EVENT_TYPES: &'static [EventType];
const EVENT_SOURCES: &'static [&'static str];
const EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>];
// Provided methods
fn get_fields() -> &'static CStr { ... }
fn extract_fields<'a>(
&'a mut self,
event_input: &EventInput,
table_reader: &LazyTableReader<'_>,
fields: &mut [ss_plugin_extract_field],
storage: &'a mut Bump,
) -> Result<(), Error> { ... }
}
Expand description
§Support for field extraction plugins
Required Associated Constants§
Sourceconst EVENT_TYPES: &'static [EventType]
const EVENT_TYPES: &'static [EventType]
The set of event types supported by this plugin
If empty, the plugin will get invoked for all event types, otherwise it will only get invoked for event types from this list.
Note: some notable event types are:
EventType::ASYNCEVENT_E
, generated from async pluginsEventType::PLUGINEVENT_E
, generated from source plugins
Sourceconst EVENT_SOURCES: &'static [&'static str]
const EVENT_SOURCES: &'static [&'static str]
The set of event sources supported by this plugin
If empty, the plugin will get invoked for events coming from all sources, otherwise it will only get invoked for events from sources named in this list.
Note: one notable event source is called syscall
Sourceconst EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>]
const EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>]
The actual list of extractable fields
An extraction method is a method with the following signature:
use anyhow::Error;
use falco_plugin::extract::{EventInput, ExtractFieldRequestArg, ExtractRequest};
use falco_plugin::tables::TableReader;
fn extract_sample(
&mut self,
req: ExtractRequest<Self>,
arg: A, // optional
) -> Result<R, Error>;
where R
is one of the following types or a Vec
of them:
u64
bool
CString
std::time::SystemTime
std::time::Duration
std::net::IpAddr
falco_event::fields::types::PT_IPNET
and A
is the argument to the field extraction:
Argument declaration | field lookup | field[5] lookup | field[foo] lookup |
---|---|---|---|
missing | valid | - | - |
arg: u64 | - | valid | - |
arg: Option<u64> | valid | valid | - |
arg: &CStr | - | - | valid |
arg: Option<&CStr> | valid | - | valid |
req
is the extraction request (ExtractRequest
), containing the context in which
the plugin is doing the work.
To register extracted fields, add them to the ExtractPlugin::EXTRACT_FIELDS
array, wrapped via crate::extract::field
:
use std::ffi::CStr;
use falco_plugin::event::events::types::EventType;
use falco_plugin::event::events::types::EventType::PLUGINEVENT_E;
use falco_plugin::anyhow::Error;
use falco_plugin::base::Plugin;
use falco_plugin::extract::{
field,
ExtractFieldInfo,
ExtractPlugin,
ExtractRequest};
use falco_plugin::tables::TablesInput;
struct SampleExtractPlugin;
impl Plugin for SampleExtractPlugin {
const NAME: &'static CStr = c"dummy";
const PLUGIN_VERSION: &'static CStr = c"0.0.0";
const DESCRIPTION: &'static CStr = c"test plugin";
const CONTACT: &'static CStr = c"rust@localdomain.pl";
type ConfigType = ();
fn new(_input: Option<&TablesInput>, _config: Self::ConfigType) -> Result<Self, Error> {
Ok(Self)
}
}
impl SampleExtractPlugin {
fn extract_sample(
&mut self,
_req: ExtractRequest<Self>,
) -> Result<u64, Error> {
Ok(10u64)
}
fn extract_arg(
&mut self,
_req: ExtractRequest<Self>,
arg: u64,
) -> Result<u64, Error> {
Ok(arg)
}
}
impl ExtractPlugin for SampleExtractPlugin {
const EVENT_TYPES: &'static [EventType] = &[PLUGINEVENT_E];
const EVENT_SOURCES: &'static [&'static str] = &["dummy"];
type ExtractContext = ();
const EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>] = &[
field("sample.always_10", &Self::extract_sample),
field("sample.arg", &Self::extract_arg)
];
}
Required Associated Types§
Sourcetype ExtractContext: Default + 'static
type ExtractContext: Default + 'static
The extraction context
It might be useful if your plugin supports multiple fields, and they all share some common preprocessing steps. Instead of redoing the preprocessing for each field, intermediate results can be stored in the context for subsequent extractions (from the same event).
If you do not need a context to share between extracting fields of the same event, use ()
as the type.
Since the context is created using the Default
trait, you may prefer to use an Option
wrapping the actual context type:
impl ExtractPlugin for MyPlugin {
type ExtractContext = Option<ActualContext>;
// ...
}
impl MyPlugin {
fn make_context(&mut self, ...) -> ActualContext { /* ... */ }
fn extract_field_one(
&mut self,
req: ExtractContext<Self>) -> ... {
let context = req.context.get_or_insert_with(|| self.make_context(...));
// use context
}
}
Provided Methods§
Sourcefn get_fields() -> &'static CStr
fn get_fields() -> &'static CStr
Generate the field schema for the Falco plugin framework
The default implementation inspects all fields from Self::EXTRACT_FIELDS
and generates
a JSON description in the format expected by the framework.
You probably won’t need to provide your own implementation.
Sourcefn extract_fields<'a>(
&'a mut self,
event_input: &EventInput,
table_reader: &LazyTableReader<'_>,
fields: &mut [ss_plugin_extract_field],
storage: &'a mut Bump,
) -> Result<(), Error>
fn extract_fields<'a>( &'a mut self, event_input: &EventInput, table_reader: &LazyTableReader<'_>, fields: &mut [ss_plugin_extract_field], storage: &'a mut Bump, ) -> Result<(), Error>
Perform the actual field extraction
The default implementation creates an empty context and loops over all extraction requests, invoking the relevant function to actually generate the field value.
You probably won’t need to provide your own implementation.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.