Trait ExtractPlugin

Source
pub trait ExtractPlugin:
    Plugin
    + ExtractPluginExported
    + Sized
where Self: 'static,
{ type Event<'a>: AnyEventPayload + TryFrom<&'a RawEvent<'a>>; type ExtractContext: Default + 'static; const EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>]; // Provided methods fn get_fields() -> &'static CStr { ... } fn extract_fields<'a>( &'a mut self, event_input: &EventInput<'a, Self::Event<'a>>, table_reader: &LazyTableReader<'_>, fields: &mut [ss_plugin_extract_field], offsets: Option<&mut ss_plugin_extract_value_offsets>, storage: &'a Bump, ) -> Result<(), Error> { ... } }
Expand description

Support for field extraction plugins

Required Associated Constants§

Source

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:

and A is the argument to the field extraction:

Argument declarationfield lookupfield[5] lookupfield[foo] lookup
missingvalid--
arg: u64-valid-
arg: Option<u64>validvalid-
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_event::events::RawEvent;
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 {
    type ExtractContext = ();
    type Event<'a> = RawEvent<'a>;
    const EXTRACT_FIELDS: &'static [ExtractFieldInfo<Self>] = &[
        field("sample.always_10", &Self::extract_sample),
        field("sample.arg", &Self::extract_arg)
    ];
}

Required Associated Types§

Source

type Event<'a>: AnyEventPayload + TryFrom<&'a RawEvent<'a>>

§Event type to perform extractions on

Events will be parsed into this type before being passed to the plugin, so you can work directly on the deserialized form and don’t need to worry about validating the events.

If an event fails this conversion, an error will be returned from EventInput::event, which you can propagate directly to the caller.

If you don’t want any specific validation/conversion to be performed, specify the type as

type Event<'a> = falco_event::events::RawEvent<'a>;
Source

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§

Source

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.

Source

fn extract_fields<'a>( &'a mut self, event_input: &EventInput<'a, Self::Event<'a>>, table_reader: &LazyTableReader<'_>, fields: &mut [ss_plugin_extract_field], offsets: Option<&mut ss_plugin_extract_value_offsets>, storage: &'a 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.

Implementors§