MINOR: stats: Enhancement to stats page to provide information of last session time.

Summary:
Track and report last session time on the stats page for each server
in every backend, as well as the backend.

This attempts to address the requirement in the ROADMAP

  - add a last activity date for each server (req/resp) that will be
    displayed in the stats. It will be useful with soft stop.

The stats page reports this as time elapsed since last session. This
change does not adequately address the requirement for long running
session (websocket, RDP... etc).
diff --git a/src/backend.c b/src/backend.c
index 8fcce7d..e561919 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -52,6 +52,14 @@
 #include <proto/stream_interface.h>
 #include <proto/task.h>
 
+int be_lastsession(const struct proxy *be)
+{
+	if (be->be_counters.last_sess)
+		return now.tv_sec - be->be_counters.last_sess;
+
+	return -1;
+}
+
 /* helper function to invoke the correct hash method */
 static unsigned long gen_hash(const struct proxy* px, const char* key, unsigned long len)
 {
@@ -668,6 +676,7 @@
 			goto out;
 		}
 		else if (srv != prev_srv) {
+			be_set_sess_last(s->be);
 			s->be->be_counters.cum_lbconn++;
 			srv->counters.cum_lbconn++;
 		}
@@ -1165,6 +1174,8 @@
 		if (srv)
 			srv_inc_sess_ctr(srv);
 		if (srv)
