Skip to content

Commit

Permalink
Dummy output: add simple statistics counters
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas955 committed May 5, 2020
1 parent 9253af5 commit 4f03dd9
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/plugins/output/dummy/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Example configuration
<plugin>dummy</plugin>
<params>
<delay>0</delay>
<stats>true</stats>
</params>
</output>
Expand All @@ -23,3 +24,7 @@ Parameters

:``delay``:
Minimum delay between processing of two consecutive messages in microseconds.

:``stats``:
Print basic statistics after termination (flows, bytes, packets).
[values: true/false, default: false]
9 changes: 8 additions & 1 deletion src/plugins/output/dummy/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@

/** XML nodes */
enum params_xml_nodes {
NODE_DELAY = 1
NODE_DELAY = 1,
NODE_STATS
};

/** Definition of the \<params\> node */
static const struct fds_xml_args args_params[] = {
FDS_OPTS_ROOT("params"),
FDS_OPTS_ELEM(NODE_DELAY, "delay", FDS_OPTS_T_UINT, 0),
FDS_OPTS_ELEM(NODE_STATS, "stats", FDS_OPTS_T_BOOL, FDS_OPTS_P_OPT),
FDS_OPTS_END
};

Expand All @@ -83,6 +85,10 @@ config_parser_root(ipx_ctx_t *ctx, fds_xml_ctx_t *root, struct instance_config *
cfg->sleep_time.tv_nsec = (content->val_uint % 1000000LL) * 1000LL;
cfg->sleep_time.tv_sec = content->val_uint / 1000000LL;
break;
case NODE_STATS:
assert(content->type == FDS_OPTS_T_BOOL);
cfg->en_stats = content->val_bool;
break;
default:
// Internal error
assert(false);
Expand All @@ -101,6 +107,7 @@ config_default_set(struct instance_config *cfg)
{
cfg->sleep_time.tv_sec = 0;
cfg->sleep_time.tv_nsec = 100000000LL; // 100ms between messages
cfg->en_stats = false;
}

struct instance_config *
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/output/dummy/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
struct instance_config {
/** Sleep time */
struct timespec sleep_time;
/** Enable statistics */
bool en_stats;
};

/**
Expand Down
80 changes: 76 additions & 4 deletions src/plugins/output/dummy/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* \file src/plugins/output/dummy/dummy.c
* \author Lukas Hutak <[email protected]>
* \brief Example output plugin for IPFIXcol 2
* \date 2018
* \date 2018-2020
*/

/* Copyright (C) 2018 CESNET, z.s.p.o.
/* Copyright (C) 2018-2020 CESNET, z.s.p.o.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -57,7 +57,7 @@ IPX_API struct ipx_plugin_info ipx_plugin_info = {
// Configuration flags (reserved for future use)
.flags = 0,
// Plugin version string (like "1.2.3")
.version = "2.0.0",
.version = "2.1.0",
// Minimal IPFIXcol version string (like "1.2.3")
.ipx_min = "2.0.0"
};
Expand All @@ -66,8 +66,72 @@ IPX_API struct ipx_plugin_info ipx_plugin_info = {
struct instance_data {
/** Parsed configuration of the instance */
struct instance_config *config;

/** Total number of Data Records (based on an IPFIX Template) */
uint64_t cnt_flows_data;
/** Total number of Data Records (based on an IPFIX Options Template */
uint64_t cnt_flows_opts;
/** Total number of bytes in Data Records */
uint64_t cnt_bytes;
/** Total number of packets in Data Records */
uint64_t cnt_pkts;
};

/**
* @brief Update statistics about flow records
*
* @param[in] inst Plugin instance
* @param[in] msg IPFIX Message
*/
static void
stats_update(struct instance_data *inst, ipx_msg_ipfix_t *msg)
{
uint32_t rec_cnt = ipx_msg_ipfix_get_drec_cnt(msg);

// For each IPFIX Data Record
for (uint32_t i = 0; i < rec_cnt; ++i) {
struct ipx_ipfix_record *rec_ptr = ipx_msg_ipfix_get_drec(msg, i);
enum fds_template_type ttype = rec_ptr->rec.tmplt->type;

struct fds_drec_field field;
uint64_t value;

// Get type of the Data Record
if (ttype == FDS_TYPE_TEMPLATE) {
inst->cnt_flows_data++;
} else if (ttype == FDS_TYPE_TEMPLATE_OPTS) {
inst->cnt_flows_opts++;
continue; // Options records doesn't contain packet and byte counters
}

// Get octetDeltaCount
if (fds_drec_find(&rec_ptr->rec, 0, 1, &field) != FDS_EOC
&& fds_get_uint_be(field.data, field.size, &value) == FDS_OK) {
inst->cnt_bytes += value;
}

// Get packetDeltaCount
if (fds_drec_find(&rec_ptr->rec, 0, 2, &field) != FDS_EOC
&& fds_get_uint_be(field.data, field.size, &value) == FDS_OK) {
inst->cnt_pkts += value;
}
}
}

/**
* @brief Print statistics
* @param[in] inst Plugin instance
*/
static void
stats_print(const struct instance_data *inst)
{
printf("Stats:\n");
printf("- data records: %10" PRIu64 "\n", inst->cnt_flows_data);
printf("- options records: %10" PRIu64 "\n", inst->cnt_flows_opts);
printf("- total bytes: %10" PRIu64 "\n", inst->cnt_bytes);
printf("- total packets: %10" PRIu64 "\n", inst->cnt_pkts);
}

int
ipx_plugin_init(ipx_ctx_t *ctx, const char *params)
{
Expand All @@ -94,8 +158,12 @@ void
ipx_plugin_destroy(ipx_ctx_t *ctx, void *cfg)
{
(void) ctx; // Suppress warnings

struct instance_data *data = (struct instance_data *) cfg;

if (data->config->en_stats) {
stats_print(data);
}

config_destroy(data->config);
free(data);
}
Expand All @@ -111,6 +179,10 @@ ipx_plugin_process(ipx_ctx_t *ctx, void *cfg, ipx_msg_t *msg)
ipx_msg_ipfix_t *ipfix_msg = ipx_msg_base2ipfix(msg);
const struct ipx_msg_ctx *ipfix_ctx = ipx_msg_ipfix_get_ctx(ipfix_msg);
IPX_CTX_INFO(ctx, "[ODID: %" PRIu32 "] Received an IPFIX message", ipfix_ctx->odid);

if (data->config->en_stats) {
stats_update(data, ipfix_msg);
}
}

if (type == IPX_MSG_SESSION) {
Expand Down

0 comments on commit 4f03dd9

Please sign in to comment.