mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
Settle time for stats protocol, documentation
This commit is contained in:
parent
727a8f32c4
commit
1c12cc9a11
@ -5411,6 +5411,54 @@ protocol static {
|
|||||||
}
|
}
|
||||||
</code>
|
</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
|
<chapt>Conclusions
|
||||||
<label id="conclusion">
|
<label id="conclusion">
|
||||||
|
@ -9,18 +9,15 @@
|
|||||||
|
|
||||||
CF_HDR
|
CF_HDR
|
||||||
|
|
||||||
/* old: #include "proto/pipe/pipe.h" */
|
|
||||||
#include "proto/stats/stats.h"
|
#include "proto/stats/stats.h"
|
||||||
|
|
||||||
CF_DEFINES
|
CF_DEFINES
|
||||||
|
|
||||||
/* old: #define PIPE_CFG ((struct pipe_config *) this_proto) */
|
|
||||||
#define STATS_CC ((struct stats_channel_config *) this_channel)
|
#define STATS_CC ((struct stats_channel_config *) this_channel)
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
/* TODO here add more keywords */
|
CF_KEYWORDS(STATS, TABLE, MAX, GENERATION, SETTLE, TIME)
|
||||||
CF_KEYWORDS(STATS, TABLE, MAX, GENERATION)
|
|
||||||
|
|
||||||
%type <cc> stats_channel_start
|
%type <cc> stats_channel_start
|
||||||
|
|
||||||
@ -48,21 +45,25 @@ channel_max_gen:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
stats_settle:
|
||||||
|
SETTLE TIME time {
|
||||||
|
STATS_CC->settle = $3 S_;
|
||||||
|
}
|
||||||
|
|
||||||
stats_opts:
|
stats_opts:
|
||||||
/* empty */
|
/* empty */
|
||||||
| stats_opts channel_item ';'
|
| stats_opts channel_item ';'
|
||||||
| stats_opts channel_max_gen ';'
|
| 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_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
|
stats_channel_start: net_type symbol
|
||||||
{
|
{
|
||||||
this_channel = channel_config_get(&channel_stats, $2->name, $1, this_proto);
|
this_channel = channel_config_get(&channel_stats, $2->name, $1, this_proto);
|
||||||
STATS_CC->max_generation = 16;
|
STATS_CC->max_generation = 16;
|
||||||
/* from filter/config.Y:
|
STATS_CC->settle = 5 S_;
|
||||||
cf_define_symbol($3, SYM_VARIABLE | $2, offset, $3->scope->slots++) */
|
|
||||||
$2 = cf_define_symbol($2, SYM_COUNTER, ch_config, this_channel);
|
$2 = cf_define_symbol($2, SYM_COUNTER, ch_config, this_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,30 +22,44 @@
|
|||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "filter/filter.h"
|
#include "filter/filter.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
|
|
||||||
#ifdef CONFIG_BGP
|
#define COUNTER 255
|
||||||
#include "proto/bgp/bgp.h"
|
|
||||||
#endif
|
static void stats_kick_timer(struct stats_channel *c);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stats_rt_notify(struct proto *P UNUSED, struct channel *src_ch, const net_addr *n UNUSED, rte *new, const rte *old)
|
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;
|
struct stats_channel *ch = (void *) src_ch;
|
||||||
|
|
||||||
|
int changed = 0;
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
ch->counters[old->generation]--;
|
ch->counters[old->generation]--;
|
||||||
if (old->generation < ch->max_generation)
|
if (old->generation < ch->max_generation)
|
||||||
ch->sum--;
|
{
|
||||||
|
changed = 1;
|
||||||
|
ch->counters[COUNTER]--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
ch->counters[new->generation]++;
|
ch->counters[new->generation]++;
|
||||||
if (new->generation < ch->max_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;
|
struct stats_channel_config *scc = (void *) cc;
|
||||||
|
|
||||||
sc->max_generation = scc->max_generation;
|
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;
|
struct stats_channel_config *scc = (void *) cc;
|
||||||
|
|
||||||
sc->max_generation = scc->max_generation;
|
sc->max_generation = scc->max_generation;
|
||||||
|
sc->settle = scc->settle;
|
||||||
|
|
||||||
/* recalculate sum */
|
/* recalculate sum */
|
||||||
sc->sum = 0;
|
sc->counters[COUNTER] = 0;
|
||||||
for (u8 i = 0; i < sc->max_generation; i++)
|
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;
|
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, " Channel %s", sc->c.name);
|
||||||
cli_msg(-1006, " Max generation: %3u", sc->max_generation);
|
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");
|
cli_msg(-1006, " Counter exported");
|
||||||
|
|
||||||
for (u8 i = 0; i < len; i++)
|
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
|
static int
|
||||||
stats_channel_start(struct channel *C)
|
stats_channel_start(struct channel *C)
|
||||||
{
|
{
|
||||||
@ -194,6 +245,8 @@ stats_channel_start(struct channel *C)
|
|||||||
|
|
||||||
c->pool = p->p.pool;
|
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->counters = mb_allocz(c->pool, 256 * sizeof(u32));
|
||||||
c->sum = 0;
|
c->sum = 0;
|
||||||
|
|
||||||
@ -207,6 +260,10 @@ stats_channel_shutdown(struct channel *C)
|
|||||||
|
|
||||||
mb_free(c->counters);
|
mb_free(c->counters);
|
||||||
|
|
||||||
|
/* FIXME freed automatically by the resource pool ?
|
||||||
|
rfree(c->timer);
|
||||||
|
*/
|
||||||
|
|
||||||
c->max_generation = 0;
|
c->max_generation = 0;
|
||||||
c->counters = NULL;
|
c->counters = NULL;
|
||||||
c->pool = NULL;
|
c->pool = NULL;
|
||||||
|
@ -28,11 +28,14 @@ struct stats_channel {
|
|||||||
u8 max_generation;
|
u8 max_generation;
|
||||||
u32 *counters;
|
u32 *counters;
|
||||||
u32 sum;
|
u32 sum;
|
||||||
|
timer *timer;
|
||||||
|
btime settle;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stats_channel_config {
|
struct stats_channel_config {
|
||||||
struct channel_config c;
|
struct channel_config c;
|
||||||
u8 max_generation;
|
u8 max_generation;
|
||||||
|
btime settle;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
Loading…
Reference in New Issue
Block a user