MEDIUM: session: maintain per-backend and per-server time statistics
Using the last rate counters, we now compute the queue, connect, response and total times per server and per backend with a 95% accuracy over the last 1024 samples. The operation is cheap so we don't need to condition it.
This commit is contained in:
parent
2438f2b984
commit
4bfc580dd3
|
@ -219,4 +219,15 @@
|
|||
#define SSL_DEFAULT_DH_PARAM 0
|
||||
#endif
|
||||
|
||||
/* Number of samples used to compute the times reported in stats. A power of
|
||||
* two is highly recommended, and this value multiplied by the largest response
|
||||
* time must not overflow and unsigned int. See freq_ctr.h for more information.
|
||||
* We consider that values are accurate to 95% with two batches of samples below,
|
||||
* so in order to advertise accurate times across 1k samples, we effectively
|
||||
* measure over 512.
|
||||
*/
|
||||
#ifndef TIME_STATS_SAMPLES
|
||||
#define TIME_STATS_SAMPLES 512
|
||||
#endif
|
||||
|
||||
#endif /* _COMMON_DEFAULTS_H */
|
||||
|
|
|
@ -50,6 +50,9 @@ int parse_track_counters(char **args, int *arg,
|
|||
struct track_ctr_prm *prm,
|
||||
struct proxy *defpx, char **err);
|
||||
|
||||
/* Update the session's backend and server time stats */
|
||||
void session_update_time_stats(struct session *s);
|
||||
|
||||
/* returns the session from a void *owner */
|
||||
static inline struct session *session_from_task(struct task *t)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* This file contains structure declarations for statistics counters.
|
||||
*
|
||||
* Copyright 2008-2009 Krzysztof Piotr Oledzki <ole@ans.pl>
|
||||
* Copyright 2011 Willy Tarreau <w@1wt.eu>
|
||||
* Copyright 2011-2014 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
|
||||
|
@ -55,6 +55,8 @@ struct pxcounters {
|
|||
long long redispatches; /* retried and redispatched connections (BE only) */
|
||||
long long intercepted_req; /* number of monitoring or stats requests intercepted by the frontend */
|
||||
|
||||
unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long cum_req; /* cumulated number of processed HTTP requests */
|
||||
|
@ -96,6 +98,8 @@ struct srvcounters {
|
|||
long long retries, redispatches; /* retried and redispatched connections */
|
||||
long long failed_secu; /* blocked responses because of security concerns */
|
||||
|
||||
unsigned int q_time, c_time, d_time, t_time; /* sums of conn_time, queue_time, data_time, total_time */
|
||||
|
||||
union {
|
||||
struct {
|
||||
long long rsp[6]; /* http response codes */
|
||||
|
|
|
@ -4714,6 +4714,8 @@ void http_end_txn_clean_session(struct session *s)
|
|||
s->do_log(s);
|
||||
}
|
||||
|
||||
session_update_time_stats(s);
|
||||
|
||||
s->logs.accept_date = date; /* user-visible date for logging */
|
||||
s->logs.tv_accept = now; /* corrected date for internal use */
|
||||
tv_zero(&s->logs.tv_request);
|
||||
|
|
|
@ -2600,6 +2600,9 @@ struct task *process_session(struct task *t)
|
|||
s->do_log(s);
|
||||
}
|
||||
|
||||
/* update time stats for this session */
|
||||
session_update_time_stats(s);
|
||||
|
||||
/* the task MUST not be in the run queue anymore */
|
||||
session_free(s);
|
||||
task_delete(t);
|
||||
|
@ -2607,6 +2610,48 @@ struct task *process_session(struct task *t)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Update the session's backend and server time stats */
|
||||
void session_update_time_stats(struct session *s)
|
||||
{
|
||||
int t_request;
|
||||
int t_queue;
|
||||
int t_connect;
|
||||
int t_data;
|
||||
int t_close;
|
||||
struct server *srv;
|
||||
|
||||
t_request = 0;
|
||||
t_queue = s->logs.t_queue;
|
||||
t_connect = s->logs.t_connect;
|
||||
t_close = s->logs.t_close;
|
||||
t_data = s->logs.t_data;
|
||||
|
||||
if (s->be->mode != PR_MODE_HTTP)
|
||||
t_data = t_connect;
|
||||
|
||||
if (t_connect < 0 || t_data < 0)
|
||||
return;
|
||||
|
||||
if (tv_isge(&s->logs.tv_request, &s->logs.tv_accept))
|
||||
t_request = tv_ms_elapsed(&s->logs.tv_accept, &s->logs.tv_request);
|
||||
|
||||
t_data -= t_connect;
|
||||
t_connect -= t_queue;
|
||||
t_queue -= t_request;
|
||||
|
||||
srv = objt_server(s->target);
|
||||
if (srv) {
|
||||
swrate_add(&srv->counters.q_time, TIME_STATS_SAMPLES, t_queue);
|
||||
swrate_add(&srv->counters.c_time, TIME_STATS_SAMPLES, t_connect);
|
||||
swrate_add(&srv->counters.d_time, TIME_STATS_SAMPLES, t_data);
|
||||
swrate_add(&srv->counters.t_time, TIME_STATS_SAMPLES, t_close);
|
||||
}
|
||||
swrate_add(&s->be->be_counters.q_time, TIME_STATS_SAMPLES, t_queue);
|
||||
swrate_add(&s->be->be_counters.c_time, TIME_STATS_SAMPLES, t_connect);
|
||||
swrate_add(&s->be->be_counters.d_time, TIME_STATS_SAMPLES, t_data);
|
||||
swrate_add(&s->be->be_counters.t_time, TIME_STATS_SAMPLES, t_close);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function adjusts sess->srv_conn and maintains the previous and new
|
||||
* server's served session counts. Setting newsrv to NULL is enough to release
|
||||
|
|
Loading…
Reference in New Issue