Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: tmm1/haproxy
base: dbf70fdd00
...
head fork: tmm1/haproxy
compare: b26fa42927
  • 6 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Showing with 97 additions and 46 deletions.
  1. +21 −20 doc/configuration.txt
  2. +2 −0  include/types/session.h
  3. +74 −26 src/dumpstats.c
View
41 doc/configuration.txt
@@ -8526,26 +8526,6 @@ show errors [<iid>]
is the slash ('/') in header name "header/bizarre", which is not a valid
HTTP character for a header name.
-show events
- Dump a stream of events about sessions as they are created and
- destroyed. The two possible event formats are:
-
- "+ <session_id> <inbound_peer> <inbound_sock> <outbound_sock> <outbound_peer>\n"
- "- <session_id>\n"
-
- Streaming will continue until a new command is received or the
- connection is closed.
-
- This command is restricted and can only be issued on sockets configured
- for levels "operator" or "admin".
-
- Example:
- >>> $ echo "show events" | socat stdio,ignoreeof /tmp/sock1
- + 1 127.0.0.1:50869 127.0.0.1:9418 127.0.0.1:50870 127.0.0.1:6000
- - 1
- + 2 127.0.0.1:50874 127.0.0.1:9418 127.0.0.1:50875 127.0.0.1:6000
- - 2
-
show info
Dump info about haproxy status on current process.
@@ -8596,6 +8576,27 @@ show stat [<iid> <type> <sid>]
A similar empty line appears at the end of the second block (stats) so that
the reader knows the output has not been truncated.
+debug sess [proxy:<proxy_name>[:<server_name>]]
+
+ Dump a stream of events about sessions as they are added and removed.
+ The possible event formats are "Forward" and "Close":
+
+ "F <session_id> <in_peer> - <in_sock> | <out_sock> - <out_peer>\n"
+ "C <session_id>\n"
+
+ Streaming will continue until a new command is received or the
+ connection is closed. If <proxy_name> or <server_name> is specified, limit to
+ events concerning only the proxy and server specified.
+
+ This command is restricted and can only be issued on sockets configured
+ for levels "operator" or "admin".
+
+ Example:
+ >>> $ echo "set timeout cli 3600; debug sess" | socat stdio,ignoreeof /tmp/sock1
+ + 1 127.0.0.1:50869 127.0.0.1:9418 127.0.0.1:50870 127.0.0.1:6000
+ - 1
+ + 2 127.0.0.1:50874 127.0.0.1:9418 127.0.0.1:50875 127.0.0.1:6000
+ - 2
/*
* Local variables:
View
2  include/types/session.h
@@ -232,6 +232,8 @@ struct session {
} errors;
struct {
struct list list; /* list of stats sessions in the STAT_CLI_EVENTS state */
+ struct proxy *px; /* if not NULL, only send events associated with this proxy */
+ struct server *srv; /* if not NULL, only send events associated with this server */
} events;
struct {
const char *msg; /* pointer to a persistent message to be returned in PRINT state */
View
100 src/dumpstats.c
@@ -62,12 +62,12 @@ const char stats_sock_usage_msg[] =
" show stat : report counters for each proxy and server\n"
" show errors : report last request and response errors for each proxy\n"
" show sess [id] : report the list of current sessions or dump this session\n"
- " show events : stream events about proxied sessions\n"
" get weight : report a server's current weight\n"
" set weight : change a server's weight\n"
" set timeout : change a timeout setting\n"
" disable server : set a server in maintenance mode\n"
" enable server : re-enable a server that was previously in maintenance mode\n"
+ " debug sess : stream events about proxied sessions\n"
"";
const char stats_permission_denied_msg[] =
@@ -103,8 +103,11 @@ static inline void stats_event_listener_remove(struct session *s)
}
}
- if (found)
+ if (found) {
+ s->data_ctx.events.px = NULL;
+ s->data_ctx.events.srv = NULL;
LIST_DEL(&s->data_ctx.events.list);
+ }
if (LIST_ISEMPTY(&stats_event_listeners))
stats_event_enabled = 0;
@@ -115,18 +118,30 @@ static inline void stats_event_listener_remove(struct session *s)
/* Send a message to all registered event listeners.
*/
-static inline void stats_event_listener_message_all(char *msg)
+static inline void stats_event_listener_message_all(char *msg, struct session *s)
{
struct session *curr;
list_for_each_entry(curr, &stats_event_listeners, data_ctx.events.list) {
struct stream_interface *si = &curr->si[1];
+ struct proxy *px;
+ struct server *srv;
+
+ if (!(si->flags & SI_FL_DONT_WAKE) && si->owner) {
+ /* filter by proxy and server if required */
+ if ((px = curr->data_ctx.events.px)) {
+ if (s->be != px && s->fe != px)
+ continue; /* ignore */
+ if ((srv = curr->data_ctx.events.srv)) {
+ if (s->srv != srv)
+ continue; /* ignore */
+ }
+ }
- if (!(si->flags & SI_FL_DONT_WAKE) &&
- si->owner &&
- buffer_feed(si->ib, msg) == -1) {
- si->ib->flags |= BF_SEND_DONTWAIT;
- task_wakeup(si->owner, TASK_WOKEN_MSG);
+ if (buffer_feed(si->ib, msg) == -1) {
+ si->ib->flags |= BF_SEND_DONTWAIT;
+ task_wakeup(si->owner, TASK_WOKEN_MSG);
+ }
}
}
}
@@ -367,7 +382,51 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
args[arg] = line;
s->data_ctx.stats.flags = 0;
- if (strcmp(args[0], "show") == 0) {
+ if (strcmp(args[0], "debug") == 0) {
+ if (strcmp(args[1], "sess") == 0) {
+ if (s->listener->perm.ux.level < ACCESS_LVL_OPER) {
+ s->data_ctx.cli.msg = stats_permission_denied_msg;
+ si->st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+ if (*args[2] && !strncmp(args[2], "proxy", 5)) {
+ struct proxy *px = NULL;
+ struct server *srv = NULL;
+ char *px_name = args[2] + 6, *srv_name;
+
+ if ((srv_name = strchr(px_name, ':'))) {
+ *srv_name = 0;
+ srv_name += 1;
+ }
+
+ px = findproxy(px_name, PR_CAP_FE|PR_CAP_BE);
+ if (!px) {
+ s->data_ctx.cli.msg = "Invalid proxy filter for event stream.";
+ si->st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ if (srv_name && *srv_name) {
+ srv = findserver(px, srv_name);
+ if (!srv) {
+ s->data_ctx.cli.msg = "Invalid server filter for event stream.";
+ si->st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+ }
+
+ s->data_ctx.events.srv = srv;
+ s->data_ctx.events.px = px;
+ } else {
+ s->data_ctx.events.srv = NULL;
+ s->data_ctx.events.px = NULL;
+ }
+
+ stats_event_listener_add(s);
+ si->st0 = STAT_CLI_EVENTS;
+ }
+ }
+ else if (strcmp(args[0], "show") == 0) {
if (strcmp(args[1], "stat") == 0) {
if (*args[2] && *args[3] && *args[4]) {
s->data_ctx.stats.flags |= STAT_BOUND;
@@ -416,15 +475,6 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
s->data_state = DATA_ST_INIT;
si->st0 = STAT_CLI_O_ERR; // stats_dump_errors_to_buffer
}
- else if (strcmp(args[1], "events") == 0) {
- if (s->listener->perm.ux.level < ACCESS_LVL_OPER) {
- s->data_ctx.cli.msg = stats_permission_denied_msg;
- si->st0 = STAT_CLI_PRINT;
- return 1;
- }
- si->st0 = STAT_CLI_EVENTS;
- stats_event_listener_add(s);
- }
else { /* neither "stat" nor "info" nor "sess" nor "errors" nor "events" */
return 0;
}
@@ -937,10 +987,6 @@ void stats_io_handler(struct stream_interface *si)
si->ib->rex = TICK_ETERNITY;
si->ob->wex = TICK_ETERNITY;
- /* no timeouts when streaming events */
- if (si->st0 == STAT_CLI_EVENTS)
- s->req->rex = TICK_ETERNITY;
-
out:
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rql=%d, rqs=%d, rl=%d, rs=%d\n",
__FUNCTION__, __LINE__,
@@ -3244,19 +3290,21 @@ void stats_event_new_session(struct session *s)
snprintf(addrs[i]+strlen(addrs[i]), sizeof(addrs[i])-strlen(addrs[i])-1, ":%d", port);
break;
case AF_UNIX:
+ sprintf(addrs[i], "unix:%d", s->listener->luid);
+ break;
default:
sprintf(addrs[i], "%s", "unknown");
}
}
}
- snprintf(trash, sizeof(trash), "+ %u %s %s %s %s\n", s->uniq_id,
+ snprintf(trash, sizeof(trash), "F %u %s - %s | %s - %s\n", s->uniq_id,
addrs[0], // inbound peer
addrs[1], // inbound sock
addrs[3], // outbound sock
addrs[2] // outbound peer
);
- stats_event_listener_message_all(trash);
+ stats_event_listener_message_all(trash, s);
}
/* Called when the session argument's s->si[1]->state goes from SI_ST_EST
@@ -3267,8 +3315,8 @@ void stats_event_end_session(struct session *s)
if (LIST_ISEMPTY(&stats_event_listeners))
return;
- snprintf(trash, sizeof(trash), "- %u\n", s->uniq_id);
- stats_event_listener_message_all(trash);
+ snprintf(trash, sizeof(trash), "C %u\n", s->uniq_id);
+ stats_event_listener_message_all(trash, s);
}
static struct cfg_kw_list cfg_kws = {{ },{

No commit comments for this range

Something went wrong with that request. Please try again.