libpressio 0.93.0
Loading...
Searching...
No Matches
Writing a User Metrics Plugin

libpressio supports adding custom metrics plugins.

To create a metrics plugin, simply create a subclass of libpressio_metrics_plugin that implements the check that you are interested in, and register the plugin with libpressio.

For example, let's create a plugin that counts the number of compressions of each data type that the user preforms.

First we will include a number of required headers:

//required for all plugins
#include "libpressio_ext/cpp/metrics.h" // provides the libpressio_metrics_plugin
#include "libpressio_ext/cpp/options.h" // provides pressio_options and related methods
#include "libpressio_ext/cpp/pressio.h" // for the plugin registry
//required for this plugin
#include "libpressio_ext/cpp/data.h" // to be able to access ->dtype()
#include <memory> //for make_unique (in c++14 or later)
#include <map> //for the map that counts what data type was used
C++ pressio_data interface.
C++ interface to the compressor loader.
an extension header for adding metrics plugins to libpressio
C++ pressio_options and pressio_option interfaces.

Next, we need to write our class. Since we want to count the number of data buffers of each type that we compress, we will hook the begin_compress_impl method. Alternatively we could also hook the end_compress_impl method. Once we have the counts, we report them out using the get_metrics_results function. We do this like so:

class counting_metric: public libpressio_metrics_plugin {
counting_metric() {
//operator[] is non-const, so explicits instantiate each of the values we need
counts[pressio_int8_dtype] = 0;
counts[pressio_int16_dtype] = 0;
counts[pressio_int32_dtype] = 0;
counts[pressio_int64_dtype] = 0;
counts[pressio_uint8_dtype] = 0;
counts[pressio_uint16_dtype] = 0;
counts[pressio_uint32_dtype] = 0;
counts[pressio_uint64_dtype] = 0;
counts[pressio_float_dtype] = 0;
counts[pressio_double_dtype] = 0;
counts[pressio_byte_dtype] = 0;
}
//increment the count at the beginning of each compress
void begin_compress_impl(pressio_data const* input, pressio_data const*) override {
counts[input->dtype()]++;
}
//return an options structure containing the metrics we care about
//notice how the namespaced matches the name of the plugin that is registered below
set(opts, "counts:int8", counts.at(pressio_int8_dtype));
set(opts, "counts:int16", counts.at(pressio_int16_dtype));
set(opts, "counts:int32", counts.at(pressio_int32_dtype));
set(opts, "counts:int64", counts.at(pressio_int64_dtype));
set(opts, "counts:uint8", counts.at(pressio_uint8_dtype));
set(opts, "counts:uint16", counts.at(pressio_uint16_dtype));
set(opts, "counts:uint32", counts.at(pressio_uint32_dtype));
set(opts, "counts:uint64", counts.at(pressio_uint64_dtype));
set(opts, "counts:float", counts.at(pressio_float_dtype));
set(opts, "counts:double", counts.at(pressio_double_dtype));
set(opts, "counts:byte", counts.at(pressio_byte_dtype));
return opts;
}
const char* prefix() const {
return "counts";
}
std::map<pressio_dtype, unsigned int> counts;
};
Definition: metrics.h:22
virtual pressio_options get_metrics_results(pressio_options const &options)=0
virtual int begin_compress_impl(const struct pressio_data *input, struct pressio_data const *output)
virtual const char * prefix() const =0
void set(pressio_options &options, StringType const &key, pressio_option const &value) const
Definition: configurable.h:97
@ pressio_byte_dtype
Definition: pressio_dtype.h:27
@ pressio_double_dtype
Definition: pressio_dtype.h:17
@ pressio_int16_dtype
Definition: pressio_dtype.h:24
@ pressio_uint64_dtype
Definition: pressio_dtype.h:22
@ pressio_float_dtype
Definition: pressio_dtype.h:18
@ pressio_uint16_dtype
Definition: pressio_dtype.h:20
@ pressio_int64_dtype
Definition: pressio_dtype.h:26
@ pressio_int8_dtype
Definition: pressio_dtype.h:23
@ pressio_uint8_dtype
Definition: pressio_dtype.h:19
@ pressio_uint32_dtype
Definition: pressio_dtype.h:21
@ pressio_int32_dtype
Definition: pressio_dtype.h:25
Definition: data.h:52
pressio_dtype dtype() const
Definition: data.h:341
Definition: options.h:352

Finally, we will register the plugin in the under the names "counts" in the metrics plugging registry

static pressio_register X(metrics_plugins(), "counts", [](){ return std::make_unique<counting_metric>(); });
Definition: pressio.h:105
pressio_registry< std::unique_ptr< libpressio_metrics_plugin > > & metrics_plugins()

Then a user of the library can then ask libpressio to construct their new plugin as normal. But what if our metrics modules takes arguments? Instead of registering it directly, the user can instantiate it manually and combine it with others from the library using the make_m_composite method.

If your metric is suitably general and well implemented, you can contribute it back to libpressio. Metrics should be added to the src/plugins/metrics/ directory and to the main CMakeLists.txt. If the metric requires additional dependencies beyond the standard library, it should be hidden behind a configuration flag that enables its use and disabled by default.

This full example can be found in the test/test_regsiter_metrics.cc file, and the full documentation of the allowed hooks and their arguments can be found in the documentation for libpressio_metrics_plugin.