+			srv_set_sess_last(srv);
+		if (srv)
 			srv->counters.failed_conns++;
 		t->be->be_counters.failed_conns++;
 
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 2599785..d147d0f 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -433,7 +433,7 @@
 	chunk_appendf(&trash,
 	              "# pxname,svname,"
 	              "qcur,qmax,"
-	              "scur,smax,slim,stot,"
+	              "scur,smax,slim,stot,lastsess,"
 	              "bin,bout,"
 	              "dreq,dresp,"
 	              "ereq,econ,eresp,"
@@ -2467,8 +2467,8 @@
 
 		chunk_appendf(&trash,
 		              "</table></div></u></td>"
-		              /* sessions: lbtot */
-		              "<td></td>"
+		              /* sessions: lbtot, lastsess */
+		              "<td></td><td></td>"
 		              /* bytes : in */
 		              "<td>%s</td>"
 		              "",
@@ -2505,8 +2505,8 @@
 		chunk_appendf(&trash,
 		              /* pxid, name, queue cur, queue max, */
 		              "%s,FRONTEND,,,"
-		              /* sessions : current, max, limit, total */
-		              "%d,%d,%d,%lld,"
+		              /* sessions : current, max, limit, total, lastsess */
+		              "%d,%d,%d,%lld,,"
 		              /* bytes : in, out */
 		              "%lld,%lld,"
 		              /* denied: req, resp */
@@ -2625,9 +2625,9 @@
 		              "%s</td><td colspan=3></td>"
 		              /* sessions rate: current, max, limit */
 		              "<td colspan=3>&nbsp;</td>"
-		              /* sessions: current, max, limit, total, lbtot */
+		              /* sessions: current, max, limit, total, lbtot, lastsess */
 		              "<td>%s</td><td>%s</td><td>%s</td>"
-		              "<td>%s</td><td>&nbsp;</td>"
+		              "<td>%s</td><td>&nbsp;</td><td>&nbsp;</td>"
 		              /* bytes: in, out */
 		              "<td>%s</td><td>%s</td>"
 		              "",
@@ -2655,8 +2655,8 @@
 		chunk_appendf(&trash,
 		              /* pxid, name, queue cur, queue max, */
 		              "%s,%s,,,"
-		              /* sessions: current, max, limit, total */
-		              "%d,%d,%d,%lld,"
+		              /* sessions: current, max, limit, total, lastsess */
+		              "%d,%d,%d,%lld,,"
 		              /* bytes: in, out */
 		              "%lld,%lld,"
 		              /* denied: req, resp */
@@ -2829,9 +2829,10 @@
 
 		chunk_appendf(&trash,
 		              "</table></div></u></td>"
-		              /* sessions: lbtot */
-		              "<td>%s</td>",
-		              U2H(sv->counters.cum_lbconn));
+		              /* sessions: lbtot, last */
+		              "<td>%s</td><td>%s</td>",
+		              U2H(sv->counters.cum_lbconn),
+		              human_time(srv_lastsession(sv), 1));
 
 		chunk_appendf(&trash,
 		              /* bytes : in, out */
@@ -2957,8 +2958,8 @@
 		              "%s,%s,"
 		              /* queue : current, max */
 		              "%d,%d,"
-		              /* sessions : current, max, limit, total */
-		              "%d,%d,%s,%lld,"
+		              /* sessions : current, max, limit, total, lastsess */
+		              "%d,%d,%s,%lld,%d,"
 		              /* bytes : in, out */
 		              "%lld,%lld,"
 		              /* denied: req, resp */
@@ -2971,6 +2972,7 @@
 		              px->id, sv->id,
 		              sv->nbpend, sv->counters.nbpend_max,
 		              sv->cur_sess, sv->counters.cur_sess_max, LIM2A(sv->maxconn, ""), sv->counters.cum_sess,
+		              srv_lastsession(sv),
 		              sv->counters.bytes_in, sv->counters.bytes_out,
 		              sv->counters.failed_secu,
 		              sv->counters.failed_conns, sv->counters.failed_resp,
@@ -3177,12 +3179,13 @@
 
 		chunk_appendf(&trash,
 		              "</table></div></u></td>"
-		              /* sessions: lbtot */
-		              "<td>%s</td>"
+		              /* sessions: lbtot, last */
+		              "<td>%s</td><td>%s</td>"
 		              /* bytes: in */
 		              "<td>%s</td>"
 		              "",
 		              U2H(px->be_counters.cum_lbconn),
+		              human_time(be_lastsession(px), 1),
 		              U2H(px->be_counters.bytes_in));
 
 		chunk_appendf(&trash,
@@ -3238,8 +3241,8 @@
 		              "%s,BACKEND,"
 		              /* queue : current, max */
 		              "%d,%d,"
-		              /* sessions : current, max, limit, total */
-		              "%d,%d,%d,%lld,"
+		              /* sessions : current, max, limit, total, lastsess */
+		              "%d,%d,%d,%lld,%s,"
 		              /* bytes : in, out */
 		              "%lld,%lld,"
 		              /* denied: req, resp */
@@ -3265,6 +3268,7 @@
 		              px->id,
 		              px->nbpend /* or px->totpend ? */, px->be_counters.nbpend_max,
 		              px->beconn, px->be_counters.conn_max, px->fullconn, px->be_counters.cum_conn,
+		              human_time(be_lastsession(px), 1),
 		              px->be_counters.bytes_in, px->be_counters.bytes_out,
 		              px->be_counters.denied_req, px->be_counters.denied_resp,
 		              px->be_counters.failed_conns, px->be_counters.failed_resp,
@@ -3378,7 +3382,7 @@
 	chunk_appendf(&trash,
 	              "<th rowspan=2></th>"
 	              "<th colspan=3>Queue</th>"
-	              "<th colspan=3>Session rate</th><th colspan=5>Sessions</th>"
+	              "<th colspan=3>Session rate</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=9>Server</th>"
@@ -3386,7 +3390,7 @@
 	              "<tr class=\"titre\">"
 	              "<th>Cur</th><th>Max</th><th>Limit</th>"
 	              "<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>Total</th><th>LbTot</th><th>Last</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>LastChk</th><th>Wght</th><th>Act</th>"
diff --git a/src/proto_http.c b/src/proto_http.c
index 6c4ba7a..371b523 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -943,6 +943,7 @@
 
 	/* FIXME: we should increase a counter of redirects per server and per backend. */
 	srv_inc_sess_ctr(srv);
+	srv_set_sess_last(srv);
 }
 
 /* Return the error message corresponding to si->err_type. It is assumed
diff --git a/src/server.c b/src/server.c
index d91c726..ccae58b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -30,6 +30,14 @@
 	return now.tv_sec - s->last_change + s->down_time;
 }
 
+int srv_lastsession(const struct server *s)
+{
+	if (s->counters.last_sess)
+		return now.tv_sec - s->counters.last_sess;
+
+	return -1;
+}
+
 int srv_getinter(const struct check *check)
 {
 	const struct server *s = check->server;
diff --git a/src/session.c b/src/session.c
index 0a03677..b3da759 100644
--- a/src/session.c
+++ b/src/session.c
@@ -974,6 +974,8 @@
 			/* state = SI_ST_CON or SI_ST_EST now */
 			if (srv)
 				srv_inc_sess_ctr(srv);
+			if (srv)
+				srv_set_sess_last(srv);
 			return;
 		}
 
@@ -988,6 +990,8 @@
 			if (srv)
 				srv_inc_sess_ctr(srv);
 			if (srv)
+				srv_set_sess_last(srv);
+			if (srv)
 				srv->counters.failed_conns++;
 			s->be->be_counters.failed_conns++;