mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Settle time for stats protocol, documentation
This commit is contained in:
parent
727a8f32c4
commit
1c12cc9a11
@ -5411,6 +5411,54 @@ protocol static {
|
||||
}
|
||||
</code>
|
||||
|
||||
<sect>Stats
|
||||
<label id="stats">
|
||||
|
||||
<sect1>
|
||||
<label id="stats-intro">
|
||||
|
||||
<p>The Statistics protocol allows you to measure number of exported routes from
|
||||
a table. You can also narrow the view by applying export filter inside stats
|
||||
channel. One instance of stats protocol can have multiple channels attached.
|
||||
Stats protocol could be particullary useful when making conditional route advertising.
|
||||
|
||||
<p>Statistics are accessed in filters by same name as channel connected to desired
|
||||
table. Value of this expresion is evaluated to the sum of all routes with
|
||||
generation smaller than max generation (see below).
|
||||
|
||||
<sect1>Configuration
|
||||
<label id="stats-config">
|
||||
|
||||
<p><descrtip>
|
||||
<tag><label id="stats-max-generation">max generation <m/expr/</tag>
|
||||
Statistics counter contains sum of all routes with generation less
|
||||
than or equal to max generation. This copies behavior of pipe's
|
||||
<ref id="pipe-max-generation" name="max generetion">. Must be in range
|
||||
from 0 to 254. Default: 16.
|
||||
|
||||
<tag><label id="stats-update-after">settle time <m/time/ <m/number/</tag>
|
||||
Wait given amount of time before notifying and recalculting filters
|
||||
which reference this counter in seconds. If counter changes during this period,
|
||||
current value is used. If set to zero, the notification is done instantly.
|
||||
Default: 5 s.
|
||||
</descrip>
|
||||
|
||||
<p>Example
|
||||
<code>
|
||||
protocol stats {
|
||||
ipv4 stats1 { table bgp_tab1; };
|
||||
}
|
||||
|
||||
protocol static {
|
||||
# note that the stats1 is unrelated
|
||||
ipv4 { import where stats1 > 200; };
|
||||
route 0.0.0.0:0;
|
||||
}
|
||||
</code>
|
||||
|
||||
<p>Beware that configuration with cyclic references (even logical ones) are
|
||||
considered invalid and the behaviour is not defined! You <em>should</em> avoid
|
||||
them. No detection is implemented.
|
||||
|
||||
<chapt>Conclusions
|
||||
<label id="conclusion">
|
||||
|
@ -9,18 +9,15 @@
|
||||
|
||||
CF_HDR
|
||||
|
||||
/* old: #include "proto/pipe/pipe.h" */
|
||||
#include "proto/stats/stats.h"
|
||||
|
||||
CF_DEFINES
|
||||
|
||||
/* old: #define PIPE_CFG ((struct pipe_config *) this_proto) */
|
||||
#define STATS_CC ((struct stats_channel_config *) this_channel)
|
||||
|
||||
CF_DECLS
|
||||
|
||||
/* TODO here add more keywords */
|
||||
CF_KEYWORDS(STATS, TABLE, MAX, GENERATION)
|
||||
CF_KEYWORDS(STATS, TABLE, MAX, GENERATION, SETTLE, TIME)
|
||||
|
||||
%type <cc> stats_channel_start
|
||||
|
||||
@ -48,21 +45,25 @@ channel_max_gen:
|
||||
}
|
||||
;
|
||||
|
||||
stats_settle:
|
||||
SETTLE TIME time {
|
||||
STATS_CC->settle = $3 S_;
|
||||
}
|
||||
|
||||
stats_opts:
|
||||
/* empty */
|
||||
| stats_opts channel_item ';'
|
||||
| stats_opts channel_max_gen ';'
|
||||
| stats_opts stats_settle ';'
|
||||
;
|
||||
|
||||
stats_proto_channel: stats_channel_start stats_channel_opt_list channel_end ;
|
||||
/* stats_proto_channel: stats_channel_start stats_max_gen channel_opt_list channel_end ; */
|
||||
|
||||
stats_channel_start: net_type symbol
|
||||
{
|
||||
this_channel = channel_config_get(&channel_stats, $2->name, $1, this_proto);
|
||||
STATS_CC->max_generation = 16;
|
||||
/* from filter/config.Y:
|
||||
cf_define_symbol($3, SYM_VARIABLE | $2, offset, $3->scope->slots++) */
|
||||
STATS_CC->settle = 5 S_;
|
||||
$2 = cf_define_symbol($2, SYM_COUNTER, ch_config, this_channel);
|
||||
}
|
||||
|
||||
|
@ -22,30 +22,44 @@
|
||||
#include "conf/conf.h"
|
||||
#include "filter/filter.h"
|
||||
#include "lib/string.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
#include "stats.h"
|
||||
|
||||
#ifdef CONFIG_BGP
|
||||
#include "proto/bgp/bgp.h"
|
||||
#endif
|
||||
#define COUNTER 255
|
||||
|
||||
static void stats_kick_timer(struct stats_channel *c);
|
||||
|
||||
static void
|
||||
stats_rt_notify(struct proto *P UNUSED, struct channel *src_ch, const net_addr *n UNUSED, rte *new, const rte *old)
|
||||
{
|
||||
struct stats_channel *ch = (void *) src_ch;
|
||||
|
||||
int changed = 0;
|
||||
if (old)
|
||||
{
|
||||
ch->counters[old->generation]--;
|
||||
if (old->generation < ch->max_generation)
|
||||
ch->sum--;
|
||||
{
|
||||
changed = 1;
|
||||
ch->counters[COUNTER]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (new)
|
||||
{
|
||||
ch->counters[new->generation]++;
|
||||
if (new->generation < ch->max_generation)
|
||||
ch->sum++;
|
||||
{
|
||||
changed = 1;
|
||||
ch->counters[COUNTER]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
log(L_INFO "stats: timer kicked with time %u", ch->settle);
|
||||
stats_kick_timer((struct stats_channel *) ch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +83,7 @@ stats_configure_channels(struct proto *P, struct proto_config *CF)
|
||||
struct stats_channel_config *scc = (void *) cc;
|
||||
|
||||
sc->max_generation = scc->max_generation;
|
||||
sc->settle = scc->settle;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,11 +132,17 @@ stats_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
struct stats_channel_config *scc = (void *) cc;
|
||||
|
||||
sc->max_generation = scc->max_generation;
|
||||
sc->settle = scc->settle;
|
||||
|
||||
/* recalculate sum */
|
||||
sc->sum = 0;
|
||||
sc->counters[COUNTER] = 0;
|
||||
for (u8 i = 0; i < sc->max_generation; i++)
|
||||
sc->sum += sc->counters[i];
|
||||
sc->counters[COUNTER] += sc->counters[i];
|
||||
|
||||
sc->sum = sc->counters[COUNTER];
|
||||
|
||||
/* notify all hooked filters */
|
||||
// TODO here
|
||||
|
||||
c->stale = 0;
|
||||
}
|
||||
@ -161,7 +182,11 @@ stats_show_proto_info(struct proto *P)
|
||||
|
||||
cli_msg(-1006, " Channel %s", sc->c.name);
|
||||
cli_msg(-1006, " Max generation: %3u", sc->max_generation);
|
||||
cli_msg(-1006, " Exports: %10u", sc->sum);
|
||||
// FIXME : actual or visible to filters ? AND TIME below in the comment
|
||||
cli_msg(-1006, " Exports: %10u (currently: %10u)",
|
||||
sc->sum,
|
||||
sc->counters[COUNTER]);
|
||||
cli_msg(-1006, " Settle time: %7u s", sc->settle / 1000000 );
|
||||
cli_msg(-1006, " Counter exported");
|
||||
|
||||
for (u8 i = 0; i < len; i++)
|
||||
@ -186,6 +211,32 @@ stats_update_debug(struct proto *P)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stats_timer(timer *t)
|
||||
{
|
||||
log(L_INFO "timer executing update");
|
||||
struct stats_channel *c = (struct stats_channel *) t->data;
|
||||
|
||||
/* update the sum correct counter data */
|
||||
c->sum = c->counters[COUNTER];
|
||||
|
||||
/* notify all filters to reevaluate them */
|
||||
// TODO here
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
stats_kick_timer(struct stats_channel *c)
|
||||
{
|
||||
|
||||
/* if set to zero execute immediately */
|
||||
if (!c->settle)
|
||||
stats_timer(c->timer);
|
||||
|
||||
if (!tm_active(c->timer))
|
||||
tm_start(c->timer, c->settle);
|
||||
}
|
||||
|
||||
static int
|
||||
stats_channel_start(struct channel *C)
|
||||
{
|
||||
@ -194,6 +245,8 @@ stats_channel_start(struct channel *C)
|
||||
|
||||
c->pool = p->p.pool;
|
||||
|
||||
c->timer = tm_new_init(c->pool, stats_timer, (void *) c, 0, 0);
|
||||
|
||||
c->counters = mb_allocz(c->pool, 256 * sizeof(u32));
|
||||
c->sum = 0;
|
||||
|
||||
@ -207,6 +260,10 @@ stats_channel_shutdown(struct channel *C)
|
||||
|
||||
mb_free(c->counters);
|
||||
|
||||
/* FIXME freed automatically by the resource pool ?
|
||||
rfree(c->timer);
|
||||
*/
|
||||
|
||||
c->max_generation = 0;
|
||||
c->counters = NULL;
|
||||
c->pool = NULL;
|
||||
|
@ -28,11 +28,14 @@ struct stats_channel {
|
||||
u8 max_generation;
|
||||
u32 *counters;
|
||||
u32 sum;
|
||||
timer *timer;
|
||||
btime settle;
|
||||
};
|
||||
|
||||
struct stats_channel_config {
|
||||
struct channel_config c;
|
||||
u8 max_generation;
|
||||
btime settle;
|
||||
};
|
||||
|
||||
static inline int
|
||||
|
Loading…
Reference in New Issue
Block a user