mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Stats add custom expression to protocol
This commit is contained in:
parent
c4fdf63482
commit
e299ebd5b6
@ -483,8 +483,8 @@
|
|||||||
SYMBOL;
|
SYMBOL;
|
||||||
NEVER_CONSTANT;
|
NEVER_CONSTANT;
|
||||||
|
|
||||||
RESULT_TYPE(stats_get_type(sym->term));
|
RESULT_TYPE(sym->val->type);
|
||||||
RESULT_VAL(stats_eval_term(sym->term));
|
RESULT_VAL(*sym->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
INST(FI_CONSTANT, 0, 1) {
|
INST(FI_CONSTANT, 0, 1) {
|
||||||
|
@ -43,18 +43,20 @@ stats_opt:
|
|||||||
type symbol '=' term {
|
type symbol '=' term {
|
||||||
|
|
||||||
struct stats_term_config *tc = cfg_alloc(sizeof(struct stats_term_config));
|
struct stats_term_config *tc = cfg_alloc(sizeof(struct stats_term_config));
|
||||||
|
struct f_val *val = cfg_allocz(sizeof(struct stats_term_config));
|
||||||
tc->code = (const struct f_line *) f_linearize($4);
|
tc->code = (const struct f_line *) f_linearize($4);
|
||||||
tc->type = $1;
|
tc->type = $1;
|
||||||
tc->name = $2->name;
|
tc->name = $2->name;
|
||||||
|
tc->val = val;
|
||||||
|
|
||||||
struct f_val val;
|
|
||||||
/* greater then F_RETURN, therefore 2 */
|
/* greater then F_RETURN, therefore 2 */
|
||||||
if (f_eval(f_linearize($4), &val) > 2) cf_error("Runtime error");
|
//if (f_eval(f_linearize($4), &val) > 2) cf_error("Runtime error");
|
||||||
if (val.type != $1) cf_error("The expresion does not match defined type");
|
//if (val.type != $1) cf_error("The expresion does not match defined type");
|
||||||
|
|
||||||
add_tail(&STATS_CFG->terms, (node *) tc);
|
add_tail(&STATS_CFG->terms, (node *) tc);
|
||||||
|
stats_eval_term(tc);
|
||||||
|
|
||||||
$2 = cf_define_symbol($2, SYM_COUNTER_TERM, term, tc);
|
$2 = cf_define_symbol($2, SYM_COUNTER_TERM, val, val);
|
||||||
}
|
}
|
||||||
| MIN SETTLE TIME expr_us { STATS_CC->min_settle_time = $4; }
|
| MIN SETTLE TIME expr_us { STATS_CC->min_settle_time = $4; }
|
||||||
| MAX SETTLE TIME expr_us { STATS_CC->max_settle_time = $4; }
|
| MAX SETTLE TIME expr_us { STATS_CC->max_settle_time = $4; }
|
||||||
|
@ -2,6 +2,4 @@
|
|||||||
#define _BIRD_STATS_PUB_H_
|
#define _BIRD_STATS_PUB_H_
|
||||||
|
|
||||||
extern int stats_get_counter(struct symbol *sym);
|
extern int stats_get_counter(struct symbol *sym);
|
||||||
extern struct f_val stats_eval_term(struct stats_term_config *tc);
|
|
||||||
extern int stats_get_type(struct stats_term_config *tc);
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,35 +36,25 @@ stats_rt_notify(struct proto *P UNUSED, struct channel *src_ch, const net_addr *
|
|||||||
int changed = 0;
|
int changed = 0;
|
||||||
if (new && old)
|
if (new && old)
|
||||||
/* count of exported routes stays the same */
|
/* count of exported routes stays the same */
|
||||||
log(L_INFO "nothing happen - no change of counter");
|
|
||||||
else if (!old)
|
else if (!old)
|
||||||
{
|
{
|
||||||
log(L_INFO "increasing _counter");
|
|
||||||
ch->_counter++;
|
ch->_counter++;
|
||||||
changed = 1;
|
changed = 1;
|
||||||
if (ch->_counter > 100)
|
|
||||||
log(L_INFO "underflow?");
|
|
||||||
}
|
}
|
||||||
else if (!new)
|
else if (!new)
|
||||||
{
|
{
|
||||||
log(L_INFO "decreasing _counter");
|
|
||||||
ch->_counter--;
|
ch->_counter--;
|
||||||
changed = 1;
|
changed = 1;
|
||||||
if (ch->_counter > 100)
|
|
||||||
log(L_INFO "underflow? - ");
|
|
||||||
}
|
}
|
||||||
else /* shouldn't happen */
|
else /* shouldn't happen */
|
||||||
{
|
{
|
||||||
log(L_INFO "BUG is here !!!");
|
|
||||||
bug("Both pointers *new and *old in rt_notify are NULL");
|
bug("Both pointers *new and *old in rt_notify are NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
log(L_INFO "stats channel %s: preparing to kick the timer %d", src_ch->name,
|
|
||||||
changed);
|
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
settle_timer_changed(ch->settle_timer);
|
settle_timer_changed(&ch->settle_timer);
|
||||||
kick_settle_timer(ch->settle_timer);
|
kick_settle_timer(&ch->settle_timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +71,6 @@ stats_reload_routes(struct channel *C)
|
|||||||
static struct proto *
|
static struct proto *
|
||||||
stats_init(struct proto_config *CF)
|
stats_init(struct proto_config *CF)
|
||||||
{
|
{
|
||||||
log(L_INFO "stats_init() ");
|
|
||||||
struct proto *P = proto_new(CF);
|
struct proto *P = proto_new(CF);
|
||||||
struct stats_proto *p = (void *) P;
|
struct stats_proto *p = (void *) P;
|
||||||
|
|
||||||
@ -93,15 +82,9 @@ stats_init(struct proto_config *CF)
|
|||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct settle_timer_class stats_settle_class = {
|
|
||||||
.action = stats_settle_timer,
|
|
||||||
.kick = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stats_configure_channels(struct proto *P, struct proto_config *CF)
|
stats_configure_channels(struct proto *P, struct proto_config *CF)
|
||||||
{
|
{
|
||||||
log(L_INFO "stats_configure_channels()");
|
|
||||||
struct channel_config *cc;
|
struct channel_config *cc;
|
||||||
WALK_LIST(cc, CF->channels)
|
WALK_LIST(cc, CF->channels)
|
||||||
{
|
{
|
||||||
@ -113,16 +96,13 @@ stats_configure_channels(struct proto *P, struct proto_config *CF)
|
|||||||
static int
|
static int
|
||||||
stats_start(struct proto *P)
|
stats_start(struct proto *P)
|
||||||
{
|
{
|
||||||
log(L_INFO "stats_start() ");
|
|
||||||
stats_configure_channels(P, P->cf);
|
stats_configure_channels(P, P->cf);
|
||||||
|
|
||||||
|
/* evaluate terms on protocol start */
|
||||||
struct stats_term_config *tc;
|
struct stats_term_config *tc;
|
||||||
WALK_LIST(tc, ((struct stats_config *) P->cf)->terms)
|
WALK_LIST(tc, ((struct stats_config *) P->cf)->terms)
|
||||||
{
|
{
|
||||||
log(L_INFO "term %s", tc->name);
|
stats_eval_term(tc);
|
||||||
f_eval(tc->code, &tc->val);
|
|
||||||
log(L_INFO "content: %s, matches %s", val_dump(&tc->val),
|
|
||||||
tc->type == tc->val.type ? "yes" : "no");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PS_UP;
|
return PS_UP;
|
||||||
@ -150,8 +130,8 @@ stats_reconfigure(struct proto *P, struct proto_config *CF)
|
|||||||
struct stats_channel *sc = (void *) c;
|
struct stats_channel *sc = (void *) c;
|
||||||
struct stats_channel_config *scc = (void *) cc;
|
struct stats_channel_config *scc = (void *) cc;
|
||||||
|
|
||||||
sc->settle_timer->min_settle_time = &(scc->min_settle_time);
|
sc->settle_timer.min_settle_time = scc->min_settle_time;
|
||||||
sc->settle_timer->max_settle_time = &(scc->max_settle_time);
|
sc->settle_timer.max_settle_time = scc->max_settle_time;
|
||||||
|
|
||||||
if (sc->counter != sc->_counter)
|
if (sc->counter != sc->_counter)
|
||||||
{
|
{
|
||||||
@ -187,13 +167,19 @@ stats_show_proto_info(struct proto *P)
|
|||||||
sc->_counter);
|
sc->_counter);
|
||||||
if (!P->disabled)
|
if (!P->disabled)
|
||||||
{
|
{
|
||||||
cli_msg(-1006, " Settle time: %4u s", (*(sc->settle_timer->min_settle_time)) TO_S);
|
cli_msg(-1006, " Settle time: %4u s", sc->settle_timer.min_settle_time TO_S);
|
||||||
cli_msg(-1006, " Settle time: %4u s", (*(sc->settle_timer->max_settle_time)) TO_S);
|
cli_msg(-1006, " Settle time: %4u s", sc->settle_timer.max_settle_time TO_S);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cli_msg(-1006, " Terms:");
|
cli_msg(-1006, " Terms:");
|
||||||
cli_msg(-1006, "terms list: %p", ((struct stats_config *) p->c)->terms);
|
|
||||||
|
struct stats_term_config *tc;
|
||||||
|
WALK_LIST(tc, ((struct stats_config *) P->cf)->terms)
|
||||||
|
{
|
||||||
|
stats_eval_term(tc);
|
||||||
|
cli_msg(-1006, " %s = %s", tc->name, val_dump(tc->val));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -209,10 +195,7 @@ stats_update_debug(struct proto *P)
|
|||||||
static void
|
static void
|
||||||
stats_settle_timer(struct settle_timer *st)
|
stats_settle_timer(struct settle_timer *st)
|
||||||
{
|
{
|
||||||
timer *t = (void *) st;
|
struct stats_channel *c = st->settle_data;
|
||||||
struct stats_channel *c = t->data;
|
|
||||||
log(L_INFO "stats_settle_timer() _counter: %u, counter: %u",
|
|
||||||
c->_counter, c->counter);
|
|
||||||
|
|
||||||
/* update only if real change happen */
|
/* update only if real change happen */
|
||||||
if (c->counter != c->_counter)
|
if (c->counter != c->_counter)
|
||||||
@ -233,12 +216,10 @@ stats_channel_start(struct channel *C)
|
|||||||
|
|
||||||
c->pool = p->p.pool;
|
c->pool = p->p.pool;
|
||||||
|
|
||||||
if (!c->settle_timer)
|
stm_init(&c->settle_timer, c->pool, (void *)c, stats_settle_timer);
|
||||||
c->settle_timer = stm_new_timer(
|
|
||||||
c->pool, (void *) c, &stats_settle_class);
|
|
||||||
|
|
||||||
c->settle_timer->min_settle_time = &(cc->min_settle_time);
|
c->settle_timer.min_settle_time = cc->min_settle_time;
|
||||||
c->settle_timer->max_settle_time = &(cc->max_settle_time);
|
c->settle_timer.max_settle_time = cc->max_settle_time;
|
||||||
|
|
||||||
c->_counter = 0;
|
c->_counter = 0;
|
||||||
c->counter = 0;
|
c->counter = 0;
|
||||||
@ -249,16 +230,9 @@ stats_channel_start(struct channel *C)
|
|||||||
static void
|
static void
|
||||||
stats_channel_shutdown(struct channel *C)
|
stats_channel_shutdown(struct channel *C)
|
||||||
{
|
{
|
||||||
log(L_INFO "stats_channel_shutdown()");
|
|
||||||
struct stats_channel *c = (void *) C;
|
struct stats_channel *c = (void *) C;
|
||||||
|
|
||||||
tm_stop((timer *) c->settle_timer);
|
tm_stop(c->settle_timer.t);
|
||||||
|
|
||||||
c->settle_timer->min_settle_time = NULL;
|
|
||||||
c->settle_timer->max_settle_time = NULL;
|
|
||||||
|
|
||||||
mb_free(c->settle_timer);
|
|
||||||
c->settle_timer = NULL;
|
|
||||||
|
|
||||||
c->_counter = 0;
|
c->_counter = 0;
|
||||||
c->counter = 0;
|
c->counter = 0;
|
||||||
@ -274,31 +248,11 @@ stats_get_counter(struct symbol *sym)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct f_val
|
void stats_eval_term(struct stats_term_config *tc)
|
||||||
stats_eval_term(struct stats_term_config *tc)
|
|
||||||
{
|
{
|
||||||
log(L_INFO "stats_eval_term() evaluating value of %s",
|
f_eval(tc->code, tc->val);
|
||||||
tc->name);
|
|
||||||
enum filter_return fret = f_eval(tc->code, &tc->val);
|
|
||||||
|
|
||||||
if (fret > F_RETURN)
|
|
||||||
tc->val.type = T_VOID;
|
|
||||||
|
|
||||||
if (tc->type != tc->val.type)
|
|
||||||
tc->val.type = T_VOID;
|
|
||||||
|
|
||||||
log(L_INFO " stats_eval_term() returning %s", val_dump(&tc->val));
|
|
||||||
return tc->val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
stats_get_type(struct stats_term_config *tc)
|
|
||||||
{
|
|
||||||
log(L_INFO "stats_get_type()");
|
|
||||||
return tc->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct channel_class channel_stats = {
|
struct channel_class channel_stats = {
|
||||||
.channel_size = sizeof(struct stats_channel),
|
.channel_size = sizeof(struct stats_channel),
|
||||||
.config_size = sizeof(struct stats_channel_config),
|
.config_size = sizeof(struct stats_channel_config),
|
||||||
|
@ -17,7 +17,7 @@ struct stats_channel;
|
|||||||
struct stats_term_config {
|
struct stats_term_config {
|
||||||
node n;
|
node n;
|
||||||
const struct f_line *code;
|
const struct f_line *code;
|
||||||
struct f_val val;
|
struct f_val *val;
|
||||||
int type; /* type declared in configuration */
|
int type; /* type declared in configuration */
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
@ -38,7 +38,7 @@ struct stats_channel {
|
|||||||
pool *pool; /* copy of procotol pool */
|
pool *pool; /* copy of procotol pool */
|
||||||
u32 _counter; /* internal counter */
|
u32 _counter; /* internal counter */
|
||||||
u32 counter; /* publicly accessible counter */
|
u32 counter; /* publicly accessible counter */
|
||||||
struct settle_timer *settle_timer;
|
struct settle_timer settle_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stats_channel_config {
|
struct stats_channel_config {
|
||||||
@ -48,48 +48,6 @@ struct stats_channel_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int stats_get_counter(struct symbol *sym);
|
int stats_get_counter(struct symbol *sym);
|
||||||
struct f_val stats_eval_term(struct stats_term_config *tc);
|
void stats_eval_term(struct stats_term_config *tc);
|
||||||
int stats_get_type(struct stats_term_config *tc);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* get_stats_counter() - extract last notified counter
|
|
||||||
* for specific stats channel if it runs
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
stats_get_counter(struct symbol *sym)
|
|
||||||
{
|
|
||||||
if (sym->ch_config->channel)
|
|
||||||
return (int) ((struct stats_channel *) sym->ch_config->channel)->counter;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* stats_eval_term() - evaluate stats term
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
inline struct f_val
|
|
||||||
stats_eval_term(struct stats_term_config *tc)
|
|
||||||
{
|
|
||||||
enum filter_return fret = f_eval(tc->code, &tc->val);
|
|
||||||
|
|
||||||
if (fret > F_RETURN)
|
|
||||||
tc->val.type = T_VOID;
|
|
||||||
|
|
||||||
if (tc->type != tc->val.type)
|
|
||||||
tc->val.type = T_VOID;
|
|
||||||
|
|
||||||
return tc->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
stats_get_type(struct stats_term_config *tc)
|
|
||||||
{
|
|
||||||
return tc->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // if 0
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user