StatsLog

Transmit the values of an aggregate to be used within graphite.

This class has 2 methods which can be used: add and addObject.

add is meant for application statistics, i.e. amount of memory used, number of channels alive, number of connections open, largest record processed...

addObject logs an instance of an object which belongs to a category. This method should be used when you have a set of standard metrics which you want to log for multiple instances of a type of object. For example, you may want to log standard stats for each channel in a storage engine, for each campaign of an advertiser, for each source of input records, etc.

See the methods description for more informations.

Note: StatsLog formerly had the ability to write single value instead of an aggregate. It was removed as it goes against Collectd's design, where data sent to the socket are sent aggregated by 'types', where a type is a collection of related metrics (akin to a struct), so single values are not permitted. In addition, it's not possible to incrementally build an aggregate either, as we need the aggregate's complete definition : if we send incomplete/too much data to Collectd, it just rejects the whole aggregate, and data is sent without field names, as Collectd relies on its type definition for that piece of information. Having the wrong order would mean some metrics are logged as other metrics, a bug that might not be easily identifiable. This was leaving too much room for error which were not easily identifiable.

Constructors

this
this(Config config, istring name)

Constructor. Creates the stats log using the AppendSysLog appender.

this
this(Config config, Appender delegate(istring file, Appender.Layout layout) new_appender, istring name)

Constructor. Creates the stats log using the appender returned by the provided delegate.

Members

Classes

Config
class Config

Stats log config class

Functions

add
typeof(this) add(T values)

Adds the values of the given aggregate to the stats log. Each member of the aggregate will be output as <member name>:<member value>.

addObject
typeof(this) addObject(cstring instance, T values)

Adds the values of the given aggregate to the stats log. Each member of the aggregate will be output as <category>/<instance>/<member name>:<member value>.

flush
void flush()

Flush everything to file and prepare for the next iteration

Static variables

default_file_name
istring default_file_name;
Undocumented in source.
default_period
time_t default_period;

Stats log default settings (used in ctor)

Variables

buffer
AppendBuffer!(char) buffer;

Message formatter

collectd
Collectd collectd;

Collectd instance

identifier
Identifier identifier;

Default identifier when doing add.

logger
Logger logger;

Logger instance via which stats should be output

options
Collectd.PutvalOptions options;

Default set options to send

Examples

See the unittest following this class for an example application

Usage example for StatsLog in a simple application

class MyStatsLogApp : DaemonApp
{
    private static struct Stats
    {
        double awesomeness;
        double bytes_written;
        double bytes_received;
    }

    private static struct Channel
    {
        double profiles_in;
        double profiles_out;
    }

    public this ()
    {
        super("Test", null, null);
    }

    protected override int run (Arguments args, ConfigParser config)
    {
        auto epoll = new EpollSelectDispatcher;
        this.startEventHandling(epoll);
        return 0;
    }

    protected override void onStatsTimer ( )
    {
        // Do some heavy-duty processing ...
        Stats app_stats1 = { 42_000_000, 10_000_000,  1_000_000 };
        Stats app_stats2 = { 42_000_000,  1_000_000, 10_000_000 };
        this.stats_ext.stats_log.add(app_stats1);

        // A given struct should be `add`ed once and only once, unless
        // you flush in between
        this.stats_ext.stats_log.flush();
        this.stats_ext.stats_log.add(app_stats2);

        // Though if you use `addObject`, it's okay as long as the instance
        // name is different
        Channel disney = { 100_000, 100_000 };
        Channel discovery = { 10_000, 10_000 };

        // For the same struct type, you probably want the
        // same category name. It's not a requirement but there are
        // no known use case where you want it to differ.
        this.stats_ext.stats_log.addObject!("channel")("disney", disney);
        this.stats_ext.stats_log.addObject!("channel")("discovery", discovery);
    }
}

Meta