From: Krzysztof Piotr Oledzki Date: Sat, 23 Feb 2008 00:19:10 +0000 (+0100) Subject: [MINOR] Implement persistent id for proxies and servers X-Git-Tag: v1.3.15~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f58a9622475b4afb97b0b193b4fe32bca1e16255;p=thirdparty%2Fhaproxy.git [MINOR] Implement persistent id for proxies and servers This patch adds a possibility to set a persistent id for a proxy/server. Now, even if some proxies/servers are inserted/deleted/moved, iids and sids can be still used reliable. Some people add servers with tricky names (BACKEND or FRONTEND for example). So I also added one more field ('type') to distinguish between a backend (0), frontend (1) and server (2) without complicated logic: if name==BACKEND and sid==0 then type is BACKEND else type is SERVER, etc for a FRONTEND. It also makes possible to have one frontend with more than one IP (a patch coming soon) with independed stats - for example to differs between remote and local traffic. Finally, I added documentation about the CSV format. This patch depends on '[MEDIUM] Implement "track [/]"' --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 504f8a9467..a2c97e3175 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1308,6 +1308,11 @@ http-check disable-on-404 See also : "option httpchk" +id + Set a persistent value for proxy ID. Must be unique and larger than 1000, as + smaller values are reserved for auto-assigned ids. + + log global log
[] Enable per-instance logging of events and traffic. @@ -3778,6 +3783,10 @@ fall consecutive unsuccessful health checks. This value defaults to 3 if unspecified. See also the "check", "inter" and "rise" parameters. +id + Set a persistent value for server ID. Must be unique and larger than 1000, as + smaller values are reserved for auto-assigned ids. + inter fastinter downinter @@ -4012,6 +4021,42 @@ Notes related to these keywords : [to do] +2.7) CSV format + + 0. pxname: proxy name + 1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name + for server) + 2. qcur: current queued requests + 3. qmax: max queued requests + 4. scur: current sessions + 5. smax: max sessions + 6. slim: sessions limit + 7. stot: total sessions + 8. bin: bytes in + 9. bout: bytes out + 10. dreq: denied requests + 11. dresp: denied responces + 12. ereq: request errors + 13. econ: connection errors + 14. eresp: responce errors + 15. wretr: retries (warning) + 16. wredis: redispatches (warning) + 17. status: status (UP/DOWN/...) + 18. weight: server weight (server), total weight (backend) + 19. act: server is active (server), number of active servers (backend) + 20. bck: server is backup (server), number of backup servers (backend) + 21. chkfail: number of failed checks + 22. chkdown: number of UP->DOWN transitions + 23. lastchg: last status change (in seconds) + 24. downtime: total downtime (in seconds) + 25. qlimit: queue limit + 26. pid: process id (0 for first instance, 1 for second, ...) + 27. iid: unique proxy id + 28. sid: service id (unique inside a proxy) + 29. throttle: warm up status + 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) /* * Local variables: diff --git a/src/cfgparse.c b/src/cfgparse.c index 25d954a4e1..0b1a0bafc5 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -800,6 +800,36 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) return -1; } } + else if (!strcmp(args[0], "id")) { + struct proxy *target; + + if (curproxy == &defproxy) { + Alert("parsing [%s:%d]: '%s' not allowed in 'defaults' section.\n", + file, linenum, args[0]); + return -1; + } + + if (!*args[1]) { + Alert("parsing [%s:%d]: '%s' expects an integer argument.\n", + file, linenum, args[0]); + return -1; + } + + curproxy->uuid = atol(args[1]); + + if (curproxy->uuid < 1001) { + Alert("parsing [%s:%d]: custom id has to be > 1000", + file, linenum); + return -1; + } + + for (target = proxy; target; target = target->next) + if (curproxy != target && curproxy->uuid == target->uuid) { + Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n", + file, linenum, curproxy->id, target->id); + return -1; + } + } else if (!strcmp(args[0], "disabled")) { /* disables this proxy */ curproxy->state = PR_STSTOPPED; } @@ -1530,7 +1560,32 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) cur_arg = 3; while (*args[cur_arg]) { - if (!strcmp(args[cur_arg], "cookie")) { + if (!strcmp(args[cur_arg], "id")) { + struct server *target; + + if (!*args[cur_arg + 1]) { + Alert("parsing [%s:%d]: '%s' expects an integer argument.\n", + file, linenum, args[cur_arg]); + return -1; + } + + newsrv->puid = atol(args[cur_arg + 1]); + + if (newsrv->puid< 1001) { + Alert("parsing [%s:%d]: custom id has to be > 1000", + file, linenum); + return -1; + } + + for (target = proxy->srv; target; target = target->next) + if (newsrv != target && newsrv->puid == target->puid) { + Alert("parsing [%s:%d]: custom id has to be unique but is duplicated in %s and %s.\n", + file, linenum, newsrv->id, target->id); + return -1; + } + cur_arg += 2; + } + else if (!strcmp(args[cur_arg], "cookie")) { newsrv->cookie = strdup(args[cur_arg + 1]); newsrv->cklen = strlen(args[cur_arg + 1]); cur_arg += 2; @@ -1696,7 +1751,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) return -1; } else { - Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n", + Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n", file, linenum, newsrv->id); return -1; } diff --git a/src/dumpstats.c b/src/dumpstats.c index 71e382afdc..c132246a51 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -171,7 +171,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," + "pid,iid,sid,throttle,lbtot,tracked,type," "\n"); } @@ -706,8 +706,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri, "%s," /* rest of server: nothing */ ",,,,,,,," - /* pid, iid, sid, throttle, lbtot, tracked*/ - "%d,%d,0,,,," + /* pid, iid, sid, throttle, lbtot, tracked, type (0=server)*/ + "%d,%d,0,,,,0," "\n", px->id, px->feconn, px->feconn_max, px->maxconn, px->cum_feconn, @@ -911,21 +911,21 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri, now.tv_sec >= sv->last_change) { unsigned int ratio; ratio = MAX(1, 100 * (now.tv_sec - sv->last_change) / sv->slowstart); - chunk_printf(&msg, sizeof(trash), "%d", ratio); + chunk_printf(&msg, sizeof(trash), "%d,", ratio); } /* sessions: lbtot */ - chunk_printf(&msg, sizeof(trash), ",%d", sv->cum_lbconn); + chunk_printf(&msg, sizeof(trash), "%d,", sv->cum_lbconn); /* tracked */ if (sv->tracked) - chunk_printf(&msg, sizeof(trash), ",%s/%s", + chunk_printf(&msg, sizeof(trash), "%s/%s,", sv->tracked->proxy->id, sv->tracked->id); else chunk_printf(&msg, sizeof(trash), ","); - /* ',' then EOL */ - chunk_printf(&msg, sizeof(trash), ",\n"); + /* type (2=server), then EOL */ + chunk_printf(&msg, sizeof(trash), "2,\n"); } if (buffer_write_chunk(rep, &msg) != 0) return 0; @@ -1007,8 +1007,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri, "%d,%d,%d," /* rest of backend: nothing, down transitions, last change, total downtime */ ",%d,%d,%d,," - /* pid, iid, sid, throttle, lbtot, tracked,*/ - "%d,%d,0,,%d,," + /* pid, iid, sid, throttle, lbtot, tracked, type (1=backend) */ + "%d,%d,0,,%d,,1," "\n", px->id, px->nbpend /* or px->totpend ? */, px->nbpend_max,