Here you will find an example plugin that covers the basics for writing a collector plugin.
For your collector plugin, create a new repository and name your plugin project using the following format:
snap-plugin-[plugin-type]-[plugin-name]
For example:
snap-plugin-collector-rando
Proposed files and directory structure:
snap-plugin-[plugin-type]-[plugin-name]
|--src
|--[plugin-name].cc
|--[plugin-name]_test.cc
For example:
snap-plugin-collector-rando
|--src
|--rando.cc
|--rando_test.cc
In order to write a plugin for Snap, it is necessary to define a few methods to satisfy the appropriate interfaces. These interfaces must be defined for a collector plugin:
/**
* The interface for a collector plugin.
* A Collector is the source.
* It is responsible for collecting metrics in the Snap pipeline.
*/
class CollectorInterface : public PluginInterface {
public:
Type GetType() const final;
CollectorInterface* IsCollector() final;
/*
* (inherited from PluginInterface)
*/
virtual const ConfigPolicy get_config_policy() = 0;
/*
* get_metric_types should report all the metrics this plugin can collect.
*/
virtual std::vector<Metric> get_metric_types(Config cfg) = 0;
/*
* collect_metrics is given a list of metrics to collect.
* It should collect and annotate each metric with the apropos context.
*/
virtual void collect_metrics(std::vector<Metric> &metrics) = 0;
};
The interface is slightly different depending on what type (collector, processor, or publisher) of plugin is being written. Please see other plugin types for more details.
After implementing a type that satisfies one of {collector, processor, publisher} interfaces, all that is left to do is to call the appropriate plugin.start_xxx() with your plugin specific meta options. For example with minimum meta data specified:
Plugin::start_collector(argc, argv, &plg, Meta{Type::Collector, "rando", 1});
The available options are defined in src/snap/plugin.h. This structure defines default values. Plugin developer needs to define only plugin Type, name and version.
/**
* Meta is the metadata about the plugin.
*/
struct Meta final {
public:
Meta(Type type, std::string name, int version);
Type type;
std::string name;
int version;
/**
* The RpcType in use, defaults to RpcType::GRPC. There should be no need to change
* it.
*/
RpcType rpc_type;
/**
* concurrency_count is the max number of concurrent calls the plugin
* should take. For example:
* If there are 5 tasks using the plugin and its concurrency count is 2,
* snapteld will keep 3 plugin instances running.
* Using concurrency_count overwrites the default value of (5).
*/
int concurrency_count;
/**
* exclusive == true results in a single instance of the plugin running
* regardless of the number of tasks using the plugin.
* Using exclusive overwrites the default value of (false).
*/
bool exclusive;
/**
* snapteld caches metrics on the daemon side for a default of 500ms.
* CacheTTL overwrites the default value of (500ms).
*/
std::chrono::milliseconds cache_ttl;
/**
* Strategy will override the routing strategy this plugin requires.
* The default routing strategy is Least Recently Used.
* Strategy overwrites the default value of (LRU).
*/
Strategy strategy;
};
An example using some arbitrary values:
Meta meta(Type::Collector, "rando", 1);
Rando plg;
start_collector(argc, argv, &plg, meta);
Official Snap plugins differentiate tests by scope into "small", "medium" and "large". That's also the strategy recommended for plugins developed using this library. For testing reference see the Snap Testing Guidelines. To test your plugin with Snap you will need to have Snap installed, check out these docs for Snap setup details, keeping in mind it's targeting Go based plugins. For C++ plugins test development consider using Google Test framework, which was selected to test this library itself.
You've made a plugin! Now it's time to share it. Create a release by following these steps. We recommend that your release version match your plugin version, as set in Plugin::Meta.
Don't forget to announce your plugin release on slack and get your plugin added to the Plugin Catalog!