mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 07:07:04 +02:00
[MEDIUM] measure and report session rate on frontend, backends and servers
With this change, all frontends, backends, and servers maintain a session counter and a timer to compute a session rate over the last second. This value will be very useful because it varies instantly and can be used to check thresholds. This value is also reported in the stats in a new "rate" column.
This commit is contained in:
parent
755905857a
commit
7f062c4193
2
Makefile
2
Makefile
@ -460,7 +460,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
|
||||
src/proto_http.o src/stream_sock.o src/appsession.o src/backend.o \
|
||||
src/stream_interface.o src/dumpstats.o src/proto_tcp.o \
|
||||
src/session.o src/hdr_idx.o src/ev_select.o \
|
||||
src/acl.o src/memory.o \
|
||||
src/acl.o src/memory.o src/freq_ctr.o \
|
||||
src/ebtree.o src/eb32tree.o
|
||||
|
||||
haproxy: $(OBJS) $(OPTIONS_OBJS)
|
||||
|
@ -106,7 +106,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
|
||||
src/stream_interface.o src/dumpstats.o src/proto_tcp.o \
|
||||
src/session.o src/hdr_idx.o src/ev_select.o \
|
||||
src/ev_poll.o src/ev_kqueue.o \
|
||||
src/acl.o src/memory.o \
|
||||
src/acl.o src/memory.o src/freq_ctr.o \
|
||||
src/ebtree.o src/eb32tree.o
|
||||
|
||||
all: haproxy
|
||||
|
@ -103,7 +103,7 @@ OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
|
||||
src/stream_interface.o src/dumpstats.o src/proto_tcp.o \
|
||||
src/session.o src/hdr_idx.o src/ev_select.o \
|
||||
src/ev_poll.o \
|
||||
src/acl.o src/memory.o \
|
||||
src/acl.o src/memory.o src/freq_ctr.o \
|
||||
src/ebtree.o src/eb32tree.o
|
||||
|
||||
all: haproxy
|
||||
|
@ -5778,6 +5778,9 @@ reading. Their sole purpose is to explain how to decipher them.
|
||||
2.7) CSV format
|
||||
---------------
|
||||
|
||||
The statistics may be consulted either from the unix socket or from the HTTP
|
||||
page. Both means provide a CSV format whose fields follow.
|
||||
|
||||
0. pxname: proxy name
|
||||
1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
|
||||
for server)
|
||||
@ -5812,6 +5815,7 @@ reading. Their sole purpose is to explain how to decipher them.
|
||||
30. lbtot: total number of times a server was selected
|
||||
31. tracked: id of proxy/server if tracking is enabled
|
||||
32. type (0=frontend, 1=backend, 2=server)
|
||||
33. rate (number of sessions per second over last elapsed second)
|
||||
|
||||
|
||||
2.8) Unix Socket commands
|
||||
|
@ -280,4 +280,13 @@ extern const char *parse_time_err(const char *text, unsigned *ret, unsigned unit
|
||||
#define TIME_UNIT_DAY 0x0005
|
||||
#define TIME_UNIT_MASK 0x0007
|
||||
|
||||
/* Multiply the two 32-bit operands and shift the 64-bit result right 32 bits.
|
||||
* This is used to compute fixed ratios by setting one of the operands to
|
||||
* (2^32*ratio).
|
||||
*/
|
||||
static inline unsigned int mul32hi(unsigned int a, unsigned int b)
|
||||
{
|
||||
return ((unsigned long long)a * b) >> 32;
|
||||
}
|
||||
|
||||
#endif /* _COMMON_STANDARD_H */
|
||||
|
70
include/proto/freq_ctr.h
Normal file
70
include/proto/freq_ctr.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
include/proto/freq_ctr.h
|
||||
This file contains macros and inline functions for frequency counters.
|
||||
|
||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation, version 2.1
|
||||
exclusively.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _PROTO_FREQ_CTR_H
|
||||
#define _PROTO_FREQ_CTR_H
|
||||
|
||||
#include <common/config.h>
|
||||
#include <types/freq_ctr.h>
|
||||
|
||||
/* Rotate a frequency counter when current period is over. Must not be called
|
||||
* during a valid period. It is important that it correctly initializes a null
|
||||
* area.
|
||||
*/
|
||||
static inline void rotate_freq_ctr(struct freq_ctr *ctr)
|
||||
{
|
||||
ctr->prev_ctr = ctr->curr_ctr;
|
||||
if (likely(now.tv_sec - ctr->curr_sec != 1)) {
|
||||
/* we missed more than one second */
|
||||
ctr->prev_ctr = 0;
|
||||
}
|
||||
ctr->curr_sec = now.tv_sec;
|
||||
ctr->curr_ctr = 0; /* leave it at the end to help gcc optimize it away */
|
||||
}
|
||||
|
||||
/* Update a frequency counter by <inc> incremental units. It is automatically
|
||||
* rotated if the period is over. It is important that it correctly initializes
|
||||
* a null area.
|
||||
*/
|
||||
static inline void update_freq_ctr(struct freq_ctr *ctr, unsigned int inc)
|
||||
{
|
||||
if (likely(ctr->curr_sec == now.tv_sec)) {
|
||||
ctr->curr_ctr += inc;
|
||||
return;
|
||||
}
|
||||
rotate_freq_ctr(ctr);
|
||||
ctr->curr_ctr = inc;
|
||||
/* Note: later we may want to propagate the update to other counters */
|
||||
}
|
||||
|
||||
/* Read a frequency counter taking history into account for missing time in
|
||||
* current period.
|
||||
*/
|
||||
unsigned int read_freq_ctr(struct freq_ctr *ctr);
|
||||
|
||||
#endif /* _PROTO_FREQ_CTR_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -26,6 +26,7 @@
|
||||
#include <common/ticks.h>
|
||||
#include <common/time.h>
|
||||
#include <types/proxy.h>
|
||||
#include <proto/freq_ctr.h>
|
||||
|
||||
int start_proxies(int verbose);
|
||||
void maintain_proxies(int *next);
|
||||
@ -62,6 +63,20 @@ static inline void proxy_reset_timeouts(struct proxy *proxy)
|
||||
proxy->timeout.check = TICK_ETERNITY;
|
||||
}
|
||||
|
||||
/* increase the number of cumulated connections on the designated frontend */
|
||||
static void inline proxy_inc_fe_ctr(struct proxy *fe)
|
||||
{
|
||||
fe->cum_feconn++;
|
||||
update_freq_ctr(&fe->fe_sess_per_sec, 1);
|
||||
}
|
||||
|
||||
/* increase the number of cumulated connections on the designated backend */
|
||||
static void inline proxy_inc_be_ctr(struct proxy *be)
|
||||
{
|
||||
be->cum_beconn++;
|
||||
update_freq_ctr(&be->be_sess_per_sec, 1);
|
||||
}
|
||||
|
||||
#endif /* _PROTO_PROXY_H */
|
||||
|
||||
/*
|
||||
|
@ -2,7 +2,7 @@
|
||||
include/proto/server.h
|
||||
This file defines everything related to servers.
|
||||
|
||||
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -30,10 +30,18 @@
|
||||
#include <types/server.h>
|
||||
|
||||
#include <proto/queue.h>
|
||||
#include <proto/freq_ctr.h>
|
||||
|
||||
int srv_downtime(struct server *s);
|
||||
int srv_getinter(struct server *s);
|
||||
|
||||
/* increase the number of cumulated connections on the designated server */
|
||||
static void inline srv_inc_sess_ctr(struct server *s)
|
||||
{
|
||||
s->cum_sess++;
|
||||
update_freq_ctr(&s->sess_per_sec, 1);
|
||||
}
|
||||
|
||||
#endif /* _PROTO_SERVER_H */
|
||||
|
||||
/*
|
||||
|
40
include/types/freq_ctr.h
Normal file
40
include/types/freq_ctr.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
include/types/freq_ctr.h
|
||||
This file contains structure declarations for frequency counters.
|
||||
|
||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation, version 2.1
|
||||
exclusively.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _TYPES_FREQ_CTR_H
|
||||
#define _TYPES_FREQ_CTR_H
|
||||
|
||||
#include <common/config.h>
|
||||
|
||||
struct freq_ctr {
|
||||
unsigned int curr_sec; /* start date of current period (seconds from now.tv_sec) */
|
||||
unsigned int curr_ctr; /* cumulated value for current period */
|
||||
unsigned int prev_ctr; /* value for last period */
|
||||
};
|
||||
|
||||
#endif /* _TYPES_FREQ_CTR_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -2,7 +2,7 @@
|
||||
include/types/proxy.h
|
||||
This file defines everything related to proxies.
|
||||
|
||||
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -37,6 +37,7 @@
|
||||
|
||||
#include <types/acl.h>
|
||||
#include <types/buffers.h>
|
||||
#include <types/freq_ctr.h>
|
||||
#include <types/httperr.h>
|
||||
#include <types/log.h>
|
||||
#include <types/protocols.h>
|
||||
@ -220,6 +221,8 @@ struct proxy {
|
||||
int totpend; /* total number of pending connections on this instance (for stats) */
|
||||
unsigned int feconn, feconn_max; /* # of active frontend sessions */
|
||||
unsigned int beconn, beconn_max; /* # of active backend sessions */
|
||||
struct freq_ctr fe_sess_per_sec; /* sessions per second on the frontend */
|
||||
struct freq_ctr be_sess_per_sec; /* sessions per second on the backend */
|
||||
unsigned int cum_feconn, cum_beconn; /* cumulated number of processed sessions */
|
||||
unsigned int cum_lbconn; /* cumulated number of sessions processed by load balancing */
|
||||
unsigned int maxconn; /* max # of active sessions on the frontend */
|
||||
|
@ -2,7 +2,7 @@
|
||||
include/types/server.h
|
||||
This file defines everything related to servers.
|
||||
|
||||
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -30,6 +30,7 @@
|
||||
#include <common/mini-clist.h>
|
||||
|
||||
#include <types/buffers.h>
|
||||
#include <types/freq_ctr.h>
|
||||
#include <types/proxy.h>
|
||||
#include <types/queue.h>
|
||||
#include <types/task.h>
|
||||
@ -122,6 +123,7 @@ struct server {
|
||||
unsigned failed_conns, failed_resp; /* failed connect() and responses */
|
||||
unsigned retries, redispatches; /* retried and redispatched connections */
|
||||
unsigned failed_secu; /* blocked responses because of security concerns */
|
||||
struct freq_ctr sess_per_sec; /* sessions per second on this server */
|
||||
unsigned cum_sess; /* cumulated number of sessions really sent to this server */
|
||||
unsigned cum_lbconn; /* cumulated number of sessions directed by load balancing */
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <proto/proto_http.h>
|
||||
#include <proto/proto_tcp.h>
|
||||
#include <proto/queue.h>
|
||||
#include <proto/server.h>
|
||||
#include <proto/session.h>
|
||||
#include <proto/stream_sock.h>
|
||||
#include <proto/task.h>
|
||||
@ -1912,7 +1913,7 @@ int srv_redispatch_connect(struct session *t)
|
||||
}
|
||||
|
||||
if (t->srv)
|
||||
t->srv->cum_sess++;
|
||||
srv_inc_sess_ctr(t->srv);
|
||||
if (t->srv)
|
||||
t->srv->failed_conns++;
|
||||
t->be->failed_conns++;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <proto/log.h>
|
||||
#include <proto/hdr_idx.h>
|
||||
#include <proto/proto_http.h>
|
||||
#include <proto/proxy.h>
|
||||
#include <proto/session.h>
|
||||
#include <proto/stream_interface.h>
|
||||
#include <proto/stream_sock.h>
|
||||
@ -236,7 +237,7 @@ int event_accept(int fd) {
|
||||
s->data_source = DATA_SRC_NONE;
|
||||
|
||||
s->uniq_id = totalconn;
|
||||
p->cum_feconn++; /* cum_beconn will be increased once assigned */
|
||||
proxy_inc_fe_ctr(p); /* note: cum_beconn will be increased once assigned */
|
||||
|
||||
txn = &s->txn;
|
||||
txn->flags = 0;
|
||||
@ -444,7 +445,7 @@ int event_accept(int fd) {
|
||||
p->feconn_max = p->feconn;
|
||||
|
||||
if (s->flags & SN_BE_ASSIGNED) {
|
||||
s->be->cum_beconn++;
|
||||
proxy_inc_be_ctr(s->be);
|
||||
s->be->beconn++;
|
||||
if (s->be->beconn > s->be->beconn_max)
|
||||
s->be->beconn_max = s->be->beconn;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <proto/buffers.h>
|
||||
#include <proto/dumpstats.h>
|
||||
#include <proto/fd.h>
|
||||
#include <proto/freq_ctr.h>
|
||||
#include <proto/pipe.h>
|
||||
#include <proto/proto_uxst.h>
|
||||
#include <proto/session.h>
|
||||
@ -173,7 +174,7 @@ int print_csv_header(struct chunk *msg, int size)
|
||||
"wretr,wredis,"
|
||||
"status,weight,act,bck,"
|
||||
"chkfail,chkdown,lastchg,downtime,qlimit,"
|
||||
"pid,iid,sid,throttle,lbtot,tracked,type,"
|
||||
"pid,iid,sid,throttle,lbtot,tracked,type,rate,"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@ -650,21 +651,21 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
|
||||
/* print a new table */
|
||||
chunk_printf(&msg, sizeof(trash),
|
||||
"<table cols=\"26\" class=\"tbl\" width=\"100%%\">\n"
|
||||
"<table cols=\"27\" class=\"tbl\" width=\"100%%\">\n"
|
||||
"<tr align=\"center\" class=\"titre\">"
|
||||
"<th colspan=2 class=\"pxname\">%s</th>"
|
||||
"<th colspan=24 class=\"empty\"></th>"
|
||||
"<th colspan=25 class=\"empty\"></th>"
|
||||
"</tr>\n"
|
||||
"<tr align=\"center\" class=\"titre\">"
|
||||
"<th rowspan=2></th>"
|
||||
"<th colspan=3>Queue</th><th colspan=5>Sessions</th>"
|
||||
"<th colspan=3>Queue</th><th colspan=6>Sessions</th>"
|
||||
"<th colspan=2>Bytes</th><th colspan=2>Denied</th>"
|
||||
"<th colspan=3>Errors</th><th colspan=2>Warnings</th>"
|
||||
"<th colspan=8>Server</th>"
|
||||
"</tr>\n"
|
||||
"<tr align=\"center\" class=\"titre\">"
|
||||
"<th>Cur</th><th>Max</th><th>Limit</th><th>Cur</th><th>Max</th>"
|
||||
"<th>Limit</th><th>Total</th><th>LbTot</th><th>In</th><th>Out</th>"
|
||||
"<th>Limit</th><th>Rate</th><th>Total</th><th>LbTot</th><th>In</th><th>Out</th>"
|
||||
"<th>Req</th><th>Resp</th><th>Req</th><th>Conn</th>"
|
||||
"<th>Resp</th><th>Retr</th><th>Redis</th>"
|
||||
"<th>Status</th><th>Wght</th><th>Act</th>"
|
||||
@ -688,10 +689,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
chunk_printf(&msg, sizeof(trash),
|
||||
/* name, queue */
|
||||
"<tr align=center class=\"frontend\"><td>Frontend</td><td colspan=3></td>"
|
||||
/* sessions : current, max, limit, total, lbtot */
|
||||
/* sessions : current, max, limit, rate, total, lbtot */
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right></td>"
|
||||
"<td align=right>%d</td><td align=right></td>"
|
||||
/* bytes : in, out */
|
||||
"<td align=right>%lld</td><td align=right>%lld</td>"
|
||||
/* denied: req, resp */
|
||||
@ -705,7 +706,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
/* rest of server: nothing */
|
||||
"<td align=center colspan=7></td></tr>"
|
||||
"",
|
||||
px->feconn, px->feconn_max, px->maxconn, px->cum_feconn,
|
||||
px->feconn, px->feconn_max, px->maxconn,
|
||||
read_freq_ctr(&px->fe_sess_per_sec), px->cum_feconn,
|
||||
px->bytes_in, px->bytes_out,
|
||||
px->denied_req, px->denied_resp,
|
||||
px->failed_req,
|
||||
@ -731,6 +733,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
",,,,,,,,"
|
||||
/* pid, iid, sid, throttle, lbtot, tracked, type */
|
||||
"%d,%d,0,,,,%d,"
|
||||
/* rate */
|
||||
"%u,"
|
||||
"\n",
|
||||
px->id,
|
||||
px->feconn, px->feconn_max, px->maxconn, px->cum_feconn,
|
||||
@ -739,7 +743,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
px->failed_req,
|
||||
px->state == PR_STRUN ? "OPEN" :
|
||||
px->state == PR_STIDLE ? "FULL" : "STOP",
|
||||
relative_pid, px->uuid, STATS_TYPE_FE);
|
||||
relative_pid, px->uuid, STATS_TYPE_FE,
|
||||
read_freq_ctr(&px->fe_sess_per_sec));
|
||||
}
|
||||
|
||||
if (buffer_write_chunk(rep, &msg) >= 0)
|
||||
@ -805,10 +810,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
"<tr align=\"center\" class=\"%s%d\"><td>%s</td>"
|
||||
/* queue : current, max, limit */
|
||||
"<td align=right>%d</td><td align=right>%d</td><td align=right>%s</td>"
|
||||
/* sessions : current, max, limit, total, lbtot */
|
||||
/* sessions : current, max, limit, rate, total, lbtot */
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right>%s</td><td align=right>%d</td>"
|
||||
"<td align=right>%d</td>"
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
/* bytes : in, out */
|
||||
"<td align=right>%lld</td><td align=right>%lld</td>"
|
||||
/* denied: req, resp */
|
||||
@ -822,6 +827,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
sv_state, sv->id,
|
||||
sv->nbpend, sv->nbpend_max, LIM2A0(sv->maxqueue, "-"),
|
||||
sv->cur_sess, sv->cur_sess_max, LIM2A1(sv->maxconn, "-"),
|
||||
read_freq_ctr(&sv->sess_per_sec),
|
||||
sv->cum_sess, sv->cum_lbconn,
|
||||
sv->bytes_in, sv->bytes_out,
|
||||
sv->failed_secu,
|
||||
@ -956,8 +962,14 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
else
|
||||
chunk_printf(&msg, sizeof(trash), ",");
|
||||
|
||||
/* type, then EOL */
|
||||
chunk_printf(&msg, sizeof(trash), "%d,\n", STATS_TYPE_SV);
|
||||
/* type */
|
||||
chunk_printf(&msg, sizeof(trash), "%d,", STATS_TYPE_SV);
|
||||
|
||||
/* rate */
|
||||
chunk_printf(&msg, sizeof(trash), "%u,", read_freq_ctr(&sv->sess_per_sec));
|
||||
|
||||
/* finish with EOL */
|
||||
chunk_printf(&msg, sizeof(trash), "\n");
|
||||
}
|
||||
if (buffer_write_chunk(rep, &msg) >= 0)
|
||||
return 0;
|
||||
@ -976,10 +988,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
"<tr align=center class=\"backend\"><td>Backend</td>"
|
||||
/* queue : current, max */
|
||||
"<td align=right>%d</td><td align=right>%d</td><td></td>"
|
||||
/* sessions : current, max, limit, total, lbtot */
|
||||
/* sessions : current, max, limit, rate, total, lbtot */
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right>%d</td><td align=right>%d</td>"
|
||||
"<td align=right>%d</td>"
|
||||
/* bytes : in, out */
|
||||
"<td align=right>%lld</td><td align=right>%lld</td>"
|
||||
/* denied: req, resp */
|
||||
@ -995,7 +1007,9 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
"<td align=center nowrap>%s %s</td><td align=center>%d</td>"
|
||||
"<td align=center>%d</td><td align=center>%d</td>",
|
||||
px->nbpend /* or px->totpend ? */, px->nbpend_max,
|
||||
px->beconn, px->beconn_max, px->fullconn, px->cum_beconn, px->cum_lbconn,
|
||||
px->beconn, px->beconn_max, px->fullconn,
|
||||
read_freq_ctr(&px->be_sess_per_sec),
|
||||
px->cum_beconn, px->cum_lbconn,
|
||||
px->bytes_in, px->bytes_out,
|
||||
px->denied_req, px->denied_resp,
|
||||
px->failed_conns, px->failed_resp,
|
||||
@ -1040,6 +1054,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
",%d,%d,%d,,"
|
||||
/* pid, iid, sid, throttle, lbtot, tracked, type */
|
||||
"%d,%d,0,,%d,,%d,"
|
||||
/* rate */
|
||||
"%u,"
|
||||
"\n",
|
||||
px->id,
|
||||
px->nbpend /* or px->totpend ? */, px->nbpend_max,
|
||||
@ -1054,7 +1070,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
|
||||
px->down_trans, now.tv_sec - px->last_change,
|
||||
px->srv?be_downtime(px):0,
|
||||
relative_pid, px->uuid,
|
||||
px->cum_lbconn, STATS_TYPE_BE);
|
||||
px->cum_lbconn, STATS_TYPE_BE,
|
||||
read_freq_ctr(&px->be_sess_per_sec));
|
||||
}
|
||||
if (buffer_write_chunk(rep, &msg) >= 0)
|
||||
return 0;
|
||||
|
45
src/freq_ctr.c
Normal file
45
src/freq_ctr.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Event rate calculation functions.
|
||||
*
|
||||
* Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common/config.h>
|
||||
#include <common/standard.h>
|
||||
#include <common/time.h>
|
||||
#include <proto/freq_ctr.h>
|
||||
|
||||
/* Read a frequency counter taking history into account for missing time in
|
||||
* current period. Current second is sub-divided in 1000 chunks of one ms,
|
||||
* and the missing ones are read proportionally from previous value. The
|
||||
* return value has the same precision as one input data sample, so low rates
|
||||
* will be inaccurate still appropriate for max checking. One trick we use for
|
||||
* low values is to specially handle the case where the rate is between 0 and 1
|
||||
* in order to avoid flapping while waiting for the next event.
|
||||
*/
|
||||
unsigned int read_freq_ctr(struct freq_ctr *ctr)
|
||||
{
|
||||
unsigned int cur;
|
||||
if (unlikely(ctr->curr_sec != now.tv_sec))
|
||||
rotate_freq_ctr(ctr);
|
||||
|
||||
cur = ctr->curr_ctr;
|
||||
if (ctr->prev_ctr <= 1 && !ctr->curr_ctr)
|
||||
return ctr->prev_ctr; /* very low rate, avoid flapping */
|
||||
|
||||
return cur + mul32hi(ctr->prev_ctr, ~curr_sec_ms_scaled);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -47,7 +47,9 @@
|
||||
#include <proto/hdr_idx.h>
|
||||
#include <proto/proto_tcp.h>
|
||||
#include <proto/proto_http.h>
|
||||
#include <proto/proxy.h>
|
||||
#include <proto/queue.h>
|
||||
#include <proto/server.h>
|
||||
#include <proto/session.h>
|
||||
#include <proto/stream_interface.h>
|
||||
#include <proto/stream_sock.h>
|
||||
@ -692,7 +694,7 @@ void perform_http_redirect(struct session *s, struct stream_interface *si)
|
||||
|
||||
/* FIXME: we should increase a counter of redirects per server and per backend. */
|
||||
if (s->srv)
|
||||
s->srv->cum_sess++;
|
||||
srv_inc_sess_ctr(s->srv);
|
||||
}
|
||||
|
||||
/* Return the error message corresponding to si->err_type. It is assumed
|
||||
@ -1943,7 +1945,7 @@ int http_process_request(struct session *s, struct buffer *req)
|
||||
s->be->beconn++;
|
||||
if (s->be->beconn > s->be->beconn_max)
|
||||
s->be->beconn_max = s->be->beconn;
|
||||
s->be->cum_beconn++;
|
||||
proxy_inc_be_ctr(s->be);
|
||||
s->flags |= SN_BE_ASSIGNED;
|
||||
}
|
||||
|
||||
@ -2046,7 +2048,7 @@ int http_process_request(struct session *s, struct buffer *req)
|
||||
s->be->beconn++;
|
||||
if (s->be->beconn > s->be->beconn_max)
|
||||
s->be->beconn_max = s->be->beconn;
|
||||
s->be->cum_beconn++;
|
||||
proxy_inc_be_ctr(s->be);
|
||||
|
||||
/* assign new parameters to the session from the new backend */
|
||||
s->rep->rto = s->req->wto = s->be->timeout.server;
|
||||
@ -2067,7 +2069,7 @@ int http_process_request(struct session *s, struct buffer *req)
|
||||
s->be->beconn++;
|
||||
if (s->be->beconn > s->be->beconn_max)
|
||||
s->be->beconn_max = s->be->beconn;
|
||||
s->be->cum_beconn++;
|
||||
proxy_inc_be_ctr(s->be);
|
||||
|
||||
/* assign new parameters to the session from the new backend */
|
||||
s->rep->rto = s->req->wto = s->be->timeout.server;
|
||||
@ -2085,7 +2087,7 @@ int http_process_request(struct session *s, struct buffer *req)
|
||||
s->be->beconn++;
|
||||
if (s->be->beconn > s->be->beconn_max)
|
||||
s->be->beconn_max = s->be->beconn;
|
||||
s->be->cum_beconn++;
|
||||
proxy_inc_be_ctr(s->be);
|
||||
s->flags |= SN_BE_ASSIGNED;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <proto/proto_http.h>
|
||||
#include <proto/proto_tcp.h>
|
||||
#include <proto/queue.h>
|
||||
#include <proto/server.h>
|
||||
#include <proto/stream_interface.h>
|
||||
#include <proto/stream_sock.h>
|
||||
#include <proto/task.h>
|
||||
@ -367,7 +368,7 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si)
|
||||
if (conn_err == SN_ERR_NONE) {
|
||||
/* state = SI_ST_CON now */
|
||||
if (s->srv)
|
||||
s->srv->cum_sess++;
|
||||
srv_inc_sess_ctr(s->srv);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -381,7 +382,7 @@ void sess_update_stream_int(struct session *s, struct stream_interface *si)
|
||||
}
|
||||
|
||||
if (s->srv)
|
||||
s->srv->cum_sess++;
|
||||
srv_inc_sess_ctr(s->srv);
|
||||
if (s->srv)
|
||||
s->srv->failed_conns++;
|
||||
s->be->failed_conns++;
|
||||
|
Loading…
Reference in New Issue
Block a user