mturk 2005/02/14 09:27:15 Modified: jk/native/common jk_status.c Log: Display workers and balancer members. Revision Changes Path 1.5 +252 -4 jakarta-tomcat-connectors/jk/native/common/jk_status.c Index: jk_status.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_status.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- jk_status.c 14 Feb 2005 07:58:02 -0000 1.4 +++ jk_status.c 14 Feb 2005 17:27:15 -0000 1.5 @@ -26,6 +26,10 @@ #include "jk_worker.h" #include "jk_status.h" #include "jk_mt.h" +#include "jk_shm.h" +#include "jk_ajp_common.h" +#include "jk_lb_worker.h" +#include "jk_connect.h" #define HUGE_BUFFER_SIZE (8*1024) @@ -129,6 +133,238 @@ return rc; } +/* Actually APR's apr_strfsize */
+char *status_strfsize(size_t size, char *buf) +{ + const char ord[] = "KMGTPE"; + const char *o = ord; + int remain; + + if (size < 0) { + return strcpy(buf, " - "); + } + if (size < 973) { + if (sprintf(buf, "%3d ", (int) size) < 0) + return strcpy(buf, "****"); + return buf; + } + do { + remain = (int)(size & 1023); + size >>= 10; + if (size >= 973) { + ++o; + continue; + } + if (size < 9 || (size == 9 && remain < 973)) { + if ((remain = ((remain * 5) + 256) / 512) >= 10) + ++size, remain = 0; + if (sprintf(buf, "%d.%d%c", (int) size, remain, *o) < 0) + return strcpy(buf, "****"); + return buf; + } + if (remain >= 512) + ++size; + if (sprintf(buf, "%3d%c", (int) size, *o) < 0) + return strcpy(buf, "****"); + return buf; + } while (1); +} + +static const char *status_val_bool(int v) +{ + if (v == 0) + return "False"; + else + return "True"; +} + +static void jk_puts(jk_ws_service_t *s, const char *str) +{ + if (str) + s->write(s, str, strlen(str)); + else + s->write(s, "(null)", 6); +} + +static void jk_putv(jk_ws_service_t *s, ...) +{ + va_list va; + const char *str; + + va_start(va, s); + while (1) { + str = va_arg(va, const char *); + if (str == NULL) + break; + s->write(s, str, strlen(str)); + } + va_end(va); +} + + +/** + * Command line reference: + * cmd=list (default) display configuration + * cmd=show display detailed configuration + * cmd=update update configuration + * cmd=add add new uri map. + * w=worker display detailed configuration for worker + * + * Worker parameters: + * r=string redirect route name + * + */ + + +static void display_workers(jk_ws_service_t *s, status_worker_t *sw, + const char *dworker, jk_logger_t *l) +{ + unsigned int i; + char buf[32]; + + for (i = 0; i < sw->we->num_of_workers; i++) { + jk_worker_t *w = wc_get_worker_for_name(sw->we->worker_list[i], l); + ajp_worker_t *aw = NULL; + lb_worker_t *lb = NULL; + if (w == NULL) + continue; + if (!strcasecmp(w->type, "lb")) { + lb = (lb_worker_t *)w->worker_private; + } + else if (!strcasecmp(w->type, "ajp13")) { + aw = (ajp_worker_t *)w->worker_private; + } + else if (!strcasecmp(w->type, "ajp14")) { + aw = (ajp_worker_t *)w->worker_private; + } + else { + /* Skip status, jni and ajp12 worker */ + continue; + } + jk_puts(s, "<hr />\n<h3>Worker Status for "); + jk_putv(s, "<a href=\"", s->req_uri, "?cmd=show&w=", + sw->we->worker_list[i], "\">", NULL); + jk_putv(s, sw->we->worker_list[i], "</a></h3>\n\n", NULL); + if (lb != NULL) { + unsigned int j; + int selected = -1; + jk_puts(s, "\n\n<table border=\"0\"><tr>" + "<th>Type</th><th>Sticky session</th>" + "<th>Local worker only</th>" + "</tr>\n<tr>"); + jk_putv(s, "<td>", w->type, "</td>", NULL); + jk_putv(s, "<td>", status_val_bool(lb->s->sticky_session), + "</td>", NULL); + jk_putv(s, "<td>", status_val_bool(lb->s->local_worker_only), + "</td>", NULL); + jk_puts(s, "</tr>\n</table>\n"); + jk_puts(s, "\n\n<table border=\"0\"><tr>" + "<th>Name</th><th>Type</th><th>Host</th><th>Addr</th>" + "<th>Stat</th><th>F</th><th>Acc</th><th>Wr</th>" + "<th>Rd</th><th>RR</th><th>Cd</th></tr>\n"); + for (j = 0; j < lb->num_of_workers; j++) { + worker_record_t *wr = &(lb->lb_workers[j]); + ajp_worker_t *a = (ajp_worker_t *)wr->w->worker_private; + jk_putv(s, "<tr>\n<td><a href=\"", s->req_uri, + "?cmd=show&w=", + wr->s->name, "\">", + wr->s->name, "</td>", NULL); + if (dworker && strcmp(dworker, wr->s->name) == 0) + selected = j; + jk_putv(s, "<td>", wr->w->type, "</td>", NULL); + jk_printf(s, "<td>%s:%d</td>", a->host, a->port); + jk_putv(s, "<td>", jk_dump_hinfo(&a->worker_inet_addr, buf), + "</td>", NULL); + /* TODO: descriptive status */ + jk_printf(s, "<td>%d</td>", wr->s->status); + jk_printf(s, "<td>%d</td>", wr->s->lb_factor); + jk_printf(s, "<td>%d</td>", wr->s->elected); + jk_putv(s, "<td>", status_strfsize(wr->s->transferred, buf), + "</td>", NULL); + jk_putv(s, "<td>", status_strfsize(wr->s->readed, buf), + "</td><td>", NULL); + jk_puts(s, wr->s->redirect); + jk_puts(s, "</td><td>\n"); + jk_puts(s, wr->s->domain); + jk_puts(s, "</td>\n</tr>\n"); + } + jk_puts(s, "</table>\n"); + if (selected >= 0) { + worker_record_t *wr = &(lb->lb_workers[selected]); + ajp_worker_t *a = (ajp_worker_t *)wr->w->worker_private; + jk_putv(s, "<hr /><h3>Edit balancer settings for ", + wr->s->name, "</h3>\n", NULL); + jk_putv(s, "<form method=\"GET\" action=\"", + s->req_uri, "\">\n", NULL); + + jk_puts(s, "\n</form>\n"); + + } + } + else { + jk_puts(s, "\n\n<table border=\"0\"><tr>" + "<th>Type</th><th>Host</th><th>Addr</th>" + "</tr>\n<tr>"); + jk_putv(s, "<td>", w->type, "</td>", NULL); + jk_puts(s, "</tr>\n</table>\n"); + jk_printf(s, "<td>%s:%d</td>", aw->host, aw->port); + jk_putv(s, "<td>", jk_dump_hinfo(&aw->worker_inet_addr, buf), + "</td>\n</tr>\n", NULL); + jk_puts(s, "</table>\n"); + } + } + /* Display legend */ + jk_puts(s, "<hr /><table>\n" + "<tr><th>Name</th><td>Worker route name</td></tr>\n" + "<tr><th>Type</th><td>Worker type</td></tr>\n" + "<tr><th>Addr</th><td>Backend Address info</td></tr>\n" + "<tr><th>Stat</th><td>Worker status</td></tr>\n" + "<tr><th>F</th><td>Load Balancer Factor in %</td></tr>\n" + "<tr><th>Acc</th><td>Number of requests</td></tr>\n" + "<tr><th>Wr</th><td>Number of bytes transferred</td></tr>\n" + "<tr><th>Rd</th><td>Number of bytes read</td></tr>\n" + "<tr><th>RR</th><td>Route redirect</td></tr>\n" + "<tr><th>Cd</th><td>Cluster domain</td></tr>\n" + "</table>"); +} + +static int status_cmd_type(const char *req) +{ + if (!strncmp(req, "cmd=list", 8)) + return 0; + else if (!strncmp(req, "cmd=show", 8)) + return 1; + else if (!strncmp(req, "cmd=update", 10)) + return 2; + else + return 0; +} + +static const char *status_cmd_worker(const char *req, char *buf, size_t len) +{ + char *p = strstr(req, "&w="); + size_t l = 0; + if (p) { + p += 3; + while (*p) { + if (*p != '&') + buf[l++] = *p; + else + break; + if (l + 2 > len) + break; + p++; + } + buf[l] = '\0'; + if (l) + return buf; + else + return NULL; + } + else + return NULL; +} + static int JK_METHOD service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_recoverable_error) @@ -136,17 +372,30 @@ JK_TRACE_ENTER(l); if (e && e->endpoint_private && s) { + char buf[128]; status_endpoint_t *p = e->endpoint_private; + *is_recoverable_error = JK_FALSE; + s->start_response(s, 200, "OK", headers_names, headers_vals, 3); s->write(s, JK_STATUS_HEAD, sizeof(JK_STATUS_HEAD) - 1); - /* Step 1: Process GET params and update configuration */ + jk_puts(s, "<h1>JK Status Manager for "); + jk_puts(s, s->server_name); + jk_puts(s, "</h1>\n\n"); + jk_putv(s, "<dl><dt>Server Version: ", + s->server_software, "</dt>\n", NULL); + jk_putv(s, "<dt>JK Version: ", + JK_VERSTRING, "\n</dt></dl>\n", NULL); + /* Step 1: Process GET params and update configuration */ + /* Step 2: Display configuration */ + display_workers(s, p->s_worker, + status_cmd_worker(s->query_string, buf, sizeof(buf)), l); - s->write(s, JK_STATUS_HEND, sizeof(JK_STATUS_HEND) - 1); + s->write(s, JK_STATUS_HEND, sizeof(JK_STATUS_HEND) - 1); JK_TRACE_EXIT(l); return JK_TRUE; } @@ -193,7 +442,6 @@ jk_map_t *props, jk_worker_env_t *we, jk_logger_t *log) { - status_worker_t *p = (status_worker_t *)pThis->worker_private; JK_TRACE_ENTER(log); if (pThis && pThis->worker_private) { status_worker_t *p = pThis->worker_private; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]