]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: session: maintain per-backend and per-server time statistics
authorWilly Tarreau <w@1wt.eu>
Tue, 17 Jun 2014 10:19:18 +0000 (12:19 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 17 Jun 2014 15:15:56 +0000 (17:15 +0200)
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.

include/common/defaults.h
include/proto/session.h
include/types/counters.h
src/proto_http.c
src/session.c

index bdd75cf90b77f5560c18134bdda78ac9065602b0..8d5d62a6fe6ceed6ac5cdceec7285ebc102e5b00 100644 (file)
 #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 */
index fc83989f2dcb427b7f23333a34726fb5cbc68432..c835bf0778fea17c0e9c772b53887909093cefa6 100644 (file)
@@ -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)
 {
index ecdc7cb9587f1df8d35785f3044670e904131957..172f8a6413b7dfb203902eaac2058c1373d502dc 100644 (file)
@@ -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 */
index 082f1616deba3d5cef3208d2c804cd9a9e56c93f..48dbc43cc79b9e44002f35784bc6c9fbc6866a83 100644 (file)
@@ -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);
index 4412125ba4977019a987ca86289f5015a1a1c205..f828d9c2e03d6861fda0219c377dc1d762fec9f1 100644 (file)
@@ -